ブロック整形コンテキスト

ブロック整形コンテキストとは

ブロック整形コンテキストとは、ブラウザによるレンダリング機能の一部で、ブロックボックスのレイアウトが行われ、浮動が他の要素と相互に作用する領域を指します。

ブロック整形コンテキストは、以下の2つの動きを理解するのに重要な概念です。

  • float による浮動の設定と解除
  • マージンの相殺

浮動の設定と解除も、マージンの相殺も、同じブロック整形コンテキストに所属するブロック同士で発生するのが原則です。

ブロック整形コンテキストは、以下の条件のいずれかに該当する要素で生成されます。

  • 文書のルート要素( <html> 要素)
  • 浮動要素( float が none 以外の要素)
  • 絶対位置指定の要素( position が absolute / fixed のいずれかの要素)
  • インラインブロック( display が inline-block の要素)
  • 表のセル( display が table-cell の要素、<th> 要素や <td> 要素の既定値)
  • 表のキャプション( display が table-caption の要素、<caption> 要素の既定値)
  • display が table, table-row, table-row-group, table-header-group, table-footer-group のいずれかの要素( <table> , <tr> , <thead> , <tbody> , <tfoot> の各要素の既定値)
  • display が inline-table の要素によって暗黙的に生成された、無名の表のセル
  • overflow が visible 以外のブロック要素
  • display が flow-root の要素
  • contain が layout, content, paint の要素
  • フレックスアイテム( display : flex または inline-flex である要素の直接の子要素)
  • グリッドアイテム( display : grid または inline-grid である要素の直接の子要素)
  • 段組みコンテナー( column-count または column-width が auto ではない要素、 column-count: 1 の要素も含む)
  • column-span が all の要素は、 column-span が all の要素が段組みコンテナーに含まれていなくても、常に新たな整形コンテキストを生成します

ブロック整形コンテキストは、それを生成する要素の内側にあるすべてのものを含みます。

浮動要素とその親の高さ

以下の例では、<div> 要素に border が適用されている中に浮動要素があります。その <div> 要素の内容は、浮動要素の横にあります。浮動要素の内容がその横のコンテンツよりも高いので、 <div> 要素の境界は浮動要素を突き抜けてしまいます。

このときは、#box2 はブロック整形コンテキストを生成していますが、親要素の #box1 はブロック整形コンテキストを生成していません。

<body>
    <div class="box" id="box1">
        <div class="float" id="box2">ここは浮動要素です。</div>
        <p>ここは class="box" の <div>要素の中身です。</p>
    </div>
</body>
.box {
    background-color: lavender;
    border: 5px solid blueviolet;
}
.float {
    float: left;
    width: 200px;
    height: 150px;
    background-color: white;
    border:1px solid black;
    padding: 10px;
}

overflow: auto; で高さを揃える

今度は、#box1 もブロック整形コンテキストを生成するように、修正を加えてみます。

<body>
    <div class="box" id="box1">
        <div class="float" id="box2">ここは浮動要素です。</div>
        <p>ここは class="box" の <div>要素の中身です。</p>
    </div>
</body>
.box {
    background-color: lavender;
    border: 5px solid blueviolet;
    overflow: auto;
}
.float {
    float: left;
    width: 200px;
    height: 150px;
    background-color: white;
    border:1px solid black;
    padding: 10px;
}

こんどは、#box1 もブロック整形コンテキストを生成しているので、#box2 はそのブロック整形コンテキストの中に収まることになり、はみ出ることはありません。

この方法は、float させた子要素をはみ出させないテクニックとして、よく紹介されていますが、本来、overflow プロパティはブロックからあふれた内容をどう扱うかを指示するためのものです。そのため、内容によっては、意図せず不要なスクロールバーが表示されてしまう場合があったり、ソースの可読性が下がってしまうリスクがあります。

display: flow-root; を使用する

この方法も、#box1 がブロック整形コンテキストを生成するように修正する方法です。overflow プロパティを使うことに懸念があったり、overflow : visible; を使う必要がある場合には、こちらの方法がおすすめです。

<body>
    <div class="box" id="box1">
        <div class="float" id="box2">ここは浮動要素です。</div>
        <p>ここは class="box" の <div>要素の中身です。</p>
    </div>
</body>
.box {
    background-color: lavender;
    border: 5px solid blueviolet;
    display: flow-root;
    overflow: visible;
}
.float {
    float: left;
    width: 200px;
    height: 150px;
    background-color: white;
    border:1px solid black;
    padding: 10px;
}

ただし、display: flow-root; は CSS3 の【勧告候補】なので、Internet explorer は非対応ですし、主要ブラウザーでもバージョンが古い場合は対応していません。

マージンの相殺

2つの隣接するブロックでマージンの相殺が発生しないようにするには、パディングを取る、ボーダーを設定するなどの方法がありますが、ブロック整形コンテキストを生成することでも、マージンの相殺が発生しないするようにすることが出来ます。

<body>
    <div class="blue"></div>
    <div class="red-outer">
      <div class="red-inner">red inner</div>
    </div>
</body>
.blue, .red-inner {
    height: 50px;
    margin: 10px 0;
}
.blue {
    background: blue;
}
.red-outer {
    overflow: hidden;
    background: red;
}

 


このサイトでは、CSSのセレクタ・プロパティなどの定義は下記サイトを参考にしています。
MDN Web Docs: https://developer.mozilla.org/ja/
W3C仕様の正確な定義、最新情報は上記サイトをご覧ください。
CSSのプロパティがどのブラウザに対応しているのかは、下記のサイトで確認できます。
Can I Use?: https://caniuse.com/#home

コメント

タイトルとURLをコピーしました