【初学者向け】RailsでのWebアプリ作成Tips デザイン編
はじめに
実務未経験からWebアプリケーションエンジニアに転職するにあたり、自分で企画したWebアプリケーションを作るということが定番になりつつあります。しかし、特に見た目の部分、デザインがいい感じになっていないせいで面接官の印象が悪くなるという非常に勿体無い例を数えきれないくらい見てきました。
そこで、主にデザイン面の部分で知っておくと得するかもしれないRailsによるWebアプリケーション開発のTipsをお伝えします。
目的
- WebアプリケーションをRailsで制作する際、デザインの質が高く就活で評価されやすい状態にすること
どれくらい重要かを★マークの数(1 ~ 3つ)で表しています。また、結局何をすれば良いかがわかりやすいよう、必要な項目には「アクションプラン」という項を設けています。
目次
- 制作進行について
- まずは見た目ではなく機能を作りこむ
- 最小限の機能を作れたら先に本番環境にデプロイする
- Renderでデプロイしたサーバがスリープ状態にならないようにする
- 具体的なデザインコーディングについて
- デザインは参考9:独創1の割合で考える
- スマホで閲覧することを前提にレスポンシブ対応する方法
- VSCodeの機能(Emmet)を使ってHTMLのコーディングを効率化する
- 要素の幅は8の倍数で取る
- CSSのクラス名の付け方を工夫する
- CSSはコメントでどこに何を書いているかわかるようにメモしておく。できればCSSのファイルをページごとに分ける
- アイコンなど画像を利用したい時はS3に画像を設置しリンクを利用する
- ChatGPTをうまく利用する
- テキストにフォントを指定する
制作進行について
まずは見た目ではなく機能を作り込む
重要度★★★
オリジナルのWebアプリを企画し作るときは、フロントエンドは極力手をつけずサーバーサイド中心に開発を進めます。最低限絶対に提供したい機能が実際に動く状態を、早く目指しましょう。
理由
理由は2つあります。
1.本当にその機能が実現できるかわからないから
2.見た目の改善は時間がかかるから
1.本当にその機能が実現できるかわからないから
実装を試して初めてうまくいくかどうかわかることもあります。機能がきちんと動いていない状態で見た目を綺麗にすることに時間を取られ、やっとサーバサイドの実装に取り掛かってみたら最低限提供したいアプリの機能が実現できないことがわかった、となるとタイムロスです。
2.見た目の改善は時間がかかるから
アプリのデザイン、見た目の部分には正解がありません。ゆえに、こだわりが強いタイプの人は修正に修正を重ねることで時間をかけがちです。またそもそもHTML/CSSを書く作業というのは時間がかかります。
ただし例外として、見栄えが良くないとテンションが上がらないというタイプの人は、最低限のレイアウトだけ作るのはありだと思います。
アクションプラン
- アプリのターゲットに対して最低限提供したい機能を作り切るまでは、デザインの改善のためのコーディングは極力行わない。
最小限の機能を作れたら先に本番環境にデプロイする
重要度★★★
大抵のアプリには何かしらの投稿の機能や、ユーザー登録/ログイン機能をつけると思います。
そうした機能を作り終えたら、まずRenderなどを使って本番環境を作り、全世界に公開してしまいましょう。
理由
面倒だからとある程度規模が大きくなるまで本番環境へのデプロイを後回しにすればするほど、デプロイ自体でエラーが発生する可能性が高くなり、難易度が上がります。はやめにデプロイしておくことに越したことはないです。
またRenderであれば、一度デプロイしてしまえば以降はmainブランチにコミット、リモートにプッシュを行うだけで自動的に本番環境に変更が反映されます。
キリが良いところでコミットしてプッシュするだけで、本番環境にてエラーが起きていないかをチェックすることもできます。エラーが起きていた時と起きていない時の差分がわかりやすく、問題解決のヒントが増えます。
アクションプラン
- ユーザー登録/ログイン機能や投稿機能を実装した段階で、Renderによるデプロイを行う
Renderでデプロイしたサーバがスリープ状態にならないようにする
重要度★★★
Renderでデプロイしたアプリはしばらくアクセスがないと「スリープ状態」になります。
これはアプリを動かしているサーバ自体が起動していない状態になり、アクセスが来て初めてサーバを起動する形になるため、サーバの起動時間がかかる分アプリの画面がブラウザに表示されるまでに非常に長い時間を有してしまいます。
アプリを閲覧する人にとっては画面が表示されるまでの速度が非常に大切です。あまりにも長い時間表示されないサービスは「壊れているのかな?」と思われたり、イライラするなどして結局見てもらえないことが大半です。
就活のアピールに使うとき、応募先の会社の人事やエンジニアの方がそのように感じられてしまうと非常にもったいないです。
そうならないように、「UptimeRobot」というサービスを使いましょう。Renderでデプロイしたアプリに対して定期的に自動でリクエストを行い、スリープ状態になることを防いでくれます。無料で使えます。使い方はこちらのサイトなどを参考にしてください。
アクションプラン
- UptimeRobotを使い、Renderでデプロイしたサイトがスリープ状態にならないようにする
具体的なデザインコーディングについて
デザインは参考9:独創1の割合で考える
重要度★★★
Webアプリのデザインを考える時、0から自力で考えてはいけません。必ず、すでに世の中で多く使われているアプリケーションのデザインを真似するようにしましょう。特にレイアウトについては絶対に独創しないようにしましょう。世の中に出ているスマホ向けのアプリのデザインをまとめたサイトを紹介するので、自分が作ろうとしているアプリの種類に似たものについて最低4 ~ 5種類は確認し、どこにどのような要素がどのような大きさで置かれているのかを記録しておきましょう。そして、自分のアプリのデザインにてそれをそっくりそのまま反映させます。変えるのは、コンテンツの中身やフォントや色味だけにしておきましょう。
理由
プロのデザイナーが考えたデザインの方が、素人が考えるデザインよりも見やすく、見る人に対して与える印象が良いためです。デザインをきちんと勉強していない人が独創して作ったデザインで、プロのデザインよりも綺麗になることはありません。
アクションプラン
- ui-pocketなどで自分が作ろうとしているアプリと似たジャンルのアプリを探す
- アプリのデザインで参考にすべき箇所を探して、記録しておく
- 自身のアプリにそのまま反映させる
スマホで閲覧することを前提にデザインする
重要度★★★
最初からスマートフォンで利用してもらう前提のアプリケーションを考えるのであれば、ビューはすべてPCで閲覧した場合でもコンテンツの表示領域を細長くしておきましょう。以下のような感じです。
理由
こちらの理由は時間を節約するためです。
パソコンで見た場合とスマートフォンで見た場合の両方の見た目をデザインしコーディングするのは大変です。利用する人のニーズを考え、なるべくどちらかに統一した方が工数を削減できます。どうしてもPC/スマートフォン両方からの利用を想定する場合は、スマートフォン向けの見た目で統一することを検討しましょう。PCで閲覧したときもスマホ向けの縦長のデザインを維持できるようにコーディングします。
コーディングのやり方
まずはviewportの設定を行います。こちらの記事を参考にしてください。
次に、PCで閲覧した際でもページがある程度の横幅より大きくならないように設定しましょう。そのためには、bodyの直下の階層に全体の幅を制御するためのブロック要素を配置します。そして、その下の階層にはデザイン的に端に幅を取るためのブロック要素を配置します。以下のようなイメージです。
HTML/CSSの例は以下のリンク先の通りです。
例の場合、tweetShow__containerクラスを当てた要素に対し内側に幅を取るpadding
が設定されているため、以下のように内側に幅が生まれ余白がある良いデザインとなっています。また、min-height
を100vhで設定しており、ブラウザ表示の縦幅がそのまま要素の縦幅になるようにしています。他のCSSのプロパティの細かな意味についてはぜひChatGPTに聞いてみてください。
ブラウザの横幅が狭い状態から広い状態に動かしても、一定以上は幅が大きくならないことがわかります。
ブロック要素の横幅は、何も指定しなければ親要素の横幅と一致します。.body__containerクラスを当てたdiv要素の親要素はbody要素なので、body要素の横幅と一致することになります。これは通常ブラウザで閲覧している画面の横幅となります。しかし、ここではmax-widthで最大幅を指定しているため、800px以上に広げるとそれ以上大きくなりません。また、margin 0 auto;を指定することにより要素を中央寄せしています。
Railsでスマホ前提のviewを作る場合、以下のようにapplication.html.erbにてbody要素とyieldの間にcontainerの役割を果たす要素を入れることで、全てのページでスマホ前提のviewにすることができます。
<body>
<header>
</header>
<div class="body__container">
<%= yield %>
</div>
<footer>
</footer>
</body>
あとは、それぞれのviewごとに内側のcontainer(.hogehoge__container
)クラスを当てた要素を作り、内側に必要な要素を書いていくだけです。
<div class="hogehoge__container">
#この内側にHTMLを書いていく
</div>
.body__containerの直下の子要素として、上下左右にpaddingを持つ要素.hogehoge__containerを置いています(hogehogeは適当な例です)。これはレイアウトを整えるための要素です。特に左右にpaddingを持たせることでデザイン的に余白を作ることができ.hogehoge__containerの子要素を配置したときに整ったデザインに見せることができます。
VSCodeの機能(Emmet)を使ってHTMLのコーディングを効率化する
重要度★★★
VSCodeでは、設定を行うことで以下のようにHTMLのコーディングを省略記法を使ってできます。
以下の例では、div.exp
と打ち込んでからtab
キーを押すことで一気に要素を書くことができています。
理由
コーディングにかかる時間を節約するためです。
やり方
設定方法
これはEmmetというツールの機能です。Emmetは、元々いくつかのコーディング用エディターにて拡張機能として提供されていました。VSCodeでは標準でEmmetが使えるようになっており、htmlファイルを編集する際はすぐに使えます。しかし、ファイルの拡張子が.erb
の場合は特別な設定が必要です。
こちらのサイトなどを参考に、拡張子が.erb
のファイルでもEmmetの機能が利用できるようにVSCodeを設定しましょう。
Emmetの使い方
Emmetの使い方はさまざまなWebサイトで紹介されています。例えばこちらのサイトなどを参考にしてください。
アクションプラン
- 拡張子が
.erb
のファイルでもEmmetが利用できるようVSCodeを設定する
文字の大きさや要素の幅は8の倍数にする
重要度★★
文字の大きさは情報の重要度ごとに8px, 16px, 32pxのいずれかに設定しましょう。ブロック要素の幅(margin, padding)も同様に8px, 16px, 32pxのいずれかにします。
なお、大きさについてはちょうど8の倍数にすることが難しい場合もあるので、考えなくても大丈夫です。
どうしても小さな横幅を作りたい場合は4pxを利用することも可能です。
理由
デザインの一貫性を出すためです。このルールは、日本のデジタル庁のデザインでも採用されています。
これだけが正解というわけではもちろんありませんが、一度ルールを決めてしまえばそれに従うだけで自動的に綺麗な見た目になるため、自身でこだわってさまざまな余白の幅を設定してしまうよりもはるかに良いものにできますし効率的です。
アクションプラン
- 要素と要素の間の幅や余白を作るときは、8の倍数のサイズにする
- 文字の大きさは重要度に応じて8の倍数のサイズにする
CSSのクラス名の付け方を工夫する
重要度★★
CSSのクラス名もルールに沿って名付けましょう。
実はCSSの命名にも一定のルールが提唱されています。
今回はそのうち、BEMと呼ばれるものの考え方をベースにした方法を紹介します。
まず、そのviewを表示しているコントローラの名前とアクション名を組み合わせた文字をクラス名の頭につけます。tweetsIndex
, userShow
などです。
そしてその後にアンダーバー2本をつけ、その要素が担う役割、パーツの名前をつなげます。tweetsIndex__linkButton
、userShow__userName
のような形になります。
このような名前にしておくことで、CSS名が被る心配を減らすことができます。また、htmlの各要素の役割がわかりやすくなります。
例として、自分がおすすめしたいご馳走を紹介するSNSを想定します。以下は、そのSNSの投稿詳細ページです。
そのアプリの投稿詳細ページのhtml/cssであれば以下のように命名します。クラス名などに出てくる「feast」は「ご馳走」という意味の英語です。
<div class="feastShow__imgContainer">
<% if @feast.image.present? %>
<%= image_tag @feast.image if @feast.image.attached? %> #投稿に画像が添付されていたら表示する
<% else %>
<i class="fas fa-user-circle fa-5x"></i> # fontawesomeというアイコンを表示するためのライブラリを利用している
<% end %>
</div>
<div class="feastShow__container">
<% if user_signed_in? && @feast.user.id == current_user.id %>
<div class="feastShow__editButtonBox">
<%= link_to '編集する', edit_feast_path(@feast), class: "feastShow__editButton" %>
</div>
<% end %>
<div class="feastShow__powerWord">
"<%= @feast.power_word %>"
</div>
<div class="feastShow__infoBox">
<div class="feastShow__infoHigh">
<div class="feastShow__restaurantName">
<%= @feast.restaurant_name %>
</div>
<div class="feastShow__nearestStation">
<%= @feast.nearest_station %>
</div>
</div>
<div class="feastShow__infoLow">
<div class="feastShow__genre">
<img src="https://example.s3.ap-northeast-1.amazonaws.com/fork-knife.svg" alt="" class="feastShow__genreIcon">
<%= @feast.genre.name %>
</div>
<div class="feastShow__situation">
<img src="https://example..s3.ap-northeast-1.amazonaws.com/user-heart-alt-1.svg" alt="" class="feastShow__situationIcon">
<%= @feast.situation.name %>
</div>
<div class="feastShow__priceRange">
<img src="https://example.s3.ap-northeast-1.amazonaws.com/circle-yen.svg" alt="" class="feastShow__priceRangeIcon">
<%= @feast.price_range.name %>
</div>
</div>
</div>
<div class="feastShow__UserInfoBox">
by
<% if @user.image.present? %>
<p class="index__userImage" style="background-image: url(<%= rails_blob_url(@user.image) %>);">
</p>
<% else %>
<i class="fas fa-user-circle fa-5x"></i>
<% end %>
<%= @user.nickname %>
</div>
<div class="feastShow__buttonContainer">
<div class="feastShow__visitButton">
<%= link_to "#{@feast.restaurant_url}", target: "_blank", rel: "noopener" do %>
<div class="feastShow__buttonInner">
お店のサイトを見る
</div>
<% end %>
</div>
</div>
<h3 class="feastShow__heading3">推しポイント</h3>
<div class="feastShow__review">
<%= @feast.review %>
</div>
<h3 class="feastShow__heading3">スペシャリテ (私のとっておき)</h3>
<div class="feastShow__specialite">
<%= @feast.specialite %>
</div>
</div>
CSSの命名は自分でルールを決めて好きにつけて良いのですが、こちらのページでは以下のようにしています。
CSS名 | 説明 |
---|---|
__container | 何かしらの要素を囲いデザインを整えるための要素 |
__hogeBox | 何かしらの要素を囲いmargin/paddingで幅をとり、デザインを整えるための要素 |
__hogeButton | 何かしらのボタン要素 |
__heading3 | そのページにおけるh3要素の装飾を行う |
その他、表示したい内容はDBのカラム名をそのまま利用しています。
CSSはコメントでどこに何を書いているかわかるようにメモしておく。できればCSSのファイルをページごとに分ける
重要度★★
CSSファイルに無秩序にCSSを書いていくと、どこに何を書いたかわからなくなっていき、CSSファイルの保守が難しくなっていきます。以下のようにコメントアウトを活用して、どこからどこまでに何についてのCSSを書いたのかがわかりやすいようにしておきましょう。
// 投稿詳細
.feastsShow__container{
padding: 16px 32px;
}
.feastsShow__editButtonBox{
text-align: right;
padding: 0 0 8px 0;
}
.feastsShow__PowerWord{
width: 90%;
margin: 0 auto;
color: var(--text-white, #F6F1F9);
/* Title2/Emphasized */
font-family: -apple-system, BlinkMacSystemFont;
font-size: 22px;
font-style: normal;
font-weight: 700;
line-height: 28px; /* 127.273% */
letter-spacing: -0.4px;
}
.feastsShow__InfoBox{
margin: 8px 0;
padding: 16px;
background-color: #212121;
}
.feastsShow__InfoHigh{
display: flex;
justify-content: center;
margin: 0 0 10px 0;
}
.feastsShow__InfoLow{
display: flex;
justify-content: center;
}
さらにわかりやすくするために、各ページごとにCSSのファイルを作成し、それを全て読み込むようにすることもできます。
そのためにはまず、application.css
のファイルの拡張子をscss
に変更します。
SCSS
はCSSの強化版のようなもので、基本的にはCSSファイルと同じように扱えます。
SCSSは、他のファイルを自身に読み込むことができます。これをインポート
と呼びます。
RailsでSCSSファイルをインポートする方法は非常にシンプルで、@import命令を使用します。@importは指定されたSCSSまたはCSSファイルを読み込み、現在のファイルに結合します。
@import 'feastsNew';
@import 'feastShow';
@import 'feastsIndex';
この例では、feastsNew.scss, feastShow.scss, feastsIndex.scssという3つのファイルが、application.scss ファイルからインポートされています。このようにすることで、これらのファイルに定義されている全てのCSSルールが application.scss ファイルに取り込まれます。
なお、上記の例ではファイル拡張子を省略しています。これは @import 命令がSCSSファイルのインポートを行う際に、ファイル拡張子が .scss であることを暗黙的に認識しているからです。そのため、.scss を省略しても問題ありません。
アイコンなど画像を利用したい時はS3に画像を設置しリンクを利用する
重要度★★
アプリケーション上に、画像やアイコンなどを利用したい時があると思います。
そうしたアイコンは、flaticonなどの無料画像/アイコンダウンロードが可能なサイトを利用して手に入れましょう。
Renderでデプロイしている場合、Railsの特定のディレクトリに入れると画像やアイコンのファイルは消えてしまいます。そこで、S3のバケットに画像を置き、そこから公開用のリンクを利用してアプリで表示する方法を取りましょう。
やり方
まず、用意したバケットのアクセス許可を修正します。
バケットの個別ページに遷移した後、「アクセス許可」をクリックします。
以下のように、パブリックアクセスのブロックを解除します。
続いて、バケットポリシーを以下のように変更、保存してください。
{
"Version": "2012-10-17",
"Id": "Policy1544152951996",
"Statement": [
{
"Sid": "Stmt1544152948221",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::あなたのバケット名/*"
}
]
}
<i class="icon attention"></i>バケット名の部分はご自身のバケットの名前に修正してください。
最後に、バケットに画像をアップロードし、その画像のオブジェクトURLをimgタグのsrc属性に指定してください。
すると、以下の例のように画像を表示できるようになります。
<div class="feastShow__container">
<div class="feastShow__infoLow">
<div class="feastShow__genre">
<img src="https://example.s3.ap-northeast-1.amazonaws.com/fork-knife.svg" alt="" class="feastShow__genreIcon">
<%= @feast.genre.name %>
</div>
<div class="feastShow__situation">
<img src="https://example..s3.ap-northeast-1.amazonaws.com/user-heart-alt-1.svg" alt="" class="feastShow__situationIcon">
<%= @feast.situation.name %>
</div>
<div class="feastShow__priceRange">
<img src="https://example.s3.ap-northeast-1.amazonaws.com/circle-yen.svg" alt="" class="feastShow__priceRangeIcon">
<%= @feast.price_range.name %>
</div>
</div>
</div>
ChatGPTを「うまく」利用する
重要度★★
ChatGPTは、聞き方を工夫することでHTML/CSSについても書き方を教えてくれます。
その際、必ず自分が今書いているHTMLやCSSを情報として書いてあげるようにしましょう。
例として、実際にあったやりとりを紹介します。
###例
Railsのフォームを作成中、以下のようにジャンルを1つだけ選択できるデザインを作りたかった。
ChatGPTでの質問のやりとり
具体的なコードや、どのような形にしたいかを言語化すれば、HTML/CSSを提案してくれることがほとんどです。
しかし、「新規投稿のページを作って」や「かっこいい感じにして」という指示では、望んだイメージのものが提供されることはほぼありません。
提案されたHTML/CSSが理解できず、自身で応用できない、カスタマイズできないことにもつながります。
あくまで自身が書いて理解できているコードの一部分の改善をお願いするようにしましょう。そのためにも、HTML/CSSは自分が書いてきちんと理解できているものをChatGPTに提示するようにしましょう。
テキストにフォントを指定する
重要度★★
Webアプリケーションを作成する際は、サイトで利用するテキストにフォントを指定しましょう。
その際、*Appleがデザインを公開しているSF(サンフランシスコ)*というフォントを指定します(おすすめというだけで、他のフォントを選択しても構いません)。
理由
Webサイトに表示される文字のフォントを適切なものに変更するだけで見栄えがよくなります。また、ブラウザの種類ごとにフォントが変わってしまう問題を防ぐことができます。
やり方
CSSファイルにて、body
タグにfont-family
プロパティを適用します。
body {
font-family: -apple-system, BlinkMacSystemFont;
}
ブラウザでページを見て、フォントが変更されていれば成功です。
Discussion