こんにちは。
強いて言うならエビよりタコ派のご飯固めです。

単刀直入ですが、
今回はCSS ボックスモデルFlex boxについてお話しします。

CSSボックスモデルとは

すべての要素はボックスという領域を持っていて、これをボックスモデルと呼びます。

下の画像はボックスモデルのイメージ図です。
外側から、「margin(マージン)」「border(ボーダー)」「padding(パディング)」「contents(コンテンツ)」という4つの領域が存在します。

contents(要素)、padding、border、marginの領域を表したcssボックスモデルの図

4つの領域についても、さっくりお話ししましょう。

contents

contentsは要素そのものことで、テキストが表示されるメインの領域です。

padding

Padding(パディング)は「詰め物」という意味の単語で、
その訳の通り、要素の詰め物。要素の内側につく余白のことです。
人間が要素だとすると、脂肪といったところでしょうか。

最近はめっきり運動不足で私のpaddingも増えてきた気がします。

border

border(ボーダー)はボーダーラインという言葉で使うことがあると思いますが、
要素の外側につける枠線のことです。
枠線でもスペースが作られているのは、太さを変えられるからですね。

margin

margin(マージン)は「余白」という意味の単語で、paddingの逆、要素の外側の余白のことです。隣にある要素との間にスキマを作ります。

よく「差額」や「手数料」という意味で「マージン」という言葉を聞いたり使うと思いますが、これも同じ「margin」から来ています。

実際に確認してみよう

タテ200px、ヨコ200pxの要素を用意します。

webブラウザにタテ200px、ヨコ200pxの要素を用意した図

このピンクの要素に

  • padding-leftを30px
  • borderを5px
  • marginを上下に20px、左右に40px

をつけます。

webブラウザにタテ200px、ヨコ200pxの要素を用意した図にpadding-leftを30px、borderを5px、marginを上下に20px、左右に40pxつけた図

marginがついたので位置が少し下がり、右に移動しました。
要素もpaddingを加えたことによって若干ですが横長になりましたね。

上画面の要素に対してのCSSボックスモデルが下の画像です。

webブラウザの図をcssボックスモデルで表した図

緑色のPaddingの範囲の左側に30と書いてありますね。
設定したpadding-leftを30pxがきちんと反映されています。
他の領域も反映されています。



余白を自分で調節してくれる優れものを紹介します。

Flex boxとは?

Flex box(フレックスボックス)
正式名称はFlexible Box Layout Moduleといいます。
フレキシブルには柔軟という意味があり、その通りに、CSSで柔軟にレイアウトが組めるボックスのことを指します。

要素を横並びで配置したいときなどはfloat等を使うのが一般的でしたが、最近ではFlexboxを使って要素を配置する方法も使われています。

“細かい場所を自動で調整してくれたり、簡単にレイアウトを作成することができる

という点で使用される頻度が高いです。

基本を押さえよう

Flex boxは

  • コンテナ(親要素)
  • アイテム(子要素)

の2つから構成されています。

Flex box使用前の準備

まず初めに設定するHTMLとCSSはこんな感じ

<div class="container">
    <div class="item">アイテム1</div>
    <div class="item">アイテム2</div>
    <div class="item">アイテム3</div>
    <div class="item">アイテム4</div>
</div>
.item{
    background: pink;
}

親要素にcontainer、子要素にitemのクラスをつけ、アイテム1~というテキストを挿入しました。

(最初「アイテム」ではなく「子要素」ってテキストを入れてたんですが、明らかにダサかったのでやめました)(すごくどうでもいい)

Flex boxを適用させよう

Flexboxレイアウトを使用する場合は、
CSSでコンテナ(親要素)にdisplay:flexと記述します。

.container{
    display:flex;	
}
アイテム1から4までを横並びに並べた図

Flexboxでレイアウトをする時には、コンテナとアイテムにそれぞれプロパティを指定していきます。

コンテナに指定できるプロパティ

コンテナに対して指定できるプロパティは下の表に書いてある通りです。

1.flex-direction
……アイテムの並び順の指定ができる

2.flex-wrap
……アイテムの折り返し(改行)を指定

3.flex-flow
……(1.)アイテムの並び順と(2.)アイテムの改行を同時に指定できる

4.justify-content
……アイテムの水平方向(横並び)の位置を揃えることができる

5.align-items
……アイテムの垂直方向(縦方向)の位置を揃えることができる

6.align-content
……複数行にした場合に位置を揃えることができる

はい、ややこし〜。もうちょっと文章だけじゃ何言ってるか分かんないですね。
私も何言ってるか理解できないのでここからは図解も交えて頑張って説明します。

1.flex-direction

flex-directionはアイテムの並び順の指定ができます。
入れられる値は以下の通り。

・row(初期値)
……アイテムを左から右に配置する

・row-reverse
……アイテムを右から左に配置する(右寄せになる)

・column
……アイテムを垂直に上から下へ配置

・colmn-reverse
……アイテムを垂直に下から上へ配置

CSSの記述例↓

.container{
    display: flex;
    flex-direction: 値;
}

row(初期値)

rowはアイテムを左から右に配置します。
初期値なので、何も指定していない時と配置は変わりません。

アイテム1から4のcssへrowを記述した図

row-reverse

row-reverseはrowの逆で、アイテムの場所が右から左に配置されます。
始まりが右なので、アイテム全体が右寄せになります。

アイテム1から4のcssへrow-reverseを記述した図

colmn

colmnはアイテムを垂直に上から下へ配置できます。

アイテム1から4のcssへcolmnを記述した図

colmn-reverse

これもリバースと付いているのでcolmnの逆で下から上へ垂直にアイテムが配置されています。全体の配置が下寄りになることはありません。

アイテム1から4のcssへcolmn-reverseを記述した図

2.flex-wrap

・nowrap(初期値)
……アイテムを横一列に配置

・wrap
……アイテムを上から下へ複数行にわたって配置

・wrap-reverse
……アイテムを(左)下から上へ複数行にわたって配置

CSS記述例↓

.container{
    display: flex;
    flex-wrap: 値;
}

nowrap

nowrapはアイテムを横一列に配置できるコードです。
アイテムの形が変わっているのは本来2段に分割される大きさのアイテムを無理に一列に収めているためです。

アイテム1から8のcssへnowrapを記述した図

wrap

wrapはアイテムを改行し、複数行に配置するものです。
下の画像では4つで1段となっていますが、ブラウザのサイズとアイテムのサイズを鑑みて勝手に改行してくれます。

アイテム1から8のcssへwrapを記述した図

wrap-reverse

wrap-reverseはwrapと並びが逆になっており、一番左下のアイテムから右上のアイテムへ下の矢じるしの順番で配置されます。

アイテム1から8のcssへwrap-reverseを記述した図

3.flex-flow

flex-flowは「flex-direction」と「flex-wrap」が同時に指定できます。
2つ書く手間が省けるので便利なコードです。

同時に指定できる、というコードなので画像は省略します。
※気になる方は「flex-direction」「flex-wrap」を参照してください。

CSS記述例↓

.container{
    display: flex;
    flex-flow: flex-directionの値 flex-wrapの値;
}

4.justify-content

・flex-start(初期値)
……アイテムを左揃えに配置します

・flex-end
……アイテムを右揃えに配置します

・center
……アイテムを左右中央揃えで配置します

・space-between
……両端のアイテムは端に配置し、間に入っているアイテムは均等に間隔を空けて配置されます。

・space-around
……両端のアイテムも含めて、均等な間隔を空けて配置

.container{
    display: flex;
    justify-content: 値;
}

flex-start(初期値)

flex-startはアイテムを右揃えで配置します。

アイテム1から4のcssへflex-startを記述した図

flex-end

flex-endはアイテムを左揃えで配置します。
アイテムの並び順は変わりません。

アイテム1から4のcssへflex-endを記述した図

center

centerはその名の通り、アイテムが左右中央に集まります。
上下中央の幅は指定できません。

密ですね。

アイテム1から3のcssへcenterを記述した図

space-between

space-betweenは両端のアイテムは余白が付かず、間に挟まれているアイテムが均等に間隔を空け配置されます。間隔はブラウザのサイズによって自動で適用されます。

ソーシャルディスタンスですね。

アイテム1から3のcssへspace-betweenを記述した図

space-around

space-aroundは、space-betweenとは違い、両端のアイテムにも余白が付いており、全ての余白が均等になっています。間隔はブラウザのサイズによって自動で適用されます。

アイテム1から3のcssへspace-aroundを記述した図

5.align-items

・stretch(初期値)
……アイテムを上下の余白を埋めるよう変形させて配置

・flex-start
……アイテムを上揃えで配置

・center
……アイテムを上下中央揃えで配置

・flex-end
……アイテムを下揃えで配置

・baseline
……アイテムをベースライン(文字列の下線)に合わせて配置

CSS記述例↓

.container{
    display: flex;
    align-items: 値;
}

(今回は、コンテナの大きさによって配置が大きく変わるので、
コンテナの大きさを300pxで指定しました。)

stretch(初期値)

上下の余白を埋めるように配置されます。今回はコンテナの高さを300pxに設定しているので、タテが300pxになっています。

アイテム1から6のcssへstretchを記述した図

flex-start

flex-startはアイテムを上揃えにします。

アイテム1から6のcssへflex-startを記述した図

center

centerは名前の通り、上下中央揃えができます。
下の画像の場合、コンテナサイズが300pxなので、
アイテムの中心が150pxに重なるように並んでいます。

アイテム1から6のcssへcenterを記述した図

flex-end

flex-endはコンテナのサイズに合わせてアイテムを下揃えにできるものです。

アイテム1から6のcssへflex-endを記述した図

baseline

baselineはアイテム内のテキストのベースライン(文字の底辺部、下画像でいう青の破線)の位置を揃えて配置ができるものです。

それぞれのアイテムに一文字入ったアイテム1から4のcssへbaselineを記述した図

6.aline-content

・stretch(初期値)
……アイテムで余白を埋めるように配置

・flex-start
……複数行のアイテムを上揃えで配置

・flex-end
……複数行のアイテムを下揃えで配置

・center
……複数行のアイテムを上下中央揃えで配置

・space-between
……一番上の行と一番下の行のアイテムは余白なしで配置し、間に入っているアイテムは均等に間隔を空けて配置される

・space-around
……上下の空白がすべて均等な間隔で配置される

CSS 記述例↓

.container{
    display: flex;
    align-content: 値;
}

stretch(初期値)

aline-itemsの stretchの時と同じように、複数行でコンテナの縦いっぱいに広がり、余白を埋めます。

アイテム1から8のcssへstretchを記述した図

flex-start

複数行のアイテム全体を上揃えにします。

アイテム1から8のcssへflex-startを記述した図

center

複数行のアイテム全体を上下中央揃えにします。

アイテム1から8のcssへcenterを記述した図

flex-end

複数行のアイテム全体を下揃えにします。

アイテム1から8のcssへflex-endを記述した図

space-between

一番上の行と一番下の行のアイテムは余白なしで配置し、間に入っているアイテムは均等に間隔を空けて配置される

アイテム1から8のcssへspace-betweenを記述した図

space-around

上下の余白、と中間のアイテムとの余白がすべて均等な間隔で配置されます。

アイテム1から8のcssへspace-aroundを記述した図

子要素に指定できるプロパティ

・order
……アイテムの並び順を指定

・flex-grow
……コンテナのサイズに合わせてアイテムのサイズ(拡張率)を指定

・flex-shrink
……コンテナのサイズに合わせてアイテムのサイズ(縮小率)を指定

・flex-basis
……アイテムの基本幅を指定

・flex
……flex-grow、flex-shrink、flex-basisを同時に指定

order

orderはアイテムの並び順を指定できます。
HTMLでは1枚目に入れた画像でも、CSSで順番を変更できます。

HTMLで各アイテムに個別でクラスを与えたあとに、
CSSで{order: [○];}と記述し、○の部分に変更したい順番の数字を入れます。
2番目にしたい場合は{order: 2;}です。

CSS記述例↓

.container{
    display: flex;
}

.item01 {order: 4;} /*4番目になる*/
.item02 {order: 1;} /*1番目になる*/
.item03 {order: 2;} /*2番目になる*/
.item04 {order: 3;} /*3番目になる*/

上のように記述すると、下画像のような並びになります。

アイテム1から4のcssへorderを記述て配置を操作した図

flex-grow

アイテムの大きさを指定するプロパティです。
この大きさを指定する時に使われる数字(flex-growの後ろに書かれた数字)は、コンテナの横幅を100%とした際の割合です。
つまり、flex-growは相対値なので、同じ「1」を指定してもコンテナサイズでアイテムの大きさは変わります。
元のサイズより大きくすることしかできません。

下のCSSで言うと、
コンテナ幅が100pxの時、item1、2は20px。item3は60pxとなります。
コンテナ幅を200pxにした場合、flex-growが同じ値でもitem1、2は40px、item3は120pxと変化するのです。

CSS記述例↓

.container{
    display: flex;
}

.item01 {flex-grow:1;}
.item02 {flex-grow:1;}
.item03 {flex-grow:3;}
アイテム1から3のcssへflex-growを記述て大きさを操作した図

flex-shrink

flex-shrinkはflex-growとは逆の特性があり、アイテムの小ささを指定することができます。指定する数字が大きいほど小さくなります。

CSS記述例↓

.container{
    display: flex;
}

.item01 {flex-shrink:1;}
.item02 {flex-shrink:5;}
.item03 {flex-shrink:1;}
.item04 {flex-shrink:1;}
.item05 {flex-shrink:1;}
.item06 {flex-shrink:1;}
アイテム1から6のcssへflex-growを記述て小ささを操作した図

flex-basis

flex-basisはアイテムの基本幅を指定するコードです。
下のコードは(赤裸々に言うと)何も考えずに設定したので、全部合わせると125%になるという少し頭が悪い感じになっていますが、100%に収める必要はありません。

ですが、要素を横幅ぴったりに並べたいのならば、100%の中で調整する方がコードを見返す際にも分かりやすいかと思います。
(結果的にちょっと悪い例になっちゃいました……。)

CSS記述例↓

.container{
    display: flex;
}

.item01 {flex-basis:25%;}
.item02 {flex-basis:40%;}
.item03 {flex-basis:50%;}
.item04 {flex-basis:10%;}
アイテム1から4のcssへflex-basisを記述て基本幅を操作した図

flex

flexはflex-grow、flex-shrink、flex-basisを同時に指定することができるプロパティです。3つとも指定したい場合は1つずつ指定するのではなく、flexで指定するのが良いでしょう。

記述する際は左から[flex-growの値] [flex-shrinkの値] [flex-basisの値]と記述します。

CSS記述例↓

.container{
    display: flex;
}

.item01 {flex: 2 0 70%;} /*grow shrink basisの順*/
.item02 {flex: 1 0 10%;}
.item03 {flex: 1 0 20%;}

まとめ

今回はいかがだったでしょうか。
CSSボックスモデルとFlex boxについてでした。

ずっと使用例とプレビュー画面とあとはこれとこれとこれと……という調子で、いつものくどい文章を挟む余地はありませんでした。残念です。

レイアウトの幅が広い分、考えることが多かったり最初はなかなか使いこなすのが難しいと言われているFlex boxではありますが、レスポンシブ対応に向いているコードだと思いますので、使いこなせれば強みになると思います。

ここまで読んでいただきありがとうございました!

作者情報

ご飯が固いと大喜びのIT初心者。年齢に似合わぬ細すぎて伝わらないネタを言うのが得意です。
今はIllustratorとPhotoshop、HTML・CSSを勉強中。