今や横並びの標準といえばFlexboxという時代ですが、そんなFlexboxでも意外と知られてないであろう使い方をご紹介します。
記述量を減らしたり、動的なサイトで重宝したり、リキッドレイアウトにも対応できちゃいます。
IEを含め主要ブラウザに対応してます。
#1. 一つが固定幅もう一つが残りの幅いっぱいの横並びボタン
こんな感じのものを一度の横幅指定だけで作る
html
<ul class="list">
<li class="item-short"><a href="">リスト1</a></li>
<li><a href="">リスト2</a></li>
</ul>
固定幅にしたい方に固有のclassを与えてやりましょう。
##css
.list {
display: flex;
}
.list li {
border: 1px solid #ccc;
flex: 1 0 0%;
box-sizing: border-box;
text-align: center;
}
.list li a {
display: block;
padding: .5em;
}
.list li.item-short {
width: 30%;
/* flexで書き換えるとこうなる */
flex: 0 0 30%;
/* ただし、IEでは11でもこの指定は効かないことがあるためmax-widthとセット */
max-width: 30%;
}
.list li:not(:last-child) {
margin-right: 3%;
}
ポイントはli
にあたっているプロパティflex
です。
ご存知の方は多いかと思いますがこれはflex-grow
, flex-shrink
, flex-basis
のショートハンドで、今回関わってくるのはflex-grow
とflex-basis
です。
flex-grow
はflexアイテムの横幅を計算してflexコンテナに対して余白がある場合その余白を埋めるかどうかの指定です。
初期値は0で整数値を指定するとその比率で余ったスペースを指定されたflexアイテムで配分するというものです。
flex-basis
は横幅の指定です。width
と同じです。初期値はautoです。
でもflex: 1 0 0%;
っておかしくない?flex: 1 0 auto;
ではダメなの?
と思った方、当然です。
これもまたIEのバグ対策です。
autoだと値が正常に計算されないのでここは数値で指定する必要があります。
ただこの数値、本当に何でも良いです(笑)
0%でも100%でも変わらないので好きな数値を指定してください。
数値が指定されていることが重要みたいです。
まとめると、flexコンテナの30%をli.item-short
が占めて、残りの70%からmargin
を引いた分が、classの付いていないli
の横幅になるというレイアウトです。
値の指定が一つだけで良いので計算も楽になるかと思います。
flex
プロパティについて詳しくは仕様書へ
#2. 要素数が可変な横並びのボタンを均等幅に
Flexboxを使えば一行あたりのflexアイテムの数ごとにclassを用意せずとも、flexアイテムの数に関わらず均等幅になるレイアウトが可能です。
##html
<ul class="flex-list">
<li><a href="">リスト1</a></li>
<li><a href="">リスト2</a></li>
<li><a href="">リスト3</a></li>
</ul>
はい、普通のリストです。
##CSS
.flex-list {
display: flex;
}
.flex-list li {
flex: 1 0 0%;
border: 1px solid #ccc;
text-align: center;
box-sizing: border-box;
}
.flex-list li:not(:last-child) {
margin-right: 1%;
}
.flex-list li a {
display: block;
padding: .5em;
}
flex
プロパティ、また出ましたね。
今回は上の応用的な考え方です。
flexアイテムの全てのflex-grow
を1にして比率を均等にすることでli
内にどれだけテキストが入ろうが、 またli
がいくつになろうがそれぞれ均等幅にすることが可能です。
コードもこれだけすっきりします。
#3. さらに横並びのボタンの一部だけテキストが複数行になった場合に縦中央揃え
こんなレイアウト
特に動的なサイトの場合、line-height
やhegiht
を固定にできないため今まではjsのプラグインで解決している方が多かったかと思いますがFlexboxを使えばjsも要りません。
##html
<ul class="flex-list">
<li><a href="">リスト1</a></li>
<li><a href="">リスト2<br>リスト2リスト2</a></li>
<li><a href="">リスト3</a></li>
</ul>
##css
.flex-list {
display: flex;
}
.flex-list li {
flex: 1 0 0%;
border: 1px solid #ccc;
text-align: center;
box-sizing: border-box;
}
.flex-list li:not(:last-child) {
margin-right: 1%;
}
.flex-list li a {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
box-sizing: border-box;
padding: .5em;
}
基本的にheight
の%指定はその親要素の値が未指定、もしくは%指定だと効きませんでしたが、a
自体をflexコンテナにしてしまえばheight: 100%;
が効くようになります。
そしてalign-items: center;
で縦の中央寄せを指定しています。
#まとめ
いかがでしたか?
少しでも皆さんのコーディングライフの助けになれば幸いです。
まだまだ奥が深そうなFlexbox。
もっと不思議な使い方もあるかもしれないので今後も色々試していきたいと思います。
また、既にそういったのをご存知の方がいれば是非教えてください。