フロント実装 〜ヘルパーメソッド〜
以下のように3つのSNSサービスにリンクするアプリケーションを実装していく。
各リンクは以下のページへリンクしている。
実装は以下のステップで進めていく。
railsの新しいアプリケーションを作成
まず、アプリケーションを作成する。名称はなんでも構わないが、ここではview_drill
とする。
view_drillディレクトリに移動し、データベースも作成しておく。
1 |
$ rails db:create
|
hamlの実装
次にrailsにおいてhamlを使用するためのgemを導入する。今回はhaml-railsを用いる。
haml-rails 公式ドキュメントにおいて、read.meにgemの使用方法等がまとめられている。
To use it, add this line to your Gemfile...
とあるので、記載どおりgemファイルに導入してみる。
記載したらbundle install。
1 |
$ bundle install
|
これでhaml使用の準備が整った。次に、rails new時に作成される、既存のerbファイルをhamlに変換する。公式ドキュメントを読むと
Converting all .erb views to haml format
If you want to convert all of your .erb views into .haml, you can do so using the following command...
と書いてあるので、コマンドを実行。
途中で
1 |
Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n)
|
と聞かれますが、今回はアプリケーションの初期段階であるため、y
を選択。すると、デフォルトで作成されたerbファイル(例えば、application.html.erbなど)がhamlに変換されていることが確認できる。
コントローラー・ビュー・ルーティングの作成
続いて、コントローラーを作成する。コントローラー名はなんでも構わないが、今回はposts_controller
を作成することにする。
1 |
$ rails g controller posts
|
次に、indexアクションを記載しておく。
1 2 3 4 |
class PostsController < ApplicationController
def index
end
end
|
続いて、app/views/posts/index.html.haml
を作成し、確認用の文字列を入力しておく。
ルーティングの設定をしておく。今回はroot_pathにアクセスした場合に、posts#indexが呼び出されるようにする。
1 2 3 |
Rails.application.routes.draw do
root to: 'posts#index'
end
|
Sassの導入
今回はscssのみ利用するため、 application.css
は削除し、application.scss
を作成する。また、posts.scss
がすでに作成されているが、_posts.scss
にファイル名を修正する。そしてapplication.scss
で以下のように_posts.scss
を読み込む記述をする。
1 |
@import "posts";
|
また、リセットCSSの導入も行う。リセットCSSにはいくつかあるが、今回はYUI3というリセットCSSを利用する。以下のページからダウンロードが可能。
https://github.com/yui/yui3/releases
Source code(zip)
をダウンロードしたら、yui3-3.18.1/src/cssreset/css/cssreset.css
を開く(YUI3のバージョンは異なることがある)。そちらを全てコピー。
_reset.scss
を作成し先程コピーしたコードを貼り付ける。以下のようになるはずです
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 9900 01 02 03 04 05 06 07 08 |
/*
TODO will need to remove settings on HTML since we can't namespace it.
TODO with the prefix, should I group by selector or property for weight savings?
*/
html{
color:#000;
background:#FFF;
}
/*
TODO remove settings on BODY since we can't namespace it.
*/
/*
TODO test putting a class on HEAD.
- Fails on FF.
*/
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
form,
fieldset,
legend,
input,
textarea,
p,
blockquote,
th,
td {
margin:0;
padding:0;
}
table {
border-collapse:collapse;
border-spacing:0;
}
fieldset,
img {
border:0;
}
/*
TODO think about hanlding inheritence differently, maybe letting IE6 fail a bit...
*/
address,
caption,
cite,
code,
dfn,
em,
strong,
th,
var {
font-style:normal;
font-weight:normal;
}
ol,
ul {
list-style:none;
}
caption,
th {
text-align:left;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size:100%;
font-weight:normal;
}
q:before,
q:after {
content:'';
}
abbr,
acronym {
border:0;
font-variant:normal;
}
/* to preserve line-height and selector appearance */
sup {
vertical-align:text-top;
}
sub {
vertical-align:text-bottom;
}
input,
textarea,
select {
font-family:inherit;
font-size:inherit;
font-weight:inherit;
*font-size:100%; /*to enable resizing for IE*/
}
/*because legend doesn't inherit in IE */
legend {
color:#000;
}
|
application.scss
で以下のように_reset.scss
を読み込む記述をする。
1 2 |
@import "reset";
@import "posts";
|
この時、フォルダ構造はこの様になっているはず。
確認する
上記の準備が完了したら、rails s
をして確認用の文字列が表示されているか確認。
上記が確認できたら、準備は完了。いよいよフロントの実装に入る。
仕様書を確認して、手描きでマークアップしてみる
まず、どのような見た目を実装するのか、仕様書を確認する。
こちらを元に、手描きで大まかにブロックやエレメントを分けてみる。例えば以下のような形である。
大枠を作成する
実際にHamlを書いていく。まずは、細かい点を気にせずに、以下のように全体的に構造を決める。
1 2 3 4 5 6 7 8 9 10 11 12 |
当然、この状態だと以下の様に縦に並んでいるだけ。
続いて、リンク部分について考える。htmlではリンクはaタグを使うが、Railsではヘルパーメソッドのlink_toを使用することが一般的。
html.erbでヘルパーメソッドやRubyの記述をする際は、erbタグ(<% %>や<%= %>)を用いていた。erbからhamlに変更したので、ヘルパーメソッドの表記は以下のようになる。
1 2 3 4 5 6 7 8 9 10 11 12 |
.header
.header__logo
SNS
.contents
.contents__message
follow me!
= link_to "https://www.facebook.com/", class: "contents__btn" do
Facebook
= link_to "https://twitter.com/", class: "contents__btn" do
Twitter
= link_to "https://www.instagram.com/", class: "contents__btn" do
Instagram
|
ヘルパーメソッドのクラスの設定など、オプションについて忘れてしまった際は、以下のドキュメントを確認すると良い。
Rails APIドキュメント
https://api.rubyonrails.org/v5.0/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
ブラウザで確認すると、リンクに変わったことがわかる。
しかし、これまで縦に並んでいたSNSへのリンクが横並びになった。
Font Awesomeでアイコンを導入
続いてアイコンを導入する。 Font Awesomeというサービスを利用。
Font Awesome
通常の使用方法について多くの参考記事が存在するが、Font Awesomeに対応するgem font-awesome-sass
が存在する。今回はRailsでの開発になるため、こちらのgemを使用する。
公式のgithubを確認。
font-awesome-sass
https://github.com/FortAwesome/font-awesome-sass
read.meに記載されている通り、以下の様にgemを導入する。
1 2 |
gem "font-awesome-sass"
# 最下部に記載
|
忘れずにbundle installする。
続いて、application.scssに以下の様に記述。
1 2 3 4 |
続いて、実際にhamlの中にアイコンを導入する記述をしていく。公式githubを確認すると以下のように記載することでアイコンが反映されるとある。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.header
.header__logo
SNS
.contents
.contents__message
follow me!
= link_to "https://www.facebook.com/", class: "contents__btn" do
= icon('fab', 'facebook-square')
Facebook
= link_to "https://twitter.com/", class: "contents__btn" do
= icon('fab', 'twitter')
Twitter
= link_to "https://www.instagram.com/", class: "contents__btn" do
= icon('fab', 'instagram')
Instagram
|
gemを用いることでfontawsomeアイコンをヘルパーメソッドで導入することができる。アイコンの名称等は
https://fontawesome.com/icons?d=gallery
から確認することができる。
実際にどのような見た目になっているか確認。
これでアイコンを導入することができた。
SassでCSSを書く(大枠を整える)
実際に仕様書を確認しながら、CSSで見た目を整えていく。まずは、大枠を整える必要がある。まずはヘッダー部分については以下のように記載。
1 2 3 4 5 6 7 8 9 10 11 |
.header {
height: 90px;
border-bottom:20px solid #ffa500;
background-color: #ff8c00;
color: #ffffff;
&__logo {
text-align: center;
font-size: 36px;
line-height: 90px;
}
}
|
ヘッダー下の20px幅の部分については、今回はborder-bottomで表現することにした。この段階で一度ブラウザで見た目を確認しておく。
次に、コンテンツ部分を作成していきます。まずは大枠を整える。
12 13 14 15 16 17 18 |
// headerについての記述は省略
.contents {
height: calc(100vh - 90px - 20px);
width:900px;
margin: 0 auto;
background-color: #fffacd;
}
|
heightについては、100vhからヘッダー分の高さ(90pxとヘッダー下部の20px分)を引いた数値で表現している。
次に、"follow me"の文字列部分のCSSを記載する。
12 13 14 15 16 17 18 19 20 21 22 23 24 |
// headerについての記述は省略
.contents {
height: calc(100vh - 90px - 20px);
width:900px;
margin: 0 auto;
background-color: #fffacd;
&__message{
padding: 40px;
color:#ffa500;
font-size:30px;
text-align: center;
}
}
|
この段階では以下のような見た目になっているはず。
SassでCSSを書こう(aタグの取り扱い)
検証ツールを用いて確認すると、link_toタグで表記している部分はaタグに読み替えられてブラウザで表示される。
aタグはインライン要素であるため、今回のように縦に並べたい場合はブロックレベル要素へ変換する必要がある。そこで以下のような記述を行う。
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// headerについての記述は省略
.contents {
height: calc(100vh - 90px - 20px);
width:900px;
margin: 0 auto;
background-color: #fffacd;
&__message{
padding: 40px;
color:#ffa500;
font-size:30px;
text-align: center;
}
&__btn{
display: block;
}
}
|
こうするとブロックレベル要素として取り扱うことができるので、縦に並べることができる。
続いて、HTMLの記述も修正する。なぜならば、各SNSごとにボタンの色が異なるから。アイコンにもクラスを付与しておく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.header
.header__logo
SNS
.contents
.contents__message
follow me!!
= link_to "https://www.facebook.com/", class: "contents__btn contents__btn--facebook" do
= icon('fab', 'facebook-square', class: "contents__btn--icon")
Facebook
= link_to "https://twitter.com/", class: "contents__btn contents__btn--twitter" do
= icon('fab', 'twitter', class: "contents__btn--icon")
Twitter
= link_to "https://www.instagram.com/", class: "contents__btn contents__btn--instagram" do
= icon('fab', 'instagram', class: "contents__btn--icon")
Instagram
|
cssを以下のように記載していく。
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
// Header部分は省略
.contents {
height: calc(100vh - 90px - 20px);
width:900px;
margin: 0 auto;
background-color: #fffacd;
&__message{
padding: 40px;
color:#ffa500;
font-size:30px;
text-align: center;
}
&__btn{
display: block;
height: 80px;
width :360px;
margin:0 auto 50px;
border-radius: 10px;
font-size:20px;
color:#fff;
text-decoration: none;
text-align: center;
line-height: 80px;
&--icon{
padding-right:20px;
}
&--facebook{
background-color: #4169e1;
}
&--twitter{
background-color: #00bfff;
}
&--instagram{
background-color: #fc76bf;
}
}
}
|
これでほぼ見た目は完成したはず。特に難しいcssプロパティは使用していませんが、アンパサンド(&)を使用しているため一見判断がつきにくい部分もあるかもしれない。しかし、scssにおける記述ではアンパサンドの使用は必要不可欠。
最後の微調整を行う
現状、一点だけ仕様書通りになっていない部分がある。アイコンとテキストの隙間に注目してみると、padding分の20pxに加えて、隙間が存在してしまっていることがわかる。
これはhamlで改行して記載しているために生じる隙間。これを埋めるためにはどの様にすれば良いのか?
この解決方法はhaml公式ドキュメントに記載がある。
haml公式ドキュメント Whitespace Removal
要は<>を付与することでこの隙間を消すことができる。以下の様にspanタグで区切った後に<>を付与してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.header
.header__logo
SNS
.contents
.contents__message
follow me!!
= link_to "https://www.facebook.com/", class: "contents__btn contents__btn--facebook" do
= icon('fab', 'facebook-square', class: "contents__btn--icon")
%span<>
Facebook
= link_to "https://twitter.com/", class: "contents__btn contents__btn--twitter" do
= icon('fab', 'twitter', class: "contents__btn--icon")
%span<>
Twitter
= link_to "https://www.instagram.com/", class: "contents__btn contents__btn--instagram" do
= icon('fab', 'instagram', class: "contents__btn--icon")
%span<>
Instagram
|
すると以下の様に隙間を消すことができ、仕様書通りに作成することができる。