Rails – パスワードの暗号化~ゼロから

概要

パスワードをデータベースに保存する際に暗号化して、万一流出した際のリスクを減らす方法。ここではハッシュ化してメッセージダイジェストにすることを「暗号化」とする。

暗号化されたパスワードを保存しておき、サインインの際に入力されたパスワードを同じ手順で暗号化し、得られたメッセージダイジェストが一致すれば符合しているとする。

以下の方法で順次リスクを減らしていく。

  1. パスワードをハッシュ化
  2. パスワードにソルトを連結してハッシュ化
  3. パスワードとソルトをそれぞれハッシュ化したものを連結してハッシュ化
  4. より安全性の高いハッシュ化を適用

ここでは3つ目の方法でRailsのDigest::MD5を使った手順を整理。

手順

パスワードを与える。

password = "pass"

ソルトを準備する。

salt = "SdvLigVDW3iDtHGAYvccBSbDn+jl"

パスワードとソルトを連結した文字列を暗号化する。

Digest::MD5.hexdigest(pass_digest + salt_digest)

この結果、以下のメッセージダイジェストが得られる。

"d1d7bd4a8d1e0a3be09d701db50ec038"

パスワードをpass→sassにしたときのメッセージダイジェストは以下の通り。

"82035cbcc496621133b8773709285313"

モデルへの実装

Railsでモデルを介してデータベースに登録する場合、モデルに暗号化の処理を書く。たとえばUserモデルのpasswordを暗号化する場合の例は以下の通り。

before_createでコールバックを設定していて、データベースへの書き込み前にencrypt_passwordメソッドが呼ばれる。

これをbefore_saveで呼ぶとデータ更新のときにもパスワードがハッシュ化されてしまうので、データの新規作成のときだけ呼ばれるようbefore_createで呼ばなければんならない。

encrypt_passwordはクラスメソッドのpassword_digestpasswordをメッセージダイジェストに変換し、その値でpasswordを書き換える。

password_digestメソッドは、パスワードとソルトからメッセージダイジェストを返す。

その結果、データベースへの書き込み時には暗号化されたパスワードが保存される。

 

Rails – flash

概要

flashはFlashHashクラスのインスタンスで、エラーなどのメッセージを遷移後の画面に表示するときに使う。ハッシュの様に状態キーに対するメッセージを登録するが、リクエストごとにクリアされる(Railsガイド)。

たとえばエラーメッセージの表示に使う手順は以下のとおり。

  1. バリデーションや保存処理などの結果に応じて、flashをセット
    • flash[状態キー] = "メッセージ"
  2. リダイレクト後の画面でflashを参照し、状態キーに応じたメッセージを表示

基本動作

前提

たとえば以下の例ではform_with@userの名前(:name)を入力して、ユーザー名が英数6文字以内であることを要求している。

app/views/flash_test.html.erb

モデルのバリデーションで、ユーザー名の長さと構成文字の検証を行う。

  • ユーザー名は6文字以上
  • ユーザー名に使える文字は英数字のみ

app/models/user.rb

flashへの登録

通常はバリデーションはデータベースへの書き込み時に行われるが、ここではvalid?でバリデーションを強制している。

検証の結果が適正であればflashに:successのキーで「適正な入力」、不適正であれば:dangerのキーで「不適正な入力」のメッセージを登録している。

その後、結果によらず最初のページを表示するアクションへリダイレクト(リダイレクト先のページは任意だが、ここでは最初のページにしている)。

app/controllers/pages_controller.rb

flashに対応した表示

リダイレクト/レンダリング後のビューに、flashの結果に応じた表示を行うコードを追加する。

app/views/flash_test.html.erb

flashのキー・値のセットの分だけeachで取り出して表示するが、その際にキーに応じたクラスを設定している。

そのレンダリング結果を確認してみよう。

遷移前のページでの入力が適正だった場合は、コントローラーでflash:successをキーとして「適正な入力」のメッセージ文字列が渡される。このとき、キーの内容(:success)を使ってクラス設定が行われる。

一方、入力が不適正だった場合にはコントローラーでflash:dangerをキーとするメッセージが渡され、それがレンダリングされた結果は以下のとおり。

この結果、遷移前のページでのバリデーション結果に応じた表示が行われる。

スタイルの変化

動的なクラス設定に対するスタイル

先のコードで、入力の結果に応じてメッセージのクラスが動的に設定された。スタイルファイルでそれらのクラスに応じたスタイルを定義することで、結果に応じた変化をつけることができる。

以下のスタイルファイルは、flashの結果セットされたクラスに応じてメッセージの色に変化をつけている。

処理の概要は以下のとおり。

  1. flashによる通知全般のスタイル設定
    .notice
  2. flashのキー(:success/:danger)に応じてセットされたクラスによって色を変化させる
    &_success/&_danger

<実行結果>

以下はバリデーションエラーの場合で、適正な場合は「適正な入力」と表示される。

ダイアログ表示

flashの内容を遷移後のページの表示前にダイアログで表示する場合、application.html.erbhead部分にJavaScriptを記述。

app/views/layouts/application.html.erb

処理の概要は以下のとおり。

  1. headブロックでダイアログ表示のスクリプトを定義
  2. flashがセットされている場合にダイアログを表示
  3. ダイアログのメッセージに、flashのすべてのメッセージを改行で結合して表示

<実行結果>

:dangerのときだけダイアログを表示する場合は以下の様になる。

has_key?を使うため、to_hashflashをハッシュに変換している。ただし、to_hashでハッシュに変換するとキーがシンボルではなく文字列になる点に注意。

一定時間後に表示を消す

flashに応じて表示されたメッセージを一定時間後に消すには、JavaScriptを使う。application.html.erbに以下の様に書く。

app/views/layouts/application.html.erb

処理の概要は以下のとおり。

  1. 必要に応じてJQueryを読み込む
  2. bodyの最初(最上部)にメッセージ表示エリアを定義
  3. 一定時間表示させた後にスライドアップで表示を消すスクリプトを定義
    1. $(".notice").slideUp()でメッセージをスライドアップ消去
    2. 1.5秒後に消去を実行するよう、window.setTimeoutにコールバックとして渡す

なお、:success:dangerによって表示の色を変える設定をCSSに書いている。

 

<実行結果>

以下、danger/successに応じた表示で、1.5秒後にこれらの表示がスライドアップされて消去される。

 

Rails – バリデーション

概要

Railsでモデルを介してフォーム入力を扱う場合、入力データが適正かどうか条件を設定して検証できる。

検証の条件はvalidatesをモデルクラス内で定義し、savevalid?などのメソッド実行に際して検証が行われる。これらのメソッドは検証結果の適正/不適正によってtrue/falseの戻り値を持つので、その結果に応じてflashによるエラー表示などの処理を行うことができる。

バリデーションの記述

モデルクラスの定義で以下を記述。

validates:(:対象カラム , 検証内容1, 検証内容2, ...) 

たとえばUserモデルのnameの存在と長さを検証する場合は以下のように書く。

app/models/user.rb

バリデーションの確認

通常、モデル内にvalidatesを書くと、モデルのsave実行前に検証が行われる。

モデルインスタンスのvalid?を実行すると、その時点でモデルの内容が妥当かどうかが検証され、検証結果が妥当であればtrue、妥当でなければfalseが返される。

また、妥当でない場合のエラーの内容は、モデルのerrors.messagesで確認できる。

app/controllers/users_controller.rb

たとえば検証結果が妥当な場合のRailsサーバーのログは、

何も入力しなかった場合は、

長さが制限を超えた場合は、

バリデーションの種類

presence~存在確認

<書式>

presence: true

入力内容がnil、空文字列、スペースでないことを検証する。全角スペースも検証の対象となる。内部でblank?メソッドを使っている。

<実行例>

モデル

errors.messages

逆にnil、空文字列、スペースのみであることを検証する場合はabscenceを使う。

length~長さの検証

<書式>

length: { 制限オプション: 制限値 }

長さを検証する。制限オプションと制限値のパターンは以下の通り。

  • :minimum:長さの最小値
    • 例:{ minimum: 10 }
  • :maximum:長さの最大値
    • 例:{ maximum: 20 }
  • :is:長さがこの値に一致しなければならない
    • 例:{ is: 10 }
  • :in/:witnin:長さの範囲
    • 例:{ in: 10..20 }

<実行例>

モデル

errors.messages

numericality~数値の検証

<書式>

numericality: true

numericality: { 制限オプション: 制限値 }

入力内容が数値形式であることを検証する。デフォルトでは整数・実数にマッチするが、制限オプションでいろいろなパターンを検証できる。

  • :only_integer:整数
  • :even/:odd:偶数/奇数
  • :equal_to:与えた数に等しい
  • :other_than:与えた数以外
  • :greater_than:与えた数より大きい
  • :greater_than_or_equal_to:与えた数より大きい
  • :less_than:与えた数より大きい
  • :less_than_or_equal_to:与えた数より大きい

<実行例>

errors.messages

format~パターンマッチング

<書式>

format: { with: 正規表現 }

入力のパターンが正規表現にマッチするかどうか検証する。正規表現を定数に設定しておく書き方が使われる。

<実行例>

モデル

errors.messages

検証結果のメッセージ

メッセージの構造

検証結果のエラーが1つの場合の、バリデーションのメッセージを確認する。

入力値とメッセージの内容は以下の通り。

 

この出力は以下のコードで表示させている。出力結果から、errors.messagesの内容は以下のようであることがわかる。

  • errors.messagesはハッシュ
  • ハッシュの キーはモデル名
  • ハッシュの値は配列で、配列の要素はメッセージ文

これを踏まえて、以下のコードの10行目のように取り出している。

複数の検証を設定した場合

1つの要素に複数の検証を設定し、それらがエラーになった場合を考える。

errors.messagesがハッシュなので、eachでキーと値を取り出し、その値が配列なのでeachで各メッセージを取り出す。

表示結果は以下の通り。

message:~メッセージの定義

メッセージは英語の文字列だが、message:で検証項目ごとのメッセージを定義できる。たとえば上の例で長さとパターンのそれぞれにメッセージを追加した例。

実行結果は以下の通り。

presenceuniquenessの場合は以下のように定義する。

presence: { message: "未入力の場合のメッセージ" }

uniqueness: { message: "重複したの場合のメッセージ" }

 

Rails – モデルによるフォームデータの取得

 

前提

例題として以下のようなモデルを使う。

  • モデル名はuser
  • モデルのフィールドはnamepasswordの2つで、いずれもstring

手順

モデルインスタンスとフォームの準備

フォームを呼び出すコントローラーで、モデルインスタンスを準備する。

app/controllers/pages_controller

フォーム側で、そのインスタンスを引数にとる。

app/views/pages/params_check.html.erb

 

フォームデータの取得

パラメーター取得の考え方

モデルを介してフォームデータを取得する考え方は以下の通り。

  • paramsrequireメソッドでモデルを指定してパラメーターを取得
  • Railsの慣習として、上記の処理をprivateメソッドとする

params.require

以下のメソッドチェーンで、パラメーターのハッシュが得られる。

params.require(モデル名).permit(キー1, キー2, ...)

今回の例の場合は以下の通り。

params.require(:user).permit(:name, :password)

メソッド化

コントローラーにprivateで以下のメソッドを定義。

データの利用

パラメーターが必要な場合はこのメソッドを呼び出す。たとえばフォーム入力データをコンソールに出力する例として、

以下はフォーム入力のコンソールへの出力例。

permitの意味~ストロングパラメーター

モデルに寄らないフォーム入力の場合paramsは単純なハッシュだが、モデルを介した場合は、paramsにモデル名をキーとするパラメーターのハッシュが含まれる。

今回の例の場合のparamsの内容は以下の通り。

params[:user]をキーとしたハッシュを取り出すと、フォーム入力が得られる。

そして、この結果はrequire.permitを通した結果とほぼ同じ。

 

ただし最後のpermittedが異なり、paramsの場合はfalsepermit.requireを通した場合はtrueになっている。

permitted: falseの場合はデータを一度に保存するマスアサインメントが使用できない。これを許すと、悪意のあるユーザーが不適切なデータを追加して送信し、データベースに書き込まれてしまう恐れがある。

require.permitによる場合はあらかじめ取り扱い可能なデータが限定されているので、permitted: trueに設定され、マスアサインメントが可能となる。

 

 

Rails – 掲示板 – フォーム入力の確認

概要

仮作成したページで、フォームからPOSTされたデータが取得できることを確認する。

掲示板の第1段階へ

アクションの追加

フォームからのデータはPOSTメソッドで送られてくるので、これを受信してサインアップ/サインインの処理を行うアクションをコントローラーに追加する。

ルーティング

追加したアクションに対するルーティングを設定する。

ルーティングの設定状況を確認すると、POSTメソッドに対するPrefixが設定されていない。

そこで、ルーティングにas:でPrefixを設定する。

その結果POSTメソッドのルーティングにもPrefixが設定され、Prefix_pathの定型句でのURL指定が可能になった。

フォームのURL指定

サインアップ/サインインを扱うアクションへのルーティングが決まったので、フォームのアクションを設定する。

sign_up.html.erbについては以下の通り。

sign_in.html.erbの方は以下の通り。

アクションのURL指定では、Prefix_pathの定型句を使っている。

パラメーターの確認

この状態でRailsサーバーを起動させて、サインアップページで何も入力せずにサインアップボタンを押す。

その処理結果をRailsサーバーのコンソールで確認すると、:name:email:passwordが送られてきているのがわかる(:passwprdはフィルタリングされている)。

これらの値はparams変数でキーを指定して参照することができる。PHPの$_POSTと同じように、paramsもグローバル・スコープを持っている。

ここでフォームに何か入力してサインアップボタンを押すと、以下のようにコンソールに入力内容が表示される。

params[:password]を直接表示させるとパスワードが平文で見られることに注意。

 

Rails – 掲示板 – 仮ページの作成

概要

コントローラーとビューの準備によって、プロジェクトの枠組みをつくった。

ここでは、仮置きのページとして3つのhtml.erbファイルの内容を書いていき、それらにスタイルを定義する。

掲示板の第1段階へ

ルーティング

第1段階では、それぞれのページのURLを指定して表示させる設定。

ルーティングの状況を確認する。後でヘルパーのリンク先URLを指定するとき、Prefix_pathという定型句で指定することができる。

共通レイアウト

サインアウト中ページ用

application_signed_out.html.erb

サインアウト中のページには特にヘッダーメニューなどを表示しないので、デフォルトで生成されたapplication.html.erbの内容通り。

ただしこちらを利用するのがsign_insign_upの2つのアクションだけと限定的なので、ファイル名を変更する。

users_controller.rb

デフォルトのapplication.html.erb以外を共通レイアウトとして使う場合は、コントローラーから明示的に呼び出す。

サインイン済みページ用

application.html.erb

サイン済みユーザーに対しては、第1段階ではtopページのみ表示させるが、今後いろいろな機能をつけていく。こちらの方が主になるので、ファイル名をデフォルトのapplication.html.erbとし、ヘッダーメニューを加える。

header.scss

ヘッダーに対するスタイル定義(HTML/CSSのヘッダーメニューを参照)。

個別ページ

topページ

top.html

第1段階では、仮置きとしてユーザー一覧を表示させる。

pages.scss

topページに対するスタイル定義は、topアクションを持つpagesコントローラーと同名のscssに書く。

メイン部分の領域が縦一杯に広がるようにするために、htmlbodyheightに100%を指定している。

sign_upページ・sign_inページ

sign_up.html.erb

sign_upsign_inは殆ど似たような内容・デザイン。モデルなしのform_withヘルパーを使い、URLは仮置きしている。

また、link_toヘルパーのリンク先に、ルーティングのPrefixを使った名前でURLを指定している。

sign_in.thml.erb

users.scss

sign_upsign_inの2つのビューのスタイルは、それらのアクションを持つusersコントローラーと同名のusers.scssに書く。

リセットCSS

reset.scss

リセットCSSにはEric Meyer’s “Reset CSS” 2.0を使った。

スタイルの読み込み

application.html.erbapplication_signed_out.html.erbのいずれも、最初にapplication.cssを呼び出している。その中で必要なSCSSファイルを読み込んでいる。

書くスタイルファイルが読み込まれるのは1度だけなので、最初にreset.scssを読み込み、その後require_treeでそれ以外のすべてのファイルを読み込む。

 

Rails – 掲示板 – 第1段階

概要

掲示板を例にして、ユーザーの登録、サインインを実装する。サインイン済みの場合のみトップページを表示するアクセス制限も実装する。

掲示板の全体ページへ

要件

画面遷移

  • アクセス時に/topにルーティング
    • サインイン状態でなければ/sign_inにルーティング
    • 仮表示として登録されているユーザー名、メールアドレス一覧を表示
    • ログアウト
      /sign_in
  • /sign_in
    • リンクをクリックして/sign_up
    • ユーザー名、パスワードを入力
      /top
  • /sign_up
    • リンクをクリックして/sign_in
    • ユーザー名、メールアドレス、パスワードを入力してユーザー登録
      /top

データベース

登録ユーザーテーブル:users

カラム名 型(MySQL) 型(Rails) 内容
id BIGINT(AI) Rails生成
name VARCHAR(255) string ユーザー名
email VARCHAR(255) string メールアドレス
pasword VARCHAR(255) string パスワード
created_at DATETIME Rails生成
updated_at DATETIME Rails生成

検討

コントローラーとアクション

pages_controller.rb

  • トップページなどサイト全体に関するページのコントローラー
  • top:サインインユーザーに対するサイトのトップページをレンダリング

users_controller.rb

  • ユーザーの登録、サインインなどユーザー管理を担うコントローラー
  • sign_in:サインインページをレンダリング
  • sign_up:サインアップページをレンダリング
  • sign_in_process:サインインフォームのPOSTに対するサインイン処理
  • sign_up_process:サインアップフォームのPOSTに対するサインアップ処理

ビューファイル

pages

  • top.html.erb:サインインユーザーが最初に見るページ
    • BBSの記事などが載ることになるが、この時点では登録済みのユーザーリストを表示する
    • ヘッダーメニューを表示する

users

  • sign_up.html.erb:未登録ユーザーのためのサインアップページ
  • sign_in.html.erb:登録ユーザーのためのサインインページ
  • これらのページにはヘッダーメニューは表示されない

共通のビューファイル

共通のビューファイルはlayoutディレクトリーに置く。サインインの有無に対応したレイアウトを分け、デフォルトでない場合はコントローラーから明示的に呼び出して使い分ける。

  • application.html.erb:サインイン済みのユーザーに対しては登録やサインアウトといった処理のメニューをヘッダーに表示する
  • application_signed_out.html.erb:サインインしていないユーザーに対してはヘッダーメニュを表示しない

スタイルファイル

CSSのスタイルをリセットするファイルを準備。

  • reset.css

ヘッダーメニューのスタイルファイルを独立して準備。

  • header.scss

各ビューのスタイルファイルはコントローラー単位のファイル。

  • pages.scss
  • users.scss

実装手順

 

 

Rails – 画像ファイルの配置とパス指定

概要

Railsで画像ファイルを配置するのは以下の2箇所

app/assets/images
開発側で準備するロゴやアイコンなど
public
ユーザーのアップロード画像など

それぞれの下にディレクトリーを作って、その中の画像ファイルをimg要素、div要素の背景画像で読み込む場合のパス指定について整理した。

ビューファイル&img要素の場合

app/assets/images

サブディレクトリ―exampleの下にimage_assets.jpgを置いた場合。

example/ファイル 読み込めない
/example/ファイル 読み込めない
./example/ファイル 読み込めない

public

サブディレクトリ―exampleの下にimage_public.jpgを置いた場合。

example/ファイル 読み込める
/example/ファイル 読み込める
./example/ファイル 読み込める

ビューファイル&img_tagの場合

app/assets/images

サブディレクトリ―exampleの下にimage_assets.jpgを置いた場合。

example/ファイル 読み込める
/example/ファイル 読み込めない
./example/ファイル NoMethodError

public

サブディレクトリ―exampleの下にimage_public.jpgを置いた場合。

example/ファイル Sprockets::Rails::Helper::AssetNotFound
/example/ファイル 読み込める
./example/ファイル NoMethodError

SCSS&div要素の背景画像の場合

app/assets/images

サブディレクトリ―exampleの下にimage_assets.jpgを置いた場合。

example/ファイル 読み込める
/example/ファイル 読み込めない
./example/ファイル 読み込めない

public

サブディレクトリ―exampleの下にimage_public.jpgを置いた場合。

example/ファイル 読み込めない
/example/ファイル 読み込める
./example/ファイル 読み込めない

まとめ

img要素はpublicの画像は読めるがassetsの画像は読めないので、img_tagヘルパーを使う方がよい。画像をimg_tagで配置する場合も、div要素の背景画像とする場合も、ファイルのパス指定は以下の通り。

パス指定
app/assets/images サブディレクトリ―/ファイル
public /サブディレクトリ―/ファイル

参考

確認に使ったアプリケーションファイル

pages_controller.rb

image_location.html.erb

pages.scss

 

Tips – ヘッダーメニュー

概要

HTMLのheader要素内に固定メニューを配置する。左端にロゴ画像を置き、メニューは右寄せで配置する例。

HTML/CSS

HTML

ヘッダーにdiv要素によるロゴ画像とulによるメニューを配置し、スタイルはCSSで設定する。

CSS

header内のロゴとメニューブロックをFlex-boxで配置し、左右に寄せている。メニューリストの水平配置にもFlex-boxを使っている。

なおheaderを固定してbodyのみをスクロールさせることもできる。

  • 最初のブロックでスタイルをリセット。
  • header要素
    • display: flex指定でコンテンツ(ロゴ、メニューブロック)をフロートさせて配置
    • justify-contentで2つのコンテンツを左端と右端に寄せる
    • 高さを指定
  • .header_logo
    • div要素に背景画像を指定
  • .header_menu
  • .header_menu li
    • 最初の3行はリストの中の文字を縦横センタリングする設定
  • .header_menu li + li

ロゴのサイズについて

  • div要素で背景画像のみを表示させるときはwidth/heightを明示的に設定しなければならない
  • 当初はheight: 100%headerの高さに合わせ、width: autoで表示されていた
  • ところがそこで親のheaderdisplay: flexを設定すると表示が消えてしまった
  • そこでここでは、グローバルなカスタムプロパティーを使っている

Rails/SCSS

HTML

  • 通常すべてのレンダリング時に使われる共通レイアウト
    • app/views/layouts/application.html.erb
  • これとは別にヘッダーメニューが必要な場合の共通レイアウトファイルを作成
    • app/views/layouts/application_with_header.html.erb

ヘッダーメニューが必要なアクションのみこのレイアウトを使うため、コントローラーでレイアウトファイルを指定。

レイアウトファイルが読み込むスタイルシートは標準と同じapplication.css

requireされるlayout.scssで、ヘッダーメニュー用のSCSSを読み込む(ヘッダーメニューがない場合も読み込む)。

SCSS

以下のSCSSファイルを作成して読み込ませる。リセットCSSは別に読み込んでいる。

 

Tips – フォームのデザイン

概要

  • テキストフィールドや送信ボタンなどを含むフォームのデザインについて
  • input要素などのコンテンツから組み上げる方法と、flex-boxを使った方法の2つ。
  • フォーム全体のページ内の位置設定についても含めた

共通事項

元になるHTML

3つのinput要素と1つのbutton要素を含むform要素。form_blockというクラスのdiv要素でラップする。

Railsのhtml.erbの場合は以下の様になる。

 

リセットCSS

CSSでは以下で関係要素のスタイルをリセットする。

Railsの場合は別にreset.cssを準備する(Eric Meyer’s “Reset CSS” 2.0)。

body要素

body要素は背景色だけを設定する。

方法1~要素スタイルの積み上げ

CSS

CSSの内容

CSSの全体は以下のとおり。以下、手順を分解して整理する。

div要素によるラップ

  • div要素で表題(h1)とform要素全体をラップする
  • 幅は400pxに設定
  • 高さ指定をしない(auto)なので、子要素に応じて全体の高さが変わる

表題

  • フォームの表題をh1要素で書いている

form要素

  • form要素のパディングと背景色を設定
  • 幅は親要素のdivにフィットし、高さは子要素群に合わせて変わる

input要素

  • インラインレベル要素のinputをブロックレベル要素に変更
  • box-sizingborder-boxに指定
    • これを指定しないとinput要素がはみ出てしまう
  • 幅(width)は親要素に合わせる
  • 高さは32px固定
  • マージン(下)を設定して間隔をあける

button要素

  • インラインレベル要素のbbuttonをブロックレベル要素に変更
  • 幅は親要素formの50%
  • margin-left: autoで右寄せ
    • 中央に置く場合はmargin-right: autoも加える

フォームの位置調整

  • もう一度全体をラップしているdiv要素に戻り、bodyに対する位置を指定する
    • フォームの左上隅が上端から20%、左端から40%

SCSS

RailsなどでSCSSを使う場合の例。

 

方法2~flex-box

CSS

CSSの内容

flex-boxを使ったCSSの全体は以下のとおり。フォーム全体の位置設定は方法1と同じ。

div要素によるラップ

  • 幅は400px
  • 高さはautoとし、子要素のformの髙さに合わせる

form要素

方法1と違うのは以下の点。

  • display: flexで子要素へのflex適用を指定
  • flex-direction: columnで子要素を縦並びに
  • justify-content: space-aroundで子要素を均等に配置
  • 高さを200pxに固定

input要素

要素の間隔は自動的に決まるので、方法1で設定していたmragin-bottomを削除している。

button要素

  • button要素もマージンを削除している
  • 右寄せにするため、align-self: flex-endを設定
    • 中央に置く場合はcenterを指定

SCSS

RailsなどでSCSSを使う場合の例。