CSS Podcast - 010: Flexbox
レスポンシブ デザインで扱いにくい設計パターンの 1 つが、一部のコンテンツとインラインに配置されるサイドバーです。ビューポートのスペースがある場合は、このパターンが適切ですが、スペースが限られている場合は、固定レイアウトが問題になる可能性があります。
フレキシブル ボックス レイアウト モデル(flexbox)は、1 次元のコンテンツ用に設計されたレイアウト モデルです。サイズの異なるアイテムをまとめて取り込み、それらのアイテムに最適なレイアウトを返す点が優れています。
これは、このサイドバー パターンに最適なレイアウト モデルです。 Flexbox を使用すると、サイドバーとコンテンツをインラインで配置できるだけでなく、スペースが足りない場合はサイドバーが改行されます。ブラウザが従う固定のサイズを設定する代わりに、フレックスボックスを使用して柔軟な境界を指定し、コンテンツの表示方法をヒントとして提供できます。
フレックス レイアウトでできること
フレックス レイアウトには次の機能があります。このガイドでは、これらの機能について説明します。
- 行または列として表示できます。
- ドキュメントの書き込みモードが優先されます。
- デフォルトでは 1 行ですが、複数行に折り返すように指定することもできます。
- レイアウト内のアイテムは、DOM 内の順序とは異なる順序で視覚的に並べ替えることができます。
- スペースはアイテム内に分散できるため、親で使用可能なスペースに応じてアイテムのサイズが大きくまたは小さくなります。
- 折り返しレイアウトのアイテムと Flex 行の周囲にスペースを配置するには、Box Alignment プロパティを使用します。
- アイテム自体は交差軸に沿って配置できます。
主軸と交差軸は
Flexbox を理解するには、主軸と交差軸の概念を理解することが重要です。主軸は flex-direction
プロパティで設定される軸です。これが row
の場合、主軸は行に沿って、column
の場合、主軸は列に沿っています。
Flex アイテムは、主軸でグループとして移動します。さまざまな要素をグループとして最適なレイアウトにまとめることを念頭に置いてください。
交差軸はメイン軸とは反対の方向に走行するため、flex-direction
が row
の場合、交差軸は列に沿って走行します。
クロス軸では次の 2 つのことができます。アイテムは個別に、またはグループとして移動して、互いに、および Flex コンテナに対して配置できます。また、折り返しフレックス線がある場合は、それらの線をグループとして扱い、それらの線にスペースを割り当てる方法を制御できます。このガイドでは、この仕組みが実際にどのように機能するかを説明します。まずは、メイン軸が flex-direction
の後に続くことを覚えておいてください。
Flex コンテナの作成
さまざまなサイズのアイテムのグループを取得し、Flexbox を使用してレイアウトすることで、Flexbox がどのように動作するかを見てみましょう。
<div class="container" id="container">
<div>One</div>
<div>Item two</div>
<div>The item we will refer to as three</div>
</div>
flexbox を使用するには、通常のブロックとインライン レイアウトではなく、flex フォーマット コンテキストを使用することを宣言する必要があります。そのためには、display
プロパティの値を flex
に変更します。
.container {
display: flex;
}
レイアウト ガイドで学んだように、これにより、子要素としてフレックス アイテムを含むブロックレベルのボックスが作成されます。フレックスアイテムは、初期値を使用して、すぐにフレックスボックスの動作を開始します。
初期値の意味は次のとおりです。
- 項目が行として表示されます。
- 折り返されません。
- コンテナいっぱいに大きくなることはありません。
- コンテナの先頭に並べられます。
アイテムの向きの制御
flex-direction
プロパティはまだ追加していませんが、flex-direction
の初期値が row
であるため、アイテムが行として表示されます。行が必要な場合は、プロパティを追加する必要はありません。方向を変更するには、プロパティと次の 4 つの値のいずれかを追加します。
row
: アイテムが行として配置されます。row-reverse:
アイテムは Flex コンテナの端から行として配置されます。column
: アイテムが列として配置されます。column-reverse
: アイテムは Flex コンテナの端から列として配置されます。
以下のデモで、アイテムのグループを使用してすべての値を試すことができます。
アイテムの流れとユーザー補助機能の逆転
視覚的な表示の順序を HTML ドキュメント内の順序から変更するプロパティを使用する場合は、ユーザー補助に悪影響を及ぼす可能性があるため、注意が必要です。row-reverse
と column-reverse
の値がその一例です。並べ替えは論理的な順序ではなく、視覚的な順序に対してのみ行われます。これは、論理的な順序がスクリーン リーダーがコンテンツを読み上げる順序であり、キーボードを使用して移動するユーザーが従う順序であるため、理解することが重要です。
次の動画では、行の反転レイアウトで、キーボード ナビゲーションが視覚的な表示ではなく DOM に従うため、リンク間のタブ移動が切断される様子を確認できます。
この問題は、Flexbox やグリッド内のアイテムの順序を変更できるものが原因で発生する可能性があります。そのため、並べ替えを行う場合は、一部のユーザーがサイトを使いづらくなることがないように、徹底したテストを行う必要があります。
詳細については、次をご覧ください。
書き込みモードと方向
Flex アイテムは、デフォルトで行としてレイアウトされます。行は、書式設定モードとスクリプトの方向で文章が流れていく方向に配置されます。つまり、アラビア語では右から左(rtl)に書くスクリプトの方向である場合、アイテムは右に揃えられます。タブ オーダーも右から始まります。これは、アラビア語で文章を読む順序が右から左であるためです。
一部の日本語書体など、縦書きモードで作業している場合、行は上から下に垂直に表示されます。縦書きモードを使用しているこのデモの flex-direction
を変更してみてください。
そのため、Flex アイテムのデフォルトの動作は、ドキュメントの書き込みモードにリンクされます。ほとんどのチュートリアルは、英語または他の横向きの左から右の書き込みモードを使用して作成されています。こうすることで、Flex のアイテムが左側に並べられ、水平に実行されると想定しやすくなります。
メイン軸とクロス軸に加えて、書き込みモードも考慮する必要があるため、Flexbox では上、下、左、右ではなく、開始と終了について説明するのがわかりやすいかもしれません。各軸には開始と終了があります。メイン軸の開始点はメイン開始点と呼ばれます。そのため、Flex アイテムは最初はメインの開始位置から並べられます。その軸の端は main-end です。交差軸の始点は交差点、終点は交差点です。
フレックスアイテムのラップ
flex-wrap
プロパティの初期値は nowrap
です。つまり、コンテナに十分なスペースがない場合、アイテムはオーバーフローします。
初期値を使用して表示されるアイテムは、オーバーフローが発生する前に min-content
サイズに縮小され、可能な限り小さくなります。
アイテムをラップするには、Flex コンテナに flex-wrap: wrap
を追加します。
.container {
display: flex;
flex-wrap: wrap;
}
Flex コンテナがラップされると、複数のFlex 行が作成されます。スペースの分布に関して、各行は新しい Flex コンテナのように動作します。したがって、行を折り返している場合、2 行目の内容を 1 行目の上にある内容と揃えることはできません。これがフレックスボックスが 1 次元であることを意味します。グリッドのように両方を同時に設定することはできませんが、1 つの軸(行または列)の配置を制御できます。
flex-flow の省略形
flex-direction
プロパティと flex-wrap
プロパティは、省略形 flex-flow
を使用して設定できます。たとえば、flex-direction
を column
に設定してアイテムの折り返しを許可するには、次のようにします。
.container {
display: flex;
flex-flow: column wrap;
}
Flex アイテム内のスペースの制御
コンテナにアイテムの表示に必要なスペースよりも多くのスペースがあると仮定すると、アイテムは先頭に並び、スペースを埋めるように拡大されません。コンテンツの最大サイズが上限に達すると増えなくなります。
これは、flex-
プロパティの初期値が次のようになるためです。
flex-grow: 0
: アイテムが成長しません。flex-shrink: 1
: アイテムはflex-basis
よりも小さく縮小される場合があります。flex-basis: auto
: アイテムのベースサイズはauto
です。
これは、flex: initial
のキーワード値で表すことができます。flex
ショートカット プロパティ、または flex-grow
、flex-shrink
、flex-basis
の長い形式が、フレックス コンテナの子に適用されます。
アイテムを大きくし、大きなアイテムに小さなアイテムよりも多くのスペースを割り当てるには、flex:auto
を使用します。上記のデモで試すことができます。これにより、プロパティが次のように設定されます。
flex-grow: 1
: アイテムはflex-basis
よりも大きくなることができます。flex-shrink: 1
: アイテムはflex-basis
より小さくできます。flex-basis: auto
: アイテムの基本サイズはauto
です。
flex: auto
を使用すると、各アイテムが最大コンテンツ サイズとしてレイアウトされた後、アイテム間で共有されるスペースが共有されるため、アイテムのサイズが異なることになります。そのため、アイテムが大きいほど表示スペースが大きくなります。すべてのアイテムのサイズを強制的に一貫させ、デモ内のコンテンツのサイズ変更 flex:auto
から flex: 1
を無視するには、
展開すると次のようになります。
flex-grow: 1
: アイテムはflex-basis
よりも大きくなることができます。flex-shrink: 1
: アイテムはflex-basis
よりも小さく縮小できます。flex-basis: 0
: アイテムの基本サイズは0
です。
flex: 1
を使用すると、すべてのアイテムのサイズがゼロになり、Flex コンテナ内のすべてのスペースを分散できます。すべてのアイテムの flex-grow
係数が 1
であるため、それらはすべて均等に増加し、スペースは均等に共有されます。
アイテムの成長率を異なるものにする
すべてのアイテムに flex-grow
係数 1
を指定する必要はありません。フレックスアイテムに異なる flex-grow
係数を指定できます。以下のデモでは、最初の項目に flex: 1
、2 番目の項目に flex: 2
、3 番目の項目に flex: 3
が含まれています。これらのアイテムが 0
から増加すると、Flex コンテナの使用可能なスペースは 6 つに共有されます。最初のアイテムに 1 つのパート、2 番目のアイテムに 2 つのパート、3 番目のアイテムに 3 つのパートが割り当てられます。
auto
の flex-basis
からも同じことができますが、3 つの値を指定する必要があります。最初の値は flex-grow
、2 番目の値は flex-shrink
、3 番目の値は flex-basis
です。
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
あまり一般的ではありませんが、auto
の flex-basis
を使用する理由は、ブラウザがスペース分布を把握できるようにするためです。アルゴリズムで判断されるレベルよりもアイテムを大きくしたい場合、有用性が判定されます。
Flex アイテムの並べ替え
フレックス コンテナ内のアイテムは、order
プロパティを使用して並べ替えることができます。このプロパティを使用すると、項目を序数グループで並べ替えることができます。アイテムは、flex-direction
で指定された方向(最小値が先)に配置されます。
複数のアイテムに同じ値が設定されている場合は、その値が設定されている他のアイテムとともに表示されます。
次の例は、この順序を示しています。
理解度をチェックする
Flexbox に関する知識をテストする
デフォルトの flex-direction
は次のとおりです。
column
row
デフォルトでは、Flex コンテナは子をラップします。
Flex の子アイテムが圧迫されているように見えます。これを軽減するには、どの Flex プロパティが役立ちますか。
flex-basis
flex-grow
flex-shrink
Flexbox の配置の概要
Flexbox には、アイテムの配置とアイテム間のスペースの分散のための一連のプロパティが用意されています。これらのプロパティは非常に有用であるため、独自の仕様に移行されました。グリッド レイアウトでも使用できます。フレックスボックスを使用している場合の動作については、こちらをご覧ください。
一連のプロパティは 2 つのグループに分類できます。スペースの分散に関するプロパティと、配置に関するプロパティ。スペースを分散するプロパティは次のとおりです。
justify-content
: 主軸のスペース分布。align-content
: 交差軸上の空間分布。place-content
: 上記の両方のプロパティを設定する省略形。
Flexbox の配置に使用されるプロパティ:
align-self
: 交差軸に単一のアイテムを配置します。align-items
: すべてのアイテムをグループとして交差軸で揃えます。
メイン軸を操作している場合、プロパティは justify-
で始まります。クロス軸では align-
で始まります。
メイン軸にスペースを分散する
前述の HTML では、Flex アイテムが行として配置され、メイン軸にスペースがあります。アイテムが Flex コンテナを完全に埋め尽くすほど大きくない。justify-content
の初期値が flex-start
であるため、アイテムは Flex コンテナの先頭に並べられます。アイテムは先頭に並び、余分なスペースは末尾にあります。
justify-content
プロパティを Flex コンテナに追加し、値を flex-end
に設定すると、アイテムはコンテナの末尾に並び、余分なスペースが先頭に配置されます。
.container {
display: flex;
justify-content: flex-end;
}
justify-content: space-between
を使用して、アイテム間のスペースを分散することもできます。
デモの値の一部をお試しください。設定可能な値の完全なセットについては、MDN をご覧ください。
flex-direction: column
でログイン
flex-direction
を column
に変更した場合、justify-content
は列で機能します。列として動作するときにコンテナに余分なスペースを確保するには、コンテナに height
または block-size
を指定する必要があります。そうしないと、配布する余分なスペースがなくなります。
さまざまな値を試します。今回は、フレックスボックスの列レイアウトを使用します。
フレックス行間のスペースを分散する
折り返しの Flex コンテナを使用すると、交差軸に分散するスペースが確保される場合があります。この場合は、justify-content
と同じ値で align-content
プロパティを使用できます。デフォルトでアイテムを flex-start
に揃える justify-content
とは異なり、align-content
の初期値は stretch
です。このデフォルトの動作を変更するには、プロパティ align-content
を Flex コンテナに追加します。
.container {
align-content: center;
}
デモで試してみてください。この例では、Flex アイテムの行が折り返されており、余分なスペースを確保するためにコンテナに block-size
が含まれています。
place-content
の省略形
justify-content
と align-content
の両方を設定するには、1 つまたは 2 つの値で place-content
を使用します。両方を指定すると、1 つ目の値は align-content
に、2 つ目の値は justify-content
に使用されます。
.container {
place-content: space-between;
/* sets both to space-between */
}
.container {
place-content: center flex-end;
/* wrapped lines on the cross axis are centered,
on the main axis items are aligned to the end of the flex container */
}
交差軸でアイテムを配置する
クロス軸では、align-items
と align-self
を使用して、フレックス行内のアイテムを配置することもできます。この配置に使用できるスペースは、Flex コンテナの高さ(アイテムの折り返しセットの場合は Flex 行)によって異なります。
align-self
の初期値は stretch
です。そのため、行内のフレックス アイテムはデフォルトで最も高いアイテムの高さまで伸びます。これを変更するには、いずれかの Flex アイテムに align-self
プロパティを追加します。
.container {
display: flex;
}
.item1 {
align-self: flex-start;
}
次のいずれかの値を使用してアイテムを配置します。
flex-start
flex-end
center
stretch
baseline
MDN の値の一覧をご覧ください。
次のデモでは、flex-direction: row
が指定された 1 行の Flex アイテムを示します。最後の項目は、Flex コンテナの高さを定義します。最初の項目の align-self
プロパティの値は flex-start
です。そのプロパティの値を変更して、クロス軸上のスペース内でどのように移動するかを確認します。
align-self
プロパティは個々のアイテムに適用されます。align-items
プロパティを Flex コンテナに適用すると、個々の align-self
プロパティをすべてグループとして設定できます。
.container {
display: flex;
align-items: flex-start;
}
次のデモでは、align-items
の値を変更して、すべての項目をグループとしてクロス軸に配置します。
flexbox に justify-self がないのはなぜですか?
Flex アイテムは、主軸でグループとして機能します。そのため、個別のアイテムをそのグループから分割するという概念はありません。
グリッド レイアウトでは、justify-self
プロパティと justify-items
プロパティがインライン軸で機能し、グリッド領域内のその軸上のアイテムを配置します。Flex レイアウトではアイテムをグループとして扱うため、これらのプロパティは Flex のコンテキストでは実装されません。
なお、flexbox は自動マージンと非常によく連携します。グループから 1 つのアイテムを分割する必要がある場合や、グループを 2 つのグループに分割する必要がある場合は、マージンを適用して分割できます。次の例では、最後の項目の左側の余白は auto
です。自動マージンは、適用される方向のすべてのスペースを吸収します。これは、アイテムを右に押し出し、グループが分割されることを意味します。
アイテムを縦方向と横方向の中央に配置する方法
配置プロパティを使用すると、別のボックス内にアイテムを中央に配置できます。justify-content
プロパティは、アイテムをメイン軸(行)に揃えます。交差軸の align-items
プロパティ。
.container {
width: 400px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
理解度を確認する
Flexbox に関する知識をテストする
.container { display: flex; direction: ltr; }
Flexbox を縦方向に配置するには、次のコマンドを使用します。
.container { display: flex; direction: ltr; }
Flexbox で水平方向に配置するには、
.container { display: flex; direction: ltr; }
デフォルトでは、Flex アイテムは stretch
に配置されます。コンテンツ サイズを子アイテムに使用する場合、次のスタイルのどれを使用すればよいですか。
align-content: start
height: auto
justify-content: flex-start
align-items: flex-start