【CSS】Flexboxの使い方を徹底解説!基本から実践まで(サンプルあり)

「Flexboxは、どんなことができるのか、いまいち分かっていない。」
「Flexboxって、横並び機能のfloatやdisplayとどう違うの?」

CSSの学習を始めた人の中には、こう思う人もいるでしょう。Flexboxは、従来、javascriptや他のCSSプロパティを駆使しながら実現していた複雑なレイアウト設計を簡単に実現します。今後、設計の主流になる可能性が高く、確実に理解し、使いこなせるようにしておきたいものです。Flexboxの守備範囲は、ほかのCSSプロパティに比べて広いため、最初の学習コストはかかりますが、それだけの価値があります。これまでmarginやpaddingでの調整に苦労してきた方は、これを学ぶことで大きな安心感がうまれるはずです。

今回は、CSS3で導入されたFlexboxを初心者の方でもわかりやすいように説明します。

【初心者向け】CSS(スタイルシート)の書き方を丁寧に解説



Flexboxとは?

Flexboxとは、CSSで行う要素の「配置」を短いコードで柔軟に行えるレイアウトモードです。初心者の方は、配置と聞くと「float」「display」「margin」などのプロパティを思い出す人もいるでしょう。もちろん、これは非常に便利なのですが、それぞれの癖を把握して利用しないとレイアウトが崩れたり、思わぬ変更を余儀なくされるものです。Flexboxを使えば、このような心配から解放されます。

また、現時点では、ほとんどのブラウザに対応しています。

対応ブラウザ

Flexboxを用いた効果

  • 要素内の縦横の配置が簡単にできる(複雑なコードを書く必要がない)。
  • HTMLでの要素の順番にかかわらず、CSSだけで自由に表示順序を変えることができる。
  • 要素間の幅の指定も柔軟にでき、要素内の分量が違っても、高さや幅を調整できる。
  • 要素間の余白の設計をそれほど気にする必要がない。

Flexboxの特徴

Flexboxの特徴は、flexを設定した親要素が「flexコンテナ」と言われるものに性質を変え、その子要素は自動的に「flexアイテム」と呼ばれるものに変わり、親要素に対するFlexプロパティの設定によって、要素の配置、順番を柔軟に変更できるようになることです。

Flexboxでは、子要素の配置を変える場合に、親要素に「display: flex;」を置くことがポイントです。これにより、親要素が「flexコンテナ」へ、子要素が「flexアイテム」へと変わり、これが基本となります。

.親要素{
  display: flex;
}

Flexプロパティと値の俯瞰図

ただ、配置や順番を指定するプロパティとそれが用意している値を同時に指定する必要があります。Flexboxを学習する場合、このプロパティの特徴を最初に理解することが大変です。以下の図は、このflexboxで使えるプロパティと値の一覧です。この全体像を見ると、一気に拒否感を覚える人もいるかもしれませんね。でも、指定は非常に簡単で、一度は、全ての挙動を確認することをお勧めします。
さらに詳しく理解したい方はこちら

要素 プロパティ名 説明
Flexコンテナ(親要素に設置) flex-direction(要素の方向を決める) row(初期値) 子要素を左から右に配置する。設定しなくても同じ効果が得られる。
row-reverse 子要素を右から左に配置する。rowの逆と考えれば良い。
column 子要素を上から下に配置。display: flex;を設定すると自動的に「flex-direction: row;」の効果が出ることから、これをしない場合は、敢えて、「column」を設定する。レスポンシブ対応の場合に使用するケースがある。
column-reverse 子要素を下から上に配置。columnの逆と考えれば良い。
flex-wrap(要素の折り返し) nowrap(初期値) 子要素を左から右へと配置するが、折り返しは行わないため、画面サイズが縮小しても、1列に並んだままとなる。
wrap 子要素を折り返す。
wrap-reverse 子要素がコンテナの幅を超える場合は折り返し、複数行に下から上へ並べる
flex-flow(一括設定) 「flex-direction」 と「flex-wrap」をまとめて書くことができる。例えば、「flex-flow: row wrap;」のように、一つにまとめて書くとコード量も減って良い。
justify-content(水平方向の配置) flex-start(初期値) 水平方向の配置をコントロールできる。flex-startは、左揃えで要素が配置される。
flex-end flex-startの逆で、右揃えで要素が配置される。
center 水平方向の中央に要素が配置される。「margin: 0 auto;」と同じ効果が得られる。
space-between 水平方向の配置だが、最初と最後の子要素は、コンテナの両端に余白なしできっちり配置しさる。残った要素は均等な余白で配置される。
space-around 水平方向の配置で、全ての要素が均等の余白とともに配置される。space-betweenとの違いは、コンテナ内の両端の要素に余白があるかどうか。
align-items(垂直方向の配置) stretch(初期値) 垂直方向の配置をコントロールできる。親要素の高さか要素の中で一番高い子要素の高さに合わせて配置してくれる。
flex-start 親要素の開始位置から要素が配置され、上揃えで並ぶ。
flex-end 親要素の終点から要素が配置され、下揃えで並ぶ。
center 縦の中央配置となる。
baseline ベースラインで揃えられた配置となる。/td>
align-content(複数要素の配置) stretch(初期値) 複数要素の配置をコントロールできるが、親要素の高さ、あるいは、子要素の中で一番高い要素に合わせて配置してくれる。
flex-start 複数要素を親要素の開始位置から、上揃えで配置してくれる。
flex-end 複数要素を親要素の終点から下揃えで配置してくれる。
center 複数要素を縦揃えで中央配置してくれる。
space-between 最上部と最下部の子要素を上下の端に余白なく配置し、残りの要素は均等な余白で配置してくれる。
space-around 部と最下部の子要素を均等な余白で配置してくれる。
Flexアイテム(子要素に設置) order(要素の順番) 初期値は0。要素の順番をHTMLの順番に関わらず変更できる。
flex-grow(要素の伸張) 要素の配置後、親要素に余ったスペースがあった場合、flex-growを指定した子要素が他の子要素に対してどれくらい伸びるかを決めることができる。マイナス値は無効となる。
flex-shrink(要素の縮小) flex-growと逆の効果で、どれくらい縮むかを決めることができる。親要素に余ったスペースがない場合で、全ての要素が入り切らない場合、flex-growを指定した子要素が他の子要素に対して縮む設定数値だけ縮む。マイナス値は無効となる。
flex-basis(要素の幅) widthプロパティと同じように幅の値(パーセンテージやピクセル値)を指定できます。
flex(一括設定) flexプロパティだけを指定すれば、「flex-grow」、「flex-shrink」、「flex-basis」の3つを一括で指定できます。初期値は「flex: 0 1 auto;」となります。
align-self(子要素の垂直方向の配置) auto 親要素のalign-itemsの値が継承されます。
stretch 親要素の高さや一番高い要素に合わせて配置されます。
flex-start 親要素の開始位置から上揃えで配置されます。
flex-end 親要素の終点から下揃えで配置されます。
center 要素を中央揃えします。
baseline 要素をベースラインで揃えて配置します。

上記は、早速、挙動を確認していきましょう。

Flexboxコンテナのプロパティと値の使い方

Flexboxの挙動を確認するために、以下のHTMLコードを元に説明します。

<div class="flexcontainer">
      <div class="flexitem item1">Item 1</div>
      <div class="flexitem item2">Item 2</div>
      <div class="flexitem item3">Item 3</div>
      <div class="flexitem item4">Item 4</div>
      <div class="flexitem item5">Item 5</div>
    </div>
.flexitem{
  width: 100%;
  height: 100px;
  text-align: center;
}

.item1{
  background: #009933;
}

.item2{
  background: #0066FF;
}

.item3{
  background: #CC6666;
}

.item4{
  background: #CC66FF;
}

.item5{
  background: #FF33CC;
}

以下のように表示されています。

ここに「display: flex;」を指定します。

.flexcontainer{
  display: flex;
}

たったこれだけの指定ですが、要素が簡単に横並びになることがわかります。

更に、この要素の配置を詳細に指示することができるのが、flexboxの優れたところです。主に、起点の指示や余白設定の指示が可能です。これには大きく2つの指示の種類があります。親要素であるflexコンテナへの指示と子要素であるフレックスアイテムへの指示です。それぞれに必要なプロパティと値があるので、一つ一つ見ていきましょう。

Flexコンテナへの指示

子要素をコントロールし、配置を行うことでさえ、親要素の指示で可能になるのがflexboxのメリットです。上記の「display: flex;」の設定に加えて、幾つかのプロパティが用意されており、配置の起点を指示したり、余白設定を指示したりできます。

flex-direction

「flex-direction」プロパティは、要素の配置の向きを指示します。

row

値に「row」をとると、左から右方向への水平方向の配置となります。

.flexcontainer{
  display: flex;
  flex-direction: row;
}

これは、「display: flex;」と同じ効果です。

row-reverse

「row」の場合は、左から右へと配置しましたが、右から左へ要素を配置するのが「row-reverse」です。

.flexcontainer{
  display: flex;
  flex-direction: row-reverse;
}

表示は、「row」とは逆になります。

column

さて、レスポンシブに対応する場合、縦に配置を切り替えたい時もあるでしょう。その場合上から下へ要素を配置するのが「column」です。

.flexcontainer{
  display: flex;
  flex-direction: column;
}

表示は、「display: flex;]を設定する前の状態に戻りました。ただ、これは「display: flex;]が無効になったのではなく、敢えて、上から下へ要素を配置したのです。

column-reverse

要素の上から下への縦配置ではなく、下から上への縦配置を実現するのが、「column-reverse」です。

.flexcontainer{
  display: flex;
  flex-direction: column-reverse;
}

表示は、以下のようになります。

flex-wrap

「flex-wrap」は、子要素を折り返します。説明の便宜上、表示要素を以下のように増やします。

<div class="flexcontainer">
      <div class="flexitem item1">Item 1</div>
      <div class="flexitem item2">Item 2</div>
      <div class="flexitem item3">Item 3</div>
      <div class="flexitem item4">Item 4</div>
      <div class="flexitem item5">Item 5</div>
      <div class="flexitem item6">Item 6</div>
      <div class="flexitem item7">Item 7</div>
      <div class="flexitem item8">Item 8</div>
      <div class="flexitem item9">Item 9</div>
      <div class="flexitem item10">Item 10</div>
    </div>

「display: flex;」だけを設定している状態は以下のようになります。

nowrap

「nowrap」を設定すれば、絶対に要素が折り返すことはありません。いくら要素数が増えても横1行になります。

.flexcontainer{
  display: flex;
  flex-wrap: nowrap;
}

以下のように表示されます。

wrap

ここに、「flex-wrap: wrap;」を追加します。また、子要素の幅を30%とします。すると、flexコンテナの幅から外れた要素が下に折り返されます。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
}

.flexitem{
  width: 30%;
  height: 100px;
  text-align: center;
  font-size: 40px;
  color: #fff;
}

以下のように表示されます。

wrap-reverse

「wrap-reverse」は、要素を左下を起点として、横方向へ配置するプロパティです。

.flexcontainer{
  display: flex;
  flex-wrap: wrap-reverse;
}

以下のように、表示されます。

flex-flow

「flex-flow」は、一括設定のプロパティです。「flex-direction」と「flex-wrap」を同時に設定可能です。 以下のように書くことが可能です。

.flexcontainer{
  display: flex;
  flex-flow: row wrap;
}

justify-content

「justify-content」は水平方向の要素の配置に用います。

flex-start

これが初期値で、要素が左端から右へ並びます。わかりやすくするために、要素数を減らしています。

<div class="flexcontainer">
      <div class="flexitem item1">Item 1</div>
      <div class="flexitem item2">Item 2</div>
      <div class="flexitem item3">Item 3</div>
      <div class="flexitem item4">Item 4</div>
      <div class="flexitem item5">Item 5</div>
    </div>
.flexcontainer{
  display: flex;
  justify-content: flex-start;
}

以下のように表示されます。

flex-end

「flex-start」が左から右へ要素を配置するのに対して、「flex-end」は右から左へ要素を配置します。

.flexcontainer{
  display: flex;
  justify-content: flex-end;
}

.flexitem{
  width: 10%;
  height: 100px;
  text-align: center;
  font-size: 40px;
  color: #fff;
}

以下のように、右寄りで表示されます。

center

「center」は水平方向に配置される要素をコンテナ内で中央配置します。

.flexcontainer{
  display: flex;
  justify-content: center;
}

以下のように、要素が中央に配置されます。

space-between

「space-between」は要素を均等に配置します。その際、両端の要素はコンテナの両端に余白なく密着します。

.flexcontainer{
  display: flex;
  justify-content: space-between;
}

以下のように表示されます。

検証ツールで確認すると、両端の要素に余白はありません。

space-around

「space-between」と同様に、要素を均等に配置するのですが、それぞれの要素に余白を持って配置されます。

.flexcontainer{
  display: flex;
  justify-content: space-around;
}

以下のように表示されます。

検証ツールで確認すると、両端の要素にも余白があります。

align-items

「justify-content」が水平方向の配置を決めるのに対して、「align-items」は垂直方向の配置を決めます。

stretch

「stretch」は初期値です。最も高い要素に高さを合わせてくれます。わかりやすくするために、長さの違うテキストを入れています。

<div class="flexcontainer">
<div class="flexitem item1">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse .</div>
      <div class="flexitem item2">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </div>
      <div class="flexitem item3">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
      <div class="flexitem item4">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
      <div class="flexitem item5">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse.</div>
</div>

また、高さを取り除いています。

.flexcontainer{
  display: flex;
  align-items: stretch;
}

.flexitem{
  width: 30%;
  text-align: center;
  font-size: 20px;
  color: #fff;
}

以下のように表示されます。すべての要素の高さが合っていることがわかります。

flex-start

「flex-start」は、垂直方向の上部から要素を下に配列します。

.flexcontainer{
  display: flex;
  align-items: flex-start;
}

以下のように、表示されます。高さはそれぞれの要素に合わせて表示されます。

flex-end

「flex-end」は「flex-start」とは逆に、下から上へ要素が配置されます。

.flexcontainer{
  display: flex;
  align-items: flex-end;
}

以下のように表示されます。

center

「center」は垂直方向で、要素を中央に配置します。

.flexcontainer{
  display: flex;
  align-items: center;
}

以下のように表示されます。

baseline

「baseline」は、文字のベースラインが揃うように配置します。

.flexcontainer{
  display: flex;
  align-items: baseline;
}

以下のように表示されます。

align-content

「align-content」は複数の行に渡る要素の配置を決めます。

stretch

「stretch」は、「flex-wrap: warp;」で要素を折り返した時で、子要素の高さが設定されていない場合、自動的に親要素の高さに合わせて子要素の高さを調整します。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
  align-content: stretch;
  height: 500px;
}

以下のように、親要素の高さに合うように、自動的に高さが設定されます。

flex-start

「flex-start」は、上位置に要素をあわせ、下方向へ要素を並べます。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 500px;
}

以下のように表示されます。

flex-end

「flex-end」は、親要素の下から要素を配置します。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
  align-content: flex-end;
  height: 500px;
}

以下のように配置されます。

center

「center」は要素の中央配置です。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  height: 500px;
}

以下のように、要素群が中央に配置されています。

space-between

「space-between」は、縦方向で要素を均等に配置します。その際、上下両端の要素は親要素の上下に密接して配置されます。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
  height: 500px;
}

以下のように表示されます。

検証ツールで確認すると、上下の要素は余白なく、配置されていることがわかります。

space-around

「space-between」は、縦方向で要素を均等に配置します。その際、上下両端の要素には余白も含めて配置されます。

.flexcontainer{
  display: flex;
  flex-wrap: wrap;
  align-content: space-around;
  height: 500px;
}

以下のように表示されます。

検証ツールで確認すると、上下の要素が入って、配置されていることがわかります。

Flexアイテムへの指示

これまで親要素に指示を出すことで、要素を配置してきましたが、ここからは子要素そのものに対して指示を出します。

order

「order」プロパティに、数値を指定することで、要素の順番を変えることができます。まずは、orderを指定しない状態が以下になります。

<div class="flexcontainer">
      <div class="flexitem item1">Item 1</div>
      <div class="flexitem item2">Item 2</div>
      <div class="flexitem item3">Item 3</div>
      <div class="flexitem item4">Item 4</div>
      <div class="flexitem item5">Item 5</div>
    </div>
.flexcontainer{
  display: flex;
}

.flexitem{
  width: 30%;
  height: 100px;
  text-align: center;
  font-size: 30px;
  color: #fff;
}

以下のように表示されます。

次に、子要素に「order」プロパティと順番を示す数値を置きます。

.flexcontainer{
  display: flex;
}

.flexitem{
  width: 30%;
  height: 100px;
  text-align: center;
  font-size: 30px;
  color: #fff;
}

.item1{
  background: #009933;
  order: 4;
}

.item2{
  background: #0066FF;
  order: 3;
}

.item3{
  background: #CC6666;
  order: 5;
}

.item4{
  background: #CC66FF;
  order: 1;
}

.item5{
  background: #FF33CC;
  order: 2;
}

順番は任意に指定していますが、指示通りに要素の順番が変化しています。

flex-grow

「flex-grow」は親要素に余白がある場合、その余白に対してどの程度特定の要素の幅を伸ばせるかの指定ができます。例えば、以下のように左揃えの要素群があります。これに「flex-grow」を設定します。

.flexcontainer{
  display: flex;
}

.flexitem{
  width: 10%;
  height: 100px;
  text-align: center;
  font-size: 30px;
  color: #fff;
}

.item1{
  background: #009933;
  flex-grow: 3;
}

.item2{
  background: #0066FF;
  flex-grow: 1;
}

.item3{
  background: #CC6666;
  flex-grow: 1;
}

.item4{
  background: #CC66FF;
  flex-grow: 1;
}

.item5{
  background: #FF33CC;
  flex-grow: 1;
}

すると、余白を使って、指定した要素が伸びています。「flex-grow: 1;」はデフォルトの大きさと考えてください。

flex-shrink

「flex-shrink」は、「flex-grow」の逆で、親要素に余白がない場合、その余白に対してどの程度特定の要素の幅を縮められるかを指定できます。例えば、幅を

.flexcontainer{
  display: flex;
}

.flexitem{
  width: 30%;
  height: 100px;
  text-align: center;
  font-size: 30px;
  color: #fff;
}

.item1{
  background: #009933;
  flex-shrink: 3;
}

.item2{
  background: #0066FF;
  flex-shrink: 2;
}

.item3{
  background: #CC6666;
  flex-shrink: 1;
}

.item4{
  background: #CC66FF;
  flex-shrink: 1;
}

.item5{
  background: #FF33CC;
  flex-shrink: 1;
}

デフォルトの値は1で、数値が大きくなれば、縮小幅も大きくなります。

flex-basis

「flex-basis」は子要素の横幅を指定します。「auto」は子要素のもともとの幅が反映されます。

.flexcontainer{
  display: flex;
}

.flexitem{
  height: 100px;
  text-align: center;
  font-size: 30px;
  color: #fff;
}

.item1{
  background: #009933;
  flex-basis: 40%;
}

.item2{
  background: #0066FF;
  flex-basis: 30%;
}

.item3{
  background: #CC6666;
  flex-basis: 20%;
}

.item4{
  background: #CC66FF;
  flex-basis: 5%;
}

.item5{
  background: #FF33CC;
  flex-basis: 5%;
}

「width」と同じ効果で、幅が指定されていることがわかります。

flex

「flex」はこれまでの子要素への指定が一括で指定できるプロパティです。

.flexcontainer{
  display: flex;
}

.flexitem{
  height: 100px;
  text-align: center;
  font-size: 30px;
  color: #fff;
}

.item1{
  background: #009933;
  flex: 2 0 30%;
}

.item2{
  background: #0066FF;
}

.item3{
  background: #CC6666;
}

.item4{
  background: #CC66FF;
}

.item5{
  background: #FF33CC;
}

以下のように指定されます。幅は30%指定ですが、「flex-grow」が効いて、余白を埋めていることがわかります。

align-self

このプロパティは、垂直方向の配置を決めます。親要素に指定するalign-itemsと同じ効果が出せます。子要素に対して指定しますが、「align-self」は「align-item」よりも、優先されます。挙動は、「align-item」と同じとなりますので、サンプルコードは省きます。

auto

これを指定した場合は、「align-item」の指定が継承されます。

stretch

これを指定した場合は、親要素の縦幅に余裕があれば、その余白を使って縦幅を広げます。

flex-start

これを指定した場合は、親要素の上部開始位置から下方向へ、要素を配置します。

flex-end

これを指定した場合は、親要素の下部開始位置から上方向へ、要素を配置します。

center

これを指定した場合は、親要素の垂直方向の中心に、要素を配置します。

baseline

これを指定した場合は、親要素の垂直方向に文字のベースラインを想定し、要素を配置します。

実践:Flexboxでデザインを作ってみる

早速、Flexboxを使って、デザインをしてみましょう。今回は、以下のような画面を作ってみます。今回は、bootstrapもgridレイアウトも使わずに、flexboxの機能だけを使って作ってみます。

レイアウト

ポイントは2つです。幅の違う要素を横並びにすること、幅が同じ要素を横に均等配置することです。

HTML-1

以下のようなフォルダ構成です。

以下のHTMLを用意します。今からこの中でコーディングしていきます。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>サンプル-Flexbox</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <div class="container">

      ここに要素を追加します。
      
  </div>
</body>
</html>

上部HTMLの作成

では、上部部分のHTMLコードを以下のように設置します。上部は、2カラム構成となっていますが、幅は同じにします。
ダミー画像を使う場合は、こちらを参考にしてください。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>サンプル-Flexbox</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <div class="container">
       <div class="first-row">
      <div class="image-area r-1">
                <img src="http://lorempixel.com/800/400" />
      </div>

      <div class="discription-area r-1">
        <h1>Business Experience</h1>
        <p>This is a template that is great for small businesses. It doesn't have too much fancy flare to it, but it makes a great use of the standard Bootstrap core components. Feel free to use this template for any project you want!</p>
        <a class="btn" href="#">Call to Action!</a>
      </div>

    </div>
  </div>
</body>
</html>

first-rowという塊の中に、「image-area」と「discription-area」という二つの要素を入れています。「image-area」にはダミー画像を、「discription-area」には、hタグとpタグ、buttonを入れています。以下のような表示になります。

※ダミー画像を使用しているため、画像は切り替わります。

上部CSSの作成

次に、CSSを設定します。ポイントは、親クラスの「.first-row」に「display: flex;」を設定し、flexコンテナを作成したことです。これによって、要素が横に並びました。次に、幅を調整するわけですが、これは、「discription-area」に「flex-basis: 50%;」を設定しています。

.first-row{
  display: flex;
}

.r-1{
  margin: 5px;
}

.image-area{
  overflow: hidden;
}

.image-area img{
  width: 100%;
  height: auto;
}

.discription-area{
  flex-basis: 40%;
  padding: 20px;
}

.btn{
  color: #fff;
  padding: 15px 25px;
  width: 30%;
  background: #1b95e0;
  border-radius: 10px;
}

以下のように表示がされます。

もし、上部の要素に対して違う幅を指定する場合は、以下のように子要素に対してそれぞれ「flex-basis: 40%;」を設定してください。

.first-row{
  display: flex;
}

.image-area{
  overflow: hidden;
  flex: 1;
}

.discription-area{
  flex-basis: 40%;
  padding: 20px;
}

下部HTMLの作成

次に、下部のHTMLです。特徴は文の長さがそれぞれ違います。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>サンプル-Flexbox</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <div class="container">

      <div class="first-row">
        <div class="image-area r-1">
          <img src="http://placekitten.com/g/800/400">
        </div>

        <div class="discription-area r-1">
          <h1>Business Experience</h1>
          <p>This is a template that is great for small businesses. It doesn't have too much fancy flare to it, but it makes a great use of the standard Bootstrap core components. Feel free to use this template for any project you want!</p>
          <a class="btn" href="#">Call to Action!</a>
        </div>

      </div>

      <div class="title">
        <h4>This call to action card is a great place to showcase some important information or display a clever tagline!</h4>
      </div>

      <div class="second-row">
        <div class="card card-1">
            <div class="card-body">
              <h2 class="card-title">Card One</h2>
              <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem magni quas ex numquam, maxime minus quam molestias corporis quod, ea minima accusamus.</p>
            </div>
            <div class="card-footer">
              <a href="#" class="btn">More Info</a>
            </div>
        </div>

        <div class="card card-2">
            <div class="card-body">
              <h2 class="card-title">Card Two</h2>
              <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod tenetur ex natus at dolorem enim! Nesciunt pariatur voluptatem sunt quam eaque, vel, non in id dolore voluptates quos eligendi labore.Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod tenetur ex natus at dolorem enim! Nesciunt pariatur voluptatem sunt quam eaque, vel, non in id dolore voluptates quos eligendi labore.Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod tenetur ex natus at dolorem enim! Nesciunt pariatur voluptatem sunt quam eaque.</p>
            </div>
            <div class="card-footer">
              <a href="#" class="btn">More Info</a>
            </div>
        </div>

        <div class="card card-3">
            <div class="card-body">
              <h2 class="card-title">Card Three</h2>
              <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem magni quas ex numquam, maxime minus quam molestias corporis quod, ea minima accusamus.</p>
            </div>
            <div class="card-footer">
              <a href="#" class="btn">More Info</a>
            </div>
        </div>
      </div>

  </div>
</body>
</html>

下部のHTMLコードは以下のように縦に配置されます。

では、これに対してCSSを設定します。親要素である「second-row」に「display: flex;」を設定します。また、要素を均等に、また、端が揃うように「justify-content: space-between;」を設定しています。

.title{
  padding: 5px;
  border: 1px solid #17a2b8;
  border-radius: 10px;
  background: #17a2b8;
  color: #fff;
  text-align: center;
}

.second-row{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.card{
  border: 1px solid #6c757d;
  border-radius: 5px;
  padding: 20px;
  margin: 5px;
  width: 28%;
  min-height: 350px;
  position:relative;
}

.card-footer{
  position:absolute;
  bottom: 0;
  padding-bottom: 20px;
  margin-left: auto;
  margin-right: auto;
}

すると、文の長さが違っても、同じボックの高さで横に均等に配置されていることがわかります。本来であれば、文の長さに応じて、ボックスの高さが異なり、「max-height」などで調整するのですが、flexboxを使えば、この必要はありません。

また、本来の配置を無視して、要素の順番も変えることが可能です。例えば、以下をCSSに追加しましょう。

.card-1{
  order: 3;
}

.card-2{
  order: 1;
}

.card-3{
  order: 2;
}

すると、順番が変わりました。

これは、例えば、携帯やタブレットで見せるためにレスポンシブ化した場合、要素の見せ方を変えたい場合があり、その際に使うことが多いです。例えば、CSSにメディアクエリでブレイクポイントを指定しましょう。

@media screen and (min-width: 320px) {

.second-row{
  display: flex;
  flex-direction: column; =>カラムを縦に配置
}

.card-1{
  order: 3;
}

.card-2{
  order: 1;
}

.card-3{
  order: 2;
}

.card-body{
  margin-bottom: 40px;
}

効果がわかると思います。一番見て欲しいものの順番を先にし、カラムを縦の配列へ変更しています。

まとめ

flexboxプロパティを使えば、これまで「float」や「margin」で行ってきた配置が少数のコードで一気にできることがわかったと思います。Flexboxを使ったCSSのフレームワークとして、Bulmaも普及しており、一旦、Flexboxの理解や挙動の確認を行いつつ、このようなフレームワークを使うこともWebデザインのレベルを更に高めてくれます。









この記事をかいた人

田中 陽介

ベトナムで起業し、HR関連のコンサルティング業務をやっています。日本を離れて8年が経ちますが、日本ではあり得ないハプニングを楽しんでいます。最近はRuby on RailsでWebサービスを作っています。