これまで、コンポーネントを横に配置するのは面倒でした。インラインを使ったりクリアしないといけなかったり。
CSS3ではたった数行でコンポーネントの配置を変えられます。
フレックスです。ナビゲーション(メニュー、パンくずリスト)などかんたんに作れます。
まずは、フレックスのシンプルな使い方から説明します。
フレックスは、Webアプリなど高度なコンポーネント配置がかんたんにできるようになりました。
2018/12現在、ほぼすべてのブラウザで対応しているので心配ありません。わかりやすく手順を追って解説します。
display: flex フレックスを使う
.container {
display: flex;
}
CSS3でdisplayプロパティに新しい機能が追加されました。フレックスもそのひとつです。displayプロパティは
- block
- inline
- inline-block
- table
- etc...
でおなじみのやつです。かんたんなサンプルを使って動かします。まずはHTMLから。
ソースコードサンプルのボックスにタップやマウスを合わせると、右上にコピーボタンが出ます。
慣れないうちは、とりあえずコピー&ペーストで、自分で動かすところから始めると良いです。
<div class="sample">
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>
</div>
このまま実行しても分かりづらいので、CSSも加えます。
.sample .container .box {
background: rgba(255, 144, 130, 0.7);
color: #fff;
width: 30px;
margin: 3px;
padding: 0 3px;
text-align: center;
}
タテに数字のボックスが並びました。display: block(<div>)なのであたりまえですね?
これをヨコ並びにします。CSSにクラスを追加します。
.sample .flex {
display: flex;
}
"display: flex"を追加しました。これをHTMLのクラスに追加します。
<div class="sample">
<div class="container flex"><!-- add flex -->
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>
</div>
ヨコに並びました。かんたんですね? floatプロパティでやっていたことがバカみたいに思えます。
フレックスは、"display: flex"を書いた要素(htmlのタブ)を『コンテナ』、すぐ下の子要素を『アイテム』と言います。
コンテナはアイテムの箱です。コンテナは並び替えの対象になりません。
アイテムは並べられる要素です。コンテナのすぐ下の子要素が自動的にアイテムになります。
アイテムになるのは子要素だけです。子のさらに子(孫以下)の階層はアイテムになりません。
<div>, <li>, <ol>など、もともとコンテンツの親の役割をする要素にコンテナを指定するのが一般的です。
display: inline-flex コンテナをインライン化する
flexを使うと、コンテナはブロックになります。ブロックはタテ方向にコンテンツが並びます。
<div>とかそうですね?
逆に<a>など、ヨコに並ぶものをインラインと言います。インラインはヨコに並ぶので文章の中に差し込めます。
ブロックは左右のコンテンツに影響を受けないので、デフォルトは横幅いっぱいに広がります。
(左右にコンテンツを置けないように『ブロック』します。)
一方、インラインは左右のコンテンツに差し込むため、デフォルトの横幅は中のコンテンツのサイズに影響されます。
(中身の長さによって横幅が変わります。)
ここで
flexをdisplayで指定したらどうやってインライン化するんだ?
という疑問が聞こえてきそうですが、フレックスにはインラインが用意されています。
.container {
display: inline-flex;
}
コンテナがインラインになり、アイテムのdisplayプロパティはもとのままです。
(flexを指定してもアイテムのdisplayプロパティは変わりません。)
じっさいにサンプルで見てみましょう。
CSSにクラスを追加します。
.sample .inline-flex {
display: inline-flex;
}
<div class="sample">
<div class="container inline-flex">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>
<div class="container inline-flex">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>
</div>
HTML結果です。合わせてflexも表示します。
flexのとき、アイテムはヨコにコンテナはタテに並びました。コンテナはブロックだということが分かります。
inline-flexのとき、コンテナもアイテムもヨコに並びました。コンテナがインライン化されます。
フレックスのしくみ
displayプロパティで"flex", "inline-flex"を指定したとき、コンテナとアイテムを作ることは説明しました。
フレックスは、コンテナとアイテムを作ると次のようなしくみになります。
フレックスは配置などいろいろな変更ができるので、複雑なしくみをもっているように感じますが、じっさいはメイン軸とクロス軸をもち、それぞれstart, endを持っているだけ。
(アイテム内の細かいしくみがありますが、ここでは省略。)
このシンプルなしくみで、もっているデータの組み合わせで複雑な動きをコントロールします。
ここでは、フレックスを使うことを目的にしているので、細かい設定や変更については説明しません。
フレックスの入れ子
フレックスは入れ子にできます。入れ子は
フレックスのアイテムにフレックスのコンテナを指定して、フレックスの中にフレックスを作る
こと。
さっき、フレックスのインライン化のことろで、『アイテムのdisplayはそのまま』と言いました。
これがフレックスの入れ子ができる理由です。フレックスのアイテムのdisplayプロパティは自由に指定できます。もちろん、"flex", "inline-flex"も使えます。
サンプルを見ていきましょう。
まずはHTMLから。
<div class="sample">
<div class="container flex">
<div class="box">1</div>
<div class="container flex">
<div class="box">1-1</div>
<div class="box">1-2</div>
<div class="box">1-3</div>
</div>
<div class="box">2</div>
<div class="container flex">
<div class="box">2-1</div>
<div class="box">2-2</div>
<div class="box">2-3</div>
</div>
<div class="box">3</div>
</div>
</div>
CSSはいままでのをそのまま使います。
比較のために、入れ子じゃないときはこんな感じです。
flexの中にinline-flex、inline-flexの中にflexを入れられます。また、入れ子は何層でもできます。
入れ子は何層でも入れられますが、Webページの表示速度に影響します。
『できても使えるかどうかは実装次第』ということに注意。
まとめ
フレックスを使ってコンテンツをかんたんに並べる方法をご紹介しました。
フレックスのすごいところはこれだけではありません。まだまだほかにもあります。
ただ、今回の目的が『フレックスを使おう』なので、細かいことは省略しました。
ここで説明すると長くなるのでとりあえずここまでにします。