CSS3のフレックスは、コンポーネントの配置を変える便利な機能です。
アイテムのサイズや余白サイズが自動で配分されるので、アイテムサイズと余白の操作はとても重要です。
今回はアイテムサイズの操作方法です。いま、ほぼすべてのブラウザで対応しているので心配ありません。わかりやすく手順を追って説明します。
flex アイテムの拡大・縮小・サイズをまとめて指定(ショートハンド)
.items {
flex: [ <flex-grow> <flex-shrink>? || <flex-basis> ] | none;
}
初期値 | 0 1 auto |
flex-grow | アイテムの自動拡大のあり/なし |
flex-shrink | アイテムの自動縮小のあり/なし |
flex-basis | ヨコ並びの場合アイテムのwidth。 タテ並びの場合アイテムのheight。 |
[] | グループ。囲まれた範囲内が1つの書式。 |
? | 直前のものは省略可。 |
|| | 半角スペース区切り。順不同。1つ指定可。 |
| | または。or |
例
.items {
// shrinkを省略
flex: 1 auto; // growとshrinkは1
}
.items {
// basisを省略
flex: 1 1; // 1 1 autoと同じ
}
.items {
flex: auto 0 1; // 0 1 autoと同じ
}
.items {
flex: none; // 0 0 autoと同じ
}
フレックスは、コンテナ内の余白部分をコントロールして、各アイテムに割り当てます。
これでアイテムのサイズ(width, heightプロパティ)とはちがうサイズになります。それをコントロールするのがflexプロパティ。
またフレックスは、コンテナ内のサイズがアイテムの合計サイズに足りないときアイテムサイズを縮小します。flexプロパティはそれもコントロールします。
- 余白を割り当てたときアイテムサイズを拡大するか?
- コンテナ内のサイズが足りないときアイテムサイズを縮小するか?
- アイテムサイズの基準をどうするか?
を指定します。
動きをイメージしやすいように、サンプルをひとつずつ見ていきましょう。
アイテムに指定します。
flex-grow アイテムの拡大
0 | 拡大しない。デフォルト |
1 | 拡大する |
アイテムの拡大を指定します。サンプルコードを実行していきます。
フレックスの並びがタテとヨコで結果がちがうので、
- ヨコ並びの拡大
- タテ並びの拡大
の2パターンでHTMLの結果を見ていきます。
ヨコ並びの拡大
まずはCSSです。ボックスの見栄えを作ってフレックスのクラスを用意します。
.sample .container .box {
background: rgba(255, 144, 130, 0.7);
color: #fff;
margin: 3px;
padding: 0 3px;
text-align: center;
}
.sample .flex{
display: flex;
}
.sample .grow {
flex: 1 0 auto;
}
次にHTMLです。
<div class="sample">
<div class="container flex">
<div class="box grow">1</div>
<div class="box">2</div>
<div class="box grow">3</div>
</div>
</div>
ボックスの1と3は拡大できて2は拡大できないようにします。
(拡大するものとしないものを比べるために混ぜました。)
アイテムにgrowクラスを追加して拡大します。ついでに拡大なしも表示して比較します。
拡大あり | アイテムに"flex: 1 0 auto"追加 |
拡大なし | 未指定("flex: 0 1 auto"と同じ) |
アイテムのwidthのサイズが大きくなりました。でも、アイテムのheightに変化がないことに注目です。
- 並びがヨコのとき、ヨコのサイズ(width)が拡大。
- アイテムの拡大分のサイズは均等に配分される。(個々のアイテムのサイズは関係ない)
- 並びがヨコのとき、タテのサイズ(height)は変わらない。
タテ並びの拡大
CSSに新たにクラスを追加します。
.sample .direction-column {
flex-direction: column;
}
HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column">
<div class="box grow">1</div>
<div class="box">2</div>
<div class="box grow">3</div>
</div>
</div>
合わせて拡大なしの結果も表示します。
???変わりません。これはコンテナのheightのせい。
並びがヨコのとき、コンテナのwidthはWebページのwidth指定で決まっていました。
でもheightは決まっていません。スクロールするから。このまま拡大すると無限に拡大されちゃいます。
それじゃあダメなので、フレックスでは、コンテナのwidthやheightが無限に広がるときは拡大しないようになっています。
CSSに新たにクラスを追加して修正します。
.sample .height {
height: 200px;
}
HTMLのコンテナのクラスにheightを追加します。
<div class="sample">
<div class="container flex direction-column height">
<div class="box grow">1</div>
<div class="box">2</div>
<div class="box grow">3</div>
</div>
</div>
アイテムのheightのサイズが大きくなりました。でも、アイテムのwidthが変わってないことに注目です。
- 並びがタテのとき、タテのサイズ(height)が拡大。
- アイテムの拡大分のサイズは均等に配分される。(個々のアイテムのサイズは関係ない)
- 並びがタテのとき、ヨコのサイズ(widht)は変わらない。
コンテナのサイズに上限がないときは、拡大指定されても拡大しない。
ヨコ並び | widthが無限だと拡大しない。heightは関係ない。 |
タテ並び | heightが無限だと拡大しない。widthは関係ない。 |
flex-shrink アイテムの縮小
0 | 縮小しない |
1 | 縮小する。デフォルト |
アイテムの縮小を指定します。『縮小する』がデフォルトなのは、1行につめて表示するプロパティがあるから。(flex-wrap)
サンプルコードを実行していきます。フレックスの並びがタテとヨコで結果がちがうので、
- ヨコ並びの縮小
- タテ並びの縮小
の2パターンでHTMLの結果を見ていきます。
ヨコ並びの縮小
CSSに新たにクラスを追加します。
.sample .width-30px {
width: 30px;
}
.sample .width-80px {
width: 80px;
}
.sample .no-shrink {
flex: none;
}
.sample .color-container {
background: rgba(130, 255, 144, 0.5);
}
アイテムのno-shrinkクラスには、"flex: none"をつけて縮小しません。
次にHTMLです。
<div class="sample">
<div class="container flex width-80px color-container">
<div class="box width-30px">1</div>
<div class="box width-30px no-shrink">2</div>
<div class="box width-30px">3</div>
</div>
/div>
ボックスの1と3は縮小できて2は縮小できないようにします。
(縮小するものとしないものを比べるために混ぜました。)
コンテナのwidth(70px)をアイテムのwidthの合計(90px)より小さくして、分かりやすいようにコンテナに色をつけます。
コンテナのwidth < アイテムのwidthの合計
でないと縮小しません。
1と3のアイテムのwidthが小さくなりました。でも、アイテムのheightが変わらないことに注目です。
そして、縮小しないときコンテナからはみ出しすことも注目です。
- 並びがヨコのとき、ヨコのサイズ(width)が縮小。
- アイテムの縮小分のサイズは均等に配分される。(個々のアイテムのサイズは関係ない)
- 並びがヨコのとき、タテのサイズ(height)は変わらない。
タテ並びの縮小
CSSに新たにクラスを追加します。
.sample .height-70px {
height: 70px;
}
HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column height-70px color-container">
<div class="box">1</div>
<div class="box no-shrink">2</div>
<div class="box">3</div>
</div>
</div>
ヨコ並びと同じように、コンテナのheight(70px)をアイテムのheightの合計(27 * 3px)より小さくして、分かりやすいようにコンテナに色をつけました。
???縮小されません。これは、アイテムのheightを指定していないので、高さは中身の番号の高さに合わせて設定されます。
言いかえると、中身を表示するためにはこれ以上小さくできません。このようにアイテムの縮小には限界があります。その限界は中身の表示できるサイズです。
CSSに新たにクラスを追加して修正します。
.sample .height-40px {
height: 40px;
}
HTMLは、アイテムのクラスに"height-40px"を追加します。
<div class="sample">
<div class="container flex direction-column height-70px color-container">
<div class="box height-40px">1</div>
<div class="box height-40px no-shrink">2</div>
<div class="box height-40px">3</div>
</div>
</div>
1と3のアイテムのheightが小さくなりました。でも、コンテナに収めるほど縮小できなかったのではみ出しています。
縮小では、まずコンテナのサイズいっぱいに収めるように小さくなります。
(ヨコの並びの結果。できる限り小さくするわけではありません。)
そして、縮小に限界がきたとき、コンテナに収められないときはあきらめます。
また、アイテムのwidthが変わらないことに注目です。
- 並びがタテのとき、タテのサイズ(height)が縮小。
- アイテムの縮小分のサイズは均等に配分される。(個々のアイテムのサイズは関係ない)
- 並びがタテのとき、ヨコのサイズ(width)は変わらない。
- 縮小はコンテナいっぱいに収めようとする。
- 縮小には限界がありコンテナに収まらないとはみ出す。
- アイテムの中身のサイズより小さくできない。
並びヨコ | [ コンテナのwidth < アイテムのwidthの合計値 ] でないと縮小しない。 heightは関係ない。 |
並びタテ | [ コンテナのheight < アイテムのheightの合計値 ] でないと縮小しない。 widthは関係ない。 |
flex-basis アイテムのサイズ指定
auto | アイテムのwidth(height)プロパティのサイズを継承する。 width(height)がautoのとき、contentと同じ効果がある。 |
content | アイテムの中身のサイズに合わせる。 新しい値なので古いブラウザでは使えないこともある。 |
<width> | width(height)プロパティと同じ指定方法。 |
- ヨコ並びのとき、アイテムのwidthのサイズを指定する。
- タテ並びのとき、アイテムのheightのサイズを指定する。
例
.items {
flex: 0 1 content;
}
.items {
// flex: 0 1 contentと同じ。中身のサイズに合わせる
width: auto;
flex: 0 1 auto;
}
.items {
flex: 0 1 50px; // ピクセル指定
}
.items {
flex: 0 1 50%; // コンテナのサイズの50%
}
.items {
flex: 0 1 5em; // アイテムのフォントサイズの5倍
}
アイテムは拡大したり縮小します。そのため基準のサイズが必要です。flex-basisはその基準を指定します。
デフォルトは、アイテムのwidth(height)プロパティのサイズです。並びの方向(タテ・ヨコ)で、flex-basisの値がwidthとheightのどちらかを指します。
またflex-basisの値は、width(height)プロパティよりも優先します。
サンプルコードを実行しましょう。まずはCSSです。
CSSに新しいクラスを追加します。
.sample .basis {
flex: 0 0 60px;
}
フレックスの並びがタテとヨコで結果がちがうので、
- ヨコ並びのサイズ指定(width)
- タテ並びのサイズ指定(height)
の2パターンでHTMLの結果を見ていきます。
ヨコ並びのサイズ
HTMLです。
<div class="sample flex">
<div class="container">
<div class="box basis">1</div>
<div class="box">2</div>
<div class="box basis">3</div>
</div>
</div>
ボックスの1と3はflex-basisでサイズを指定します。2はサイズ指定しません。
(比べるために混ぜました。)
アイテムのクラス(basis)に60pxのサイズを指定します。ついでにサイズ指定なしも表示します。
サイズ指定あり | アイテムに"flex: 0 0 60px"追加 |
サイズ指定なし | アイテムにflex指定なし(デフォルトのflex: 0 1 auto) |
1と3のサイズ(width)が変わりました。でも、heightは変わらないことに注目です。
- 並びがヨコのとき、ヨコのサイズがflex-basisで指定されたサイズになる。(widthは無効)
- サイズはアイテムごとに指定可能。
- 並びがヨコのとき、タテのサイズ(height)は変わらない。
タテ並びのサイズ
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample flex">
<div class="container flex direction-column">
<div class="box basis">1</div>
<div class="box">2</div>
<div class="box basis">3</div>
</div>
</div>
- 並びがタテのとき、タテのサイズが flex-basis 指定されたサイズになる。(heightは無効)
- サイズはアイテムごとに指定可能。
- 並びがタテのとき、ヨコのサイズ(width)は変わらない。
- ヨコ並びのとき、flex-basisはアイテムのwidthプロパティより優先する。(widthの値は変えない)
- タテ並びのとき、flex-basisはアイテムのheightプロパティより優先する。(heightの値は変えない)
拡大・縮小のリミット指定
フレックスのプロパティは、拡大・縮小の有無、基準サイズは指定できますが、拡大の上限、縮小の下限は指定できません。
でも、別のプロパティ(max-***, min-***)でコントロールできます。
width, heightプロパティは、条件によってflex-basisを優先しますが、max-***, min-***はフレックスを使っても効果があります。
ヨコ並びの拡大上限 | max-width |
タテ並びの拡大上限 | max-height |
ヨコ並びの縮小下限 | min-width |
タテ並びの縮小下限 | min-height |
まとめ
フレックスを使って、アイテムの拡大・縮小、基準サイズの指定方法をご紹介しました。
フレックスは、余白を自動的に配分したり、アイテムの拡大・縮小があったりしてwidth, heightどおりにサイズが固定されることはあまりありません。
アイテムのサイズをコントロールする基準はflexプロパティです。これが分かっていないと自動的なサイズ変更に振り回されるので注意しましょう。
flexプロパティはショートハンドです。3つのプロパティをまとめて指定します。しかし、個別のプロパティは公式ドキュメントでも推奨していません。
将来削除される可能性大です。とりあえず紹介しましたが覚えなくていいです。
.items {
// flex: 0 1 auto; と同じ
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
フレックスのすごいところはこれだけではありません。まだまだほかにもあります。
ここで説明すると長くなるのでとりあえずここまでにします。