CSS ポッドキャスト - 010: Flexbox
レスポンシブ デザインで扱いにくいデザイン パターンとして、コンテンツと一緒に配置されるサイドバーがあります。ビューポート スペースがある場合はこのパターンで十分ですが、スペースが狭くなると、レイアウトが固定されてしまうことがあります。
Flexible Box Layout Model(flexbox)は、1 次元のコンテンツ用に設計されたレイアウト モデルです。 サイズが異なる多数のアイテムを取得し、それらのアイテムに最適なレイアウトを返すのに優れています。
これは、このサイドバー パターンに最適なレイアウト モデルです。 Flexbox は、サイドバーとコンテンツをインラインで配置するのに役立つだけでなく、十分なスペースが残っていない場合は、サイドバーが新しい行に改行されます。Flexbox では、ブラウザのサイズを固定する代わりに、柔軟な境界を設定し、コンテンツの表示方法のヒントを与えることができます。
柔軟なレイアウトでできること
Flex レイアウトには次の機能があり、このガイドではそれらについて説明します。
- 行または列として表示できます。
- ドキュメントの作成モードが考慮されます。
- デフォルトでは 1 行ですが、複数の行で折り返すこともできます。
- レイアウト内のアイテムは、DOM 内の順序に関係なく、視覚的に並べ替えることができます。
- スペースはアイテム内で分配できるため、親で利用可能なスペースに応じてサイズが大きくなります。
- Box Alignment プロパティを使用して、ラップされたレイアウト内のアイテムとフレックス ラインの周囲にスペースを分配できます。
- アイテム自体を交差軸上に配置できます。
主軸と交差軸
Flexbox を理解するには、主軸と交差軸の概念を理解することが重要です。
主軸は、flex-direction
プロパティで設定する軸です。row
の場合、主軸は行に沿っています。column
の場合、主軸は列に沿っています。
Flex アイテムは、メイン軸上でグループとして移動します。 たくさんの項目を用意しており、参加者にとって最適なレイアウトにしたいと思っています。
交差軸はメイン軸の反対方向に存在します。flex-direction
が row
の場合、交差軸は列に沿って表示されます。
交差軸では 2 つの操作を行うことができます。
アイテムは個別またはグループとして移動して、相互に、または Flex コンテナに対して位置合わせできます。また、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 アイテムの子を持つブロックレベルのボックスが作成されます。フレキシブル アイテムは、初期値を使用したフレックスボックス動作がすぐに現れ始めます。
初期値の意味は次のとおりです。
- アイテムは行として表示されます。
- ラップは包まれません。
- コンテナいっぱいに大きくなることはありません。
- これらはコンテナの先頭に配置されます。
アイテムの向きを制御する
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 では上、下、左、右ではなく、開始と終了について話す方が理解しやすい場合があります。各軸には開始と終了があります。メイン軸の始点は「main-start」と呼ばれます。そのため、フレキシブル アイテムは最初はメインスタートから並べられます。 その軸の終点は「main-end」です。交差軸の始点は cross-start、終点は cross-end です。
Flex アイテムのラッピング
flex-wrap
プロパティの初期値は nowrap
です。つまり、コンテナに十分なスペースがない場合、アイテムはオーバーフローします。
初期値を使用して表示されるアイテムは、オーバーフローが発生する前に min-content
サイズまで可能な限り小さく縮小されます。
アイテムをラップするには、Flex コンテナに flex-wrap: wrap
を追加します。
.container {
display: flex;
flex-wrap: wrap;
}
Flex コンテナがラップされると、複数の Flex 行が作成されます。スペースの分散では、各行が新しい Flex コンテナのように機能します。そのため、行を折り返すと、行 2 の内容と行 1 より上の文字列を一致させることはできません。これが、Flexbox が一次元であることを意味しています。 グリッドとは異なり、1 つの軸、行、列のいずれかで配置を制御できます。両方をまとめて制御することはできません。
Flex-Flow の省略形
省略形の flex-flow
を使用して、flex-direction
プロパティと flex-wrap
プロパティを設定できます。たとえば、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 コンテナの子に適用されます。
アイテムを大きくする一方で、大きいアイテムには小さいアイテムよりも広いスペースを持たせる場合は、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 アイテムには、異なる flex-grow
要素を指定できます。下のデモでは、1 つ目のアイテムに 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
は次のとおりです。
row
column
デフォルトでは、Flex コンテナは子をラップします。
flex-wrap: wrap
と display: flex
を使用して子をラップするFlex の子アイテムがつぶれていますが、この問題を軽減できる Flex プロパティは次のうちどれですか。
flex-grow
flex-shrink
flex-basis
Flexbox の配置の概要
Flexbox には、アイテムを整列し、アイテム間のスペースを分配するための一連のプロパティが用意されています。 これらのプロパティは非常に有用で、それ以降は独自の仕様に移行されています。グリッド レイアウトでもこのようなプロパティを使用できます。ここでは、Flexbox を使用した場合に、どのように動作するかを説明します。
プロパティのセットは 2 つのグループに分類できます。スペース分布のプロパティと配置のプロパティ。 スペースを分配するプロパティは次のとおりです。
justify-content
: 主軸上の空間分布。align-content
: 交差軸上の空間分布。place-content
: 上記の両方のプロパティ設定の省略形
フレックスボックスでアライメントに使用されるプロパティは次のとおりです。
align-self
: 1 つのアイテムを交差軸上で位置揃えします。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
を付与する必要があります。そうしないと、配布するための予備のスペースを確保できません。
別の値を試してみてください。今回は Flexbox の列レイアウトです。
Flex ライン間のスペースの分散
ラップされた Flex コンテナを使用すると、交差軸上で分配するスペースを確保できます。この場合、align-content
プロパティに justify-content
と同じ値を指定できます。デフォルトでアイテムを flex-start
に揃える justify-content
とは異なり、align-content
の初期値は stretch
です。このデフォルトの動作を変更するには、プロパティ align-content
を Flex コンテナに追加します。
.container {
align-content: center;
}
デモでお試しください。この例では、Flex アイテムの行を折りたたんでおり、予備のスペースを確保するためにコンテナに block-size
があります。
place-content
省略形
justify-content
と align-content
の両方を設定するには、place-content
を使用して 1 つまたは 2 つの値を指定します。最初の軸を align-content
に、2 番目の軸を justify-content
に指定すると、両方の軸に 1 つの値が使用されます。
.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 コンテナの高さ、またはアイテムのセットをラップしている場合は Flex 行の高さによって異なります。
align-self
の初期値は stretch
であるため、デフォルトでは、行のフレキシブル アイテムは最も背の高いアイテムの高さまで拡張されます。これを変更するには、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
プロパティをすべて 1 つのグループとして設定できます。
.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
に揃えられます。子アイテムでコンテンツ サイズを使用する場合、次のどのスタイルを使用しますか。
justify-content: flex-start
align-content: start
content
は、子アイテムの配置ではなく、Flex の線の配置を調整します。height: auto
align-items: flex-start