CSS 入門

CSS Flexbox のネスト(入れ子)

フレックスボックス(Flexbox)コンテナのネスト(入れ子)は、複雑かつ高度に柔軟なレイアウトを作成するための核心的な技術です。

これは、HTML構造の異なる階層においてFlexboxのレイアウト機能を組み合わせて使用することを可能にし、要素内部の子要素に対して極めて精密なポジショニングとアライメント(整列)の制御を実現します。ネストのテクニックをマスターすれば、あらゆる画面サイズやデバイスに完璧に適応する、洗練されたページ構造を構築できるようになります。

1. フレックスボックスのネストを理解する

Flexboxのネストの本質は非常にシンプルです。それは、「あるフレックスアイテム自体を、さらにフレックスコンテナにする」ということです。

つまり、フレックスコンテナの直接の子要素が、同時に自分自身の子要素に対するフレックスコンテナとして機能できることを意味します。このメカニズムによって、階層化されたレイアウト構造が構築されます。外側のコンテナは直接の子要素の「マクロ(広域)」な配置を担当し、内側のコンテナは内部の小さな要素の「ミクロ(詳細)」な配置を独立して担当します。

2. ネストにおける3つの核心原則

2.1 親子関係 (Parent-Child Relationship)

Flexboxのネストの鍵は、HTML要素間の厳格な親子関係にあります。親要素がフレックスコンテナになり、その直接の子要素がフレックスアイテムになります。これらのフレックスアイテムのいずれも、display: flex を設定することで、新たな親コンテナになることができます。

2.2 独立した制御 (Independent Control)

各フレックスコンテナは、自身の直接の子要素を独立して制御します。外側のコンテナのアライメント属性を変更しても、内側のコンテナ内の要素の並び順に自動的に影響を与えることはありません(ただし、外側コンテナのサイズ変化が内側コンテナの利用可能なスペースに影響を与えることはあります)。

2.3 継承の制限 (Inheritance Limited)

Flexboxのレイアウトプロパティは、デフォルトでは継承されません。コンテナとして機能させたいすべてのHTML要素に対して、明示的に display: flex(または inline-flex)を宣言する必要があります。font-sizecolor のような一般的なプロパティは通常通り継承されますが、Flexbox専用の排版ルールは継承されない点に注意してください。

3. 実行例1:基本的なネスト構造

最も基本的なネストの例を見てみましょう。

<div class="outer-container">
  <div class="item item-1">プロジェクト 1</div>
  <div class="item item-2">プロジェクト 2
    <div class="inner-container">
      <div class="inner-item">内層アイテム 1</div>
      <div class="inner-item">内層アイテム 2</div>
    </div>
  </div>
  <div class="item item-3">プロジェクト 3</div>
</div>
.outer-container {
  display: flex;
  background-color: #eee;
  padding: 20px;
  gap: 10px;
}

.item {
  background-color: #ddd;
  padding: 20px;
  text-align: center;
}

.inner-container {
  display: flex; /* 重要:内部の div もフレックスコンテナにする */
  flex-direction: column; /* 内層アイテムを垂直方向に積み重ねる */
  background-color: #ccc;
  margin-top: 10px;
}

.inner-item {
  background-color: #bbb;
  padding: 10px;
  margin: 5px;
  text-align: center;
}

コード解析:

  • .outer-container は外側のフレックスコンテナであり、自身の子要素(.item)を水平方向に並べます(デフォルトの row 方向)。
  • .item-2 は通常のフレックスアイテムですが、その内部に .inner-container を含んでいます。
  • .inner-container もまた、display: flex を宣言しているためフレックスコンテナです。ここでは flex-direction: column を使用して、自身の子要素(.inner-item)を垂直方向に並べています。この display: flex の宣言がない場合、内部の要素はフレックスレイアウトのルールに従いません。

4. 実行例2:階層ごとのアライメント制御

ネストの強力な点は、階層ごとに全く異なる整列戦略(アライメント)を設定できることです。

<div class="outer-container">
  <div class="item">プロジェクト 1</div>
  <div class="item">プロジェクト 2
    <div class="inner-container">
      <div class="inner-item">内層アイテム 1</div>
      <div class="inner-item">内層アイテム 2</div>
    </div>
  </div>
  <div class="item">プロジェクト 3</div>
</div>
.outer-container {
  display: flex;
  justify-content: space-around; /* 外層アイテムを均等に分布 */
  align-items: center; /* 外層アイテムを垂直中央揃え */
  background-color: #eee;
  padding: 20px;
  height: 200px; /* 外層コンテナに固定高さを設定 */
}

.item {
  background-color: #ddd;
  padding: 20px;
  text-align: center;
}

.inner-container {
  display: flex;
  justify-content: center; /* 内層コンテナ内でアイテムを垂直方向(主軸)に中央揃え */
  align-items: flex-end; /* 内層アイテムを交差軸(水平方向)の終端に寄せる */
  flex-direction: column;
  background-color: #ccc;
  height: 100px; /* 位置関係を観察するために内層コンテナに高さを設定 */
}

.inner-item {
  background-color: #bbb;
  padding: 10px;
  margin: 5px;
  text-align: center;
}

コード解析:

  • 外側の .outer-containerjustify-content: space-around を使用して主軸上で3つの .item を均等に分散させ、align-items: center で全体を垂直中央に配置しています。
  • 内側の .inner-containerjustify-content: center を使用して内部要素を垂直方向(この階層の主軸)に中央揃えにし、さらに align-items: flex-end で内側アイテムを右端に寄せています(列レイアウトのため、交差軸が水平方向になります)。

5. 実行例3:ネストされたコンテナでの flex-grow 活用

以前に学んだスペース分配プロパティ(flex-grow)と組み合わせることで、ネストレイアウトは極めて高い自律的な適応力を発揮します。

<div class="outer-container">
  <div class="sidebar">サイドバー</div>
  <div class="main-content">
    <div class="inner-container">
      <div class="inner-item">プロジェクト 1</div>
      <div class="inner-item">プロジェクト 2</div>
      <div class="inner-item">プロジェクト 3</div>
    </div>
  </div>
</div>
.outer-container {
  display: flex;
  height: 300px;
}

.sidebar {
  background-color: #ddd;
  width: 200px;
}

.main-content {
  background-color: #eee;
  flex-grow: 1; /* メインコンテンツエリアに残りの全スペースを占有させる */
  display: flex; /* メインコンテンツエリア自体もフレックスコンテナにする */
}

.inner-container {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
  background-color: #ccc;
  flex-grow: 1; /* 重要:内層コンテナがメインエリア内でさらに膨張して埋め尽くすようにする */
}

.inner-item {
  background-color: #bbb;
  padding: 10px;
  text-align: center;
  width: 80%;
}

コード解析:

  • .outer-container は、左側に固定幅のサイドバー、右側にメインコンテンツエリアというクラシックな2カラムレイアウトを作成します。
  • .main-content は外側のフレックスアイテムとして、flex-grow: 1 により右側の余剰幅をすべて占有します。同時に、display: flex を設定することで内側コンテナの親(コンテナ)となります。
  • .main-content 内にネストされた .inner-container に対して flex-grow: 1 を設定することが非常に重要です。これにより、単に内部テキストの高さを包むだけでなく、.main-content 領域全体を垂直方向に引き伸ばして埋め尽くすことができます。その上で、flex-direction: columnjustify-content: space-around を使って、内部の3つのボックスをエレガントに整列させています。