CSS3のFlexでは、ほんの数行でコンポーネントの配置を変えられるようになりました。
また配置だけでなく関係する細かい設定もたくさんあります。
今回はコンテンツの行詰め・折り返しの方法です。
2018/12現在、ほぼすべてのブラウザに対応しています。わかりやすく順を追って解説します。
- flex-wrap 1行に詰めたり折り返しを指定する
- nowrap 1行に詰める(デフォルト)
- 左に向かって1行に詰める
- 右に向かって1行に詰める
- 上に向かって1行に詰める
- 下に向かって1行に詰める
- wrap 複数行で折り返す
- 左上 -> 右に配置して複数行に折り返す
- 右上 -> 左に配置して複数行に折り返す
- 左上 -> 下に配置して複数行に折り返す
- 左下 -> 上に配置して複数行に折り返す
- wrap-reverse 折り返しの開始位置を変える
- 左上 -> 右に配置して複数行に折り返す(のリバース)
- 右上 -> 左に配置して複数行に折り返す(のリバース)
- 左上 -> 下に配置して複数行に折り返す(のリバース)
- 左下 -> 上に配置して複数行に折り返す(のリバース)
- flex-flow ショートハンド
- まとめ
flex-wrap 1行に詰めたり折り返しを指定する
フレックスは、すべてのアイテムを1行に詰めたり、折り返しを指定したり、その折り返しの方向を変えたりすることができます。
デフォルトも含めて3つの指定ができます。
指定方法
- 1行に詰める(デフォルト)
- 複数行で折り返し
- 逆方向に複数行で折り返し
コンテナに指定します。
なんか分からないものがありますね? 3番目。ひとつずつ見ていきましょう。
フレックスのしくみが分からないとつらいので図を載せます。
nowrap 1行に詰める(デフォルト)
.container {
flex-wrap: nowrap;
}
"display: flex"を指定すると、アイテムが1行に詰めて表示されます。flex-wrapがデフォルトで"nowrap"になっているからです。
デフォルトの動きをフレックスの4方向のサンプルで見ていきます。
左に向かって1行に詰める
まずは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;
}
次にHTMLです。
<div class="sample">
<div class="container 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 class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
<div class="box">17</div>
<div class="box">18</div>
<div class="box">19</div>
<div class="box">20</div>
<div class="box">21</div>
<div class="box">22</div>
<div class="box">23</div>
<div class="box">24</div>
<div class="box">25</div>
<div class="box">26</div>
<div class="box">27</div>
<div class="box">28</div>
<div class="box">29</div>
<div class="box">30</div>
</div>
</div>
左に向かって1行に詰められます。アイテムの開始位置が左にあるからです。(main start)
詰めきれないものは、はみ出してしまうことに注意。
はみ出した部分は、ほかのコンテンツと重なります。
(どっちが上になるかはz-indexプロパティが影響する)
クロス軸はcross startから動きません。クロスサイズは0です。
1行に詰めるか折り返すかはクロス軸のサイズが影響します。
右に向かって1行に詰める
CSSに新たにクラスを追加します。
.sample .direction-row-reverse {
flex-direction: row-reverse;
}
HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-row-reverse">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
右に向かって1行に詰められます。アイテムの開始位置がリバースされて右にあるからです。(main start)
もちろん、折り返ししないのでクロスサイズは0。
同じようにはみだしが発生します。
上に向かって1行に詰める
CSSに新たにクラスを追加します。
.sample .direction-column {
flex-direction: column;
}
.sample .height {
height: 200px;
}
次にHTMLです。コンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column height">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">20</div>
</div>
</div>
heightプロパティを指定しないと、コンテナが無限にタテに広がって折り返しません。
(折り返すにはコンテナのheightプロパティに値を指定。)
上に向かって1行に詰められます。アイテムの開始位置が上にあるからです。(main start)
ちなみに、columnではメイン軸とクロス軸が交代します。もちろんヨコ向きに変わったクロスサイズは0。
はみだしが発生します。
Webページが崩れたように見えるはず。サンプルですが『こうなるよ』という意味で残しておきます。
Webページのバグではありません。
下に向かって1行に詰める
CSSに新たにクラスを追加します。
.sample .direction-column-reverse {
flex-direction: column-reverse;
}
HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column-reverse height">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">20</div>
</div>
</div>
下に向かって1行に詰められます。アイテムの開始位置がリバースされて下にあるからです。(main start)
(リバースはmain startとmain endが交代。)
もちろんクロスサイズは0。
1行に詰めるnowrapは、はみ出したり他のコンテンツに重なります。
自動で1行に詰める便利さはありますが『限度がある』ことに注意。
それでも、今まで自動で詰めるものは無かったので、とても便利な機能です。
詰める方向は、配置の方向(flex-direction)によって変わります。配置の基準の方向に向かって1行に詰めます。
サンプルでは、『1』のアイテムが基準です。
(アイテムの中で一番最初にHTMLに書かれたタグ)
wrap 複数行で折り返す
.container {
flex-wrap: wrap;
}
次は、複数行で折り返す"wrap"です。
コンテナの幅(高さ)までくるとアイテムを折り返します。
スクロールを使って幅・高さを伸ばすと折り返しません。1行にアイテムを配置します。
変更は、コンテナのCSSに"flex-wrap: wrap;"を追加するだけです。
左上 -> 右に配置して複数行に折り返す
CSSに新たにクラスを追加します。
.sample .wraps {
flex-wrap: wrap;
}
HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex wraps">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
flex-directionが未指定なので、ヨコの基準は左になります。でもタテの基準は指定できません。ここではタテの基準はデフォルトの上になります。
アイテムの開始位置は左上です。(main start)
1行に詰めるときはクロスサイズが0でした。折り返しのときはcross endが動いてクロスサイズが計算されます。この動きで折り返します。
cross endの位置、cross sizeは、コンテナのheight(width)になります。
右上 -> 左に配置して複数行に折り返す
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-row-reverse wraps">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
flex-directionがrow-reverseなので、ヨコの基準は右になります。でもタテの基準は指定できません。ここではタテの基準はデフォルトの上になります。
アイテムの開始位置は右上です。(main start)
(リバースはmain startとmain endが交代。)
もちろんクロスサイズはコンテナのheightになります。
左上 -> 下に配置して複数行に折り返す
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column height wraps">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
タテに折り返しました。
flex-directionがcolumnなので、タテの基準は上になります。でもヨコの基準は指定できません。ここではヨコの基準はデフォルトの左になります。
アイテムの開始位置は左上。(main start)
columnでメイン軸とクロス軸が交代しているので、クロスサイズはコンテナのwidthになります。
左下 -> 上に配置して複数行に折り返す
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column-reverse height wraps">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
下から上に向かう配置は、Webページの性質上、ユーザエクスペリエンス(UX, ユーザーの使いやすさ)の点からもあまり使うことはないと思います。
(高度なWebアプリではあるかもしれませんが。)
こういうこともできるという程度でいいでしょう。
flex-directionがcolumn-reverseなので、タテの基準は下になります。でもヨコの基準は指定できません。ここではヨコの基準はデフォルトの左になります。
アイテムの開始位置は左下です。(main start)
(リバースはmain startとmain endが交代)
もちろん、クロスサイズはコンテナのwidth。
wrap-reverse 折り返しの開始位置を変える
.container {
flex-wrap: wrap-reverse;
}
最後に『折り返しの開始位置を変える』です。これが一番分かりにくいと思います。
でも説明を聞くとかんたんです。wrapのところで、何度も『flex-directionで指定できないからデフォルトが...』と言ってきました。画像のクロス軸(黄色)の矢印です。
wrap-reverseは、このクロス軸の矢印をリバースします。
wrapでは基準にできないものがあるのに気づいたでしょうか?
- ヨコ向き -> 左下, 右下はできない。
- タテ向き -> 右上, 右下はできない。
このできない部分がwrap-reverseでできます。
- ヨコ向き -> 左下, 右下が基準になる。
- タテ向き -> 右上, 右下が基準になる。
すべてのパターン(4つ)でwrap-reverseしてみましょう。
HTMLはwrapのものをそのまま使います。CSSはflex-wrapだけを変更します。
比較のためにwrapの結果も表示します。
左上 -> 右に配置して複数行に折り返す(のリバース)
CSSに新たなクラスを追加します。
.sample .wraps-reverse {
flex-wrap: wrap-reverse;
}
HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex wraps-reverse">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
wrapでは『上か下か』の指定ができませんでした。それをwrap-reverseで指定します。『左上のリバース』なので『左下』が基準です。(main start, cross start)
"wrap-reverse"では、クロス軸のcross startとcross endを交代して方向を変えます。
右上 -> 左に配置して複数行に折り返す(のリバース)
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-row-reverse wraps-reverse">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
wrapでは『上か下か』の指定ができませんでした。それをwrap-reverseで指定します。『右上のリバース』なので『右下』が基準です。(main start, cross start)
(row-reverseでmain startとmain endを交代。)
(wrap-reverseでcross startとcross endを交代。)
左上 -> 下に配置して複数行に折り返す(のリバース)
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column height wraps-reverse">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
wrapでは『左か右か』の指定ができませんでした。それをwrap-reverseで指定します。『左上のリバース』なので『右上』が基準です。
(columnはメイン軸とクロス軸を交代。)
(wrap-reverseはcross startとcross endを交代。)
左下 -> 上に配置して複数行に折り返す(のリバース)
CSSに変更はありません。HTMLはコンテナのクラスを変更します。
<div class="sample">
<div class="container flex direction-column-reverse height wraps-reverse">
<div class="box">1</div>
<!-- 省略 -->
<div class="box">30</div>
</div>
</div>
wrapでは『左か右か』の指定ができませんでした。それをwrap-reverseで指定します。『左下のリバース』なので『右下』が基準です。(main start, cross start)
(column-reverseでメイン軸とクロス軸、main startとmain endを交代。)
(wrap-reverseでcross startとcross endを交代。)
flex-flow ショートハンド
flex-wrapプロパティは、コンテンツの並びの方向を指定するflex-directionプロパティと同時指定ができるショートハンドをもっています。
コンテナに指定します。
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
初期値 | row nowrap |
|| | 半角スペース区切り。順不同。1つ指定可。 |
例
.container {
// 順序はどうでもいい
flex-flow: wrap row; // row wrapと同じ
}
.container {
// flex-wrapの省略
flex-flow: row; // row nowrapと同じ
}
.container {
// flex-directionの省略
flex-flow: wrap; // row wrapと同じ
}
まとめ
フレックスを使って、コンテンツを1行に詰めたり折り返しをする方法をご紹介しました。
フレックスのすごいところはこれだけではありません。まだまだほかにもあります。
ここで説明すると長くなるのでとりあえずここまでにします。