要素の余白を決定するmarginとpadding
CSSには要素の余白を表すプロパティとしてmargin
とpadding
が用意されています。この二つのプロパティは、ボックス・モデルにおいて固有の範囲を持ち、専用の面積を作り出すことができます。
margin
は要素の外側の余白を表し、padding
は要素の内側の余白を表します。これらの間には、境界線であるborder
が挟まれています。この全てが、内容を配置するコンテンツ・ボックスを取り囲んでおり、寸法を広げると外側へ向かって拡大します。
本来、width
とheight
は純粋に内容が配置されるコンテンツ・ボックスの寸法を表します。これを理解しないままレイアウトを行うと、想定したサイズに合わなかった要素が、親要素からはみ出したり崩れた状態で表示されます。
また、垂直方向の余白は状況に応じて折りたたまれることがあるため、指定したmargin
が期待したように反映されないということが起こります。それを防ぐために、CSSの余白を正しく理解しておく必要があるのです。
内側の余白であるpaddingの正しい解釈
まずは、内側の余白を定義する「パディング」について見て行きましょう。padding
は、CSSのボックス・モデルを構成する区域のうち、パディング・ボックスの寸法を指定するプロパティです。
パディング・ボックスは、専有の面積を持つ固有の区域で、コンテンツ・ボックスとボーダー・ボックスの間に隣接しています。これはどういうことかと言うと、境界線の内側にあるため、ボックスの内側に属しているということです。例えば、凡庸な<div>
要素で囲んだテキストを配置した場合、パディングは<div>
の内部構造の一部です。
要素の内部に含まれている以上、padding
は外部環境の影響を受けません。例え内容が空の要素であっても、padding
を指定すれば折りたたまれずにそのまま表示されます。
以下の例は、要素のサイズ変更と余白の関係を可視化したものです。要素のwidth
やheight
の値を変更すると、ボックスの寸法が変化します。背景色はbackground-clip
の機能を使ってコンテンツ・ボックスのみに適用しているため、余白の部分は親要素に指定されている青色を透過します。
上記の例では、padding
の値を増加させると余白の寸法が外側へ向かって拡大します。これはbox-sizing
の値が既定値のcontent-box
になっているためです。この状態の要素は、標準モデルの計算値でレイアウトされます。この時、width
やheight
で示される寸法は、コンテンツ・ボックスの大きさを表します。
box-sizing
の値をborder-box
に変更すると、代替モデルでの表示に切り替わります。この状態の要素は、内部構造に含まれるpadding
やborder
を内側へ向かって拡大します。つまり、コンテツ・ボックスは圧迫され、幅や高さが足りない場合に押しつぶされて見えなくなります。
外側の余白であるmarginの正しい解釈
続いて、外側の余白を定義する「マージン」について見て行きましょう。margin
は、CSSのボックス・モデルを構成する区域のうち、マージン・ボックスの寸法を指定するプロパティです。
マージン・ボックスは、専有の面積を持つ固有の区域で、ボーダー・ボックスの外側を取り巻いています。これはどういうことかと言うと、境界線の外側にあるため、ボックスの外側に属しているということです。例えば、凡庸な<div>
要素で囲んだテキストを配置した場合、マージンは唯一外部環境に触れている部分です。
要素の外部環境に触れているということは、当然その影響を受ける可能性があるということです。例えば、値の異なる垂直方向のマージンがぶつかった場合に、最大値を持つ方が優先されて少ない値が吸収されます。この機能はマージンが相殺されることから、折りたたみ(collapsed)とも呼ばれます。
以下の例では、隣接する要素に指定されたマージンが相殺される様子を確認できます。ここでのしきい値は30px
です。それを下回る数値では、隣接するマージンに余白の寸法が吸収されます。
上記の例では、同じ階層に所属する要素同士の関係でしたが、親要素に対する子要素の挙動にも影響します。例えば、包含ボックスの直下にブロック要素を配置して、垂直方向のマージンを指定した場合、この余白は包含ボックスを貫通します。
次の例は、<div>
要素を入れ子にした状態で、子要素にmargin
を追加した場合の挙動です。本来であれば、上下左右の全方向にマージンが適用されて、包含ボックスの背景を映したいのですが、左右が適用される反面、上下方向のマージンは効いていないように見えます。しかし、隣接するボックスとの余白が広がります。これは親要素を貫通して外側の空間に影響を及ぼしていることを意味します。
この現象を回避するためには、一種の衝突材が必要になります。具体的に言うと、子要素のマージンとぶつかるような素材を親要素に置いてあげれば良いのです。一番簡単な方法としてはテキストを配置するだけで、それが衝突判定の材料になります。
上下のマージンが効かない場合の対処方
包含ボックスの中に配置した子要素の垂直方向のマージンが効かない場合、CSSを用いた解決方法は何らかのプロパティを親要素に追加することです。その効果があるものを見ていきましょう。
<div id="container">
<section>
<h1>何も指定しない</h1>
<div>
<div class="item">Item</div>
</div>
</section>
<section>
<h1>overflow: auto;</h1>
<div id="wrapper_overflow">
<div class="item">Item</div>
</div>
</section>
<section>
<h1>padding: 0.1px;</h1>
<div id="wrapper_padding">
<div class="item">Item</div>
</div>
</section>
<section>
<h1>border: 1px solid transparent;</h1>
<div id="wrapper_border">
<div class="item">Item</div>
</div>
</section>
</div>
#container {
overflow: auto;
padding: 0 1rem 1rem;
background-color: #eee;
}
#container > section {
overflow: auto;
margin: 1rem 0 0;
padding: 0 1rem 1rem;
background-color: #fff;
}
section > h1 {
margin: .5rem 0 0;
font-size: 1rem;
}
section > div {
background-color: #f09;
}
div > .item {
margin: 1rem;
background-color: #ffc;
}
#wrapper_overflow {
overflow: auto;
}
#wrapper_padding {
padding: 0.1px;
}
#wrapper_border {
border: 1px solid transparent;
}
overflowの効果
包含ボックスにoverflow
を追加すると、子要素のマージンが貫通しなくなります。その理由は既定値のvisible
にあります。
overflow
を省略した場合、ブラウザは既定値を適用します。この状態で表示された要素は、コンテンツ・エリアからはみ出す内容を、そのまま表示します。つまり、要素の寸法からはみ出したコンテンツをボックスの外へ露出させます。
その結果、親要素のボックスを貫通したマージンが隣接する要素を押して余白が生まれたのです。あくまで、マージンが効いていないのではなく、親要素のoverflow
が正しく機能した結果です。
これを回避するためには、overflow
の値をvisible
以外のものにします。ここではauto
を採用していますが、これにより子要素のマージンも包含ボックスの中に含まれるようになります。
paddingの効果
padding
は、パディングの解説で示した通りボックスの内部構造の一部です。そのため、包含ボックスに有効な寸法のパディングを指定すれば、それが子要素のマージンの衝突材料になります。
パディングを省略した場合に既定値で0
になっている要素、あるいはCSSリセットで対象となる要素のパディングを0
にしている場合は、パディング自体が存在しないことになり、衝突せずにすり抜けが発生します。
ここで注意点があります。例え人間が認識できないほどの小さい数値であっても、厳密なレイアウトには影響を及ぼします。padding
は負の数値を扱えないため、これを有効にするには0
以上の寸法を指定する必要があります。
borderの効果
border
を指定すると、当然ながら衝突判定となってマージンの貫通を食い止めます。ですが、境界線に太さを指定するということは、もちろん見た目やレイアウトに影響します。
サンプルでは境界線の色を透明にしていますが、ボーダーの寸法がボックスのサイズに影響を与えています。その装飾がコンテンツに必要なものであれば良いのですが、単にマージンの貫通を避ける目的のためだけに使うことは推奨できません。
border
は、省略された時に既定値でborder-style
のnone
が採用されるため、この問題が起こります。ただし、先に示した通り代替案が複数用意されているので、無理に使う必要はないでしょう。
CSSリファレンス一覧
-
CSSって何?初心者が最初に学ぶべき基礎知識
初めてCSSに触れる方はこちらから読み進めて下さい。CSSの役割やブラウザとの関係など、初心者にも分かりやすいように基礎知識を解説します。
入門編 -
CSSの書き方を詳しく解説!基本的な型とルールを覚えよう
CSSの書き方には一定の法則があるので、慣れてしまえば迷うことはないでしょう。まずは基本的な文法をマスターしましょう。
初級編 -
CSSの特徴をしっかりと把握しよう
CSSにはいくつかの特徴があります。これらを早いうちに理解しておくと、ウェブ制作の作業効率が格段に上がります。
初級編 -
CSSファイルの作り方
CSSファイルは誰でも簡単に作成できます。特別な技術やソフトウェアは必要ありません。
初級編 -
CSSセレクタの一覧表
スタイルの適用対象となる要素を選択するセレクタの一覧表です。詳しい書き方やサンプルコードを掲載しています。
学習編 -
CSSで使える単位の一覧表
プロパティの指定に用いる単位の解説です。CSSで使用できる単位の一覧表を掲載しています。
学習編 -
ボックス・モデルの完全解説
CSSの基礎が固まってきたらボックス・モデルについて学びましょう。これを理解するとCSSの操作が格段にやりやすくなります。
中級編 -
ブロックレベルとインラインレベルを理解する
CSSのブロックレベルとインラインレベルの特性について解説します。これらの扱いはHTMLからボックス・モデルに引き継がれました。
中級編 -
CSSの余白を表すmarginとpaddingを正しく理解する
要素の余白を表すmarginとpaddingについて正しい知識を身に着けましょう。
中級編 -
idとclassを上手く使い分ける
idセレクタとclassセレクタの使い分け方を詳しく解説します。
中級編 -
全称セレクタ(ユニバーサル・セレクタ)の解説
全ての要素のプロパティを一括で操作する全称セレクタについて解説します。
中級編 -
リストのデザインをマスターする
リストのデザインに関するCSSのテクニックを多数紹介します。入れ子、多段式、横並びを全て解決します。
応用編 -
フレックス・ボックスを理解する
横並びのレイアウトやレスポンシブデザインに対応するフレックス・ボックス(Flexible Box)について解説します。
応用編 -
グリッド・レイアウトを理解する
複数の行と列を作成して多次元のレイアウトを行うグリッド・レイアウトについて解説します。
応用編