包含ブロックとは
2017年2月26日
「widthやmarginなどのサイズの設定次第で包含ブロックとなる親要素を飛び出す(オーバーフローする)ことも可能です」
を追加しました。
ボックスモデルは次の図で表すことができます。
ボーダーを境界にしてマージンとパディングがあり、パディングの内側にコンテンツ(内容領域)が存在します。
これは例えると自分から見た地球のイメージです。
では神の目から見た地球はどんな感じでしょうか。
宇宙があって、その中に太陽系があって地球が存在する。そんなイメージが包含ブロックの考え方です。CSSにおける視覚整形モデルは宇宙ほど複雑で神秘的ではありません。それは実にシンプルで有限のものです。
ちょうど宇宙にあたるものがルート要素(html)の包含ブロックです。それは初期包含ブロックといいます。
初期包含ブロックはビューポートの寸法を持ち、キャンバスの原点で固定される。 初期包含ブロックはページメディアのページ領域となる。
と定義されていますが、簡単に言ってしまうとそれはブラウザの表示領域のことです。
たとえばdisplay:blockで指定された要素を通常フローさせた場合、ルート要素が作成している包含ブロック、つまりブラウザの表示領域いっぱいにボックスモデルを形成することになります。
(実際にはブラウザが独自のCSSでbodyにマージンを付けていますのでわずかな空白ができます)
包含ブロックはボックスを作成した時に、自分自身が包含ブロックとなりその子孫要素にとっての包含ブロックとなるということで、親要素となる包含ブロックを形成しているのではありません。
また、widthやmarginなどのサイズの設定次第で包含ブロックとなる親要素を飛び出す(オーバーフローする)ことも可能です。
次の例では簡単なボックス生成要素と包含ブロックとなる要素の関係を表したものです。
サンプルページ
.p2内ではem要素がインラインボックスを作成しています。さらに、strong要素がインラインボックスを作成しています。em要素以外のテキスト部分は匿名インラインボックスと呼ばれる特殊なインラインボックスが作成されたことになります。
<body> <div id="div1"> <p class="p1">このテキストは最初の段落...</p> <p class="p2">このテキストは<em class="em1">最初から<strong class="strong1">2番目の</strong>段落です。</em> </p> </div> </body>
ボックスを生成する要素 | 包含ブロックを設定する要素 |
---|---|
html | 初期包含ブロック(UA依存) |
body | html |
div1 | body |
p1 | div1 |
p2 | div1 |
em1 | p2 |
strong1 | p2 |
幅の算出
初期値
display:blockの要素を作成しただけなら初期設定では包含ブロックいっぱいに広がります。ルート要素(html)が包含ブロックですからブラウザいっぱいに広がることになります。
幅の決定
幅の設定はwidthプロパティを使用します。非置換インライン要素、テーブル列と列グループを除く全要素に設定することができます。非置換インライン要素とはimg要素とinput要素textarea要素以外のインライン要素のことです。
widthを数値やパーセントで指定することで幅を決めることができます。
autoは特別な働きをします。それは他のプロパティに依存して大きさを調整します。
通常フローのブロック要素
‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ = 包含ブロックの幅
この計算式を見るとボックスモデルの計算式と同じです。つまり、地球側から見た、積み上げ方式の計算で算出できると思えてしまいますが、それは間違いです。
その証拠に、width.margin,padding,border-widthのすべてに値を設定することはできません。
通常の横書きのページで、すべてに値を設定した場合、margin-rightの値が無視されて調整値が入ります。
固定サイズの包含ブロックの場合は、宇宙の広さ(包含ブロックの幅)が先に決まっています。そのため、包含ブロック内に子要素のブロックを収めるには、width.margin,padding,border-width、いずれかの値をautoで調整する必要があります。
**包含ブロックからはみ出すことも可能ですが、width.margin,padding,border-widthのすべてに値を設定すると矛盾が生じます(もしも包含ブロックを飛び出すwidthのサイズを設定しておきながら、右側のマージンに正の値を指定することはおかしいですね)のでmargin-rightの値で調整しています。
ここが包含ブロックの考え方のポイントです。
widthがautoに設定される場合、それ以外のautoの値は0になります。つまり幅がいっぱいに広がります。
ただし、border-left-width、border-right-widthにはautoの値がありません。この値を省略した場合は初期値はmediumになります。また、paddingにもautoの値がありません。
つまり、幅の自動設定はwidthかmarginで調整するしかありません。
‘margin-left’と’margin-right’の両方の値が’auto’の場合には両方とも同じ値が入ります。それはつまりブロック要素の中央揃えに利用されます。
包含ブロック計算での例外
非置換インライン要素
img要素とinput要素textarea要素以外のインライン要素です。
‘width’プロパティとheightプロパティは使用できません。左右のマージンはインライン要素にも設定できますが上下のマージンはありません。
margin-leftまたはmargin-rightをautoにすると0になります。
置換インライン要素
margin-leftまたはmargin-rightをautoにすると0になります。
heightおよびwidthがautoの場合、imgなどの要素が固有の幅を持つ場合、その固有の幅がwidthの値となります。
フロートさせた場合
margin-leftまたはmargin-rightがautoの場合、値は0になります。
また、widthがautoの場合、値は内容に依存した幅になります。 そして、imgなどの置換要素の場合は置換要素自信(画像など)の幅になります。
固定配置の場合
固定配置要素の包含ブロックはビューポートの代わりに初期包含ブロックとなります。
固定配置要素の包含ブロック幅の算出は以下のようにします。
‘left’ + ‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ + ‘right’ = 包含ブロックの幅
leftとrightの指定は通常同時に行いませんが、両方指定した場合は以下のような扱いになります。
参考サンプル(下記リスト5の例)
- leftとwidthがautoでありrightに固定値を指定したならwidthは伸縮して調整されます。そしてleftのautoは無視されます。
- leftとrightがautoでありwidthに固定値を指定したなら、directionプロパティが通常位置のleftに設置されるltrであるなら、通常フローの位置にそのまま設定されます。
- widthとrightがautoでありleftに固定値を指定したならwidthは伸縮して調整されます。そしてrightのautoは無視されます。
- leftがautoでwidthとrightがautoでないなら、leftのautoは無視されます。
- widthがautoで、leftとrightがautoでないなら、widthが伸縮して幅が調整されます。
- rightがautoで、leftとwidthがautoでないなら、rightのautoは無視されます。
コメントを投稿するにはログインしてください。