CSSを学び始めたばかりのころ、marginプロパティとpaddingプロパティに混乱しました。そっくりに感じただけでなく、同じ表示になっているとさえ思えました。
このチュートリアルでは、CSSにおけるmarginとpaddingの違いと、Webページでの余白への影響について解説します。さらにマージンの相殺(margin collapsing)やレスポンシブWebサイトの作成でさまざまな単位を使った場合の効果について説明し、最後にCSSのmarginと paddingを使って実現できるレイアウトテクニックをいくつか紹介します。
ボックスモデル
CSSは、要素を四角形のボックスで表します。四角形のサイズは次の要素で指定します。
- Content
- Padding
- Border
- Margin
- Content(内容)
- Padding(パディング)
- Border(ボーダー)
- Margin(マージン)
コンテンツは要素の中心に配置されます。コンテンツをpaddingで囲み、paddingをborderで囲みます。marginはさらに外側に位置します。
図にすると分かりやすいでしょうか。
paddingプロパティはコンテンツの外側でborderの内側の領域です。つまりpaddingはコンテンツとborderの間の余白を調整します。paddingはWebページに配置される要素のサイズに影響しますが、別の要素との距離には影響しません。
要素間の余白の調整はmarginプロパティを使います。marginは要素のサイズには影響しません。
Webページにあるすべてのボックスのサイズは使われている「ボックスモデル」で決まります。ボックスモデルには次の2種類があります。
- W3C仕様のボックスモデル
- 伝統的なボックスモデル
W3C仕様のボックスモデルでは、paddingとborderを除いたコンテンツの幅が要素の幅とされます。要素に設定されたサイズにpaddingとborderが追加されるので、ページのレイアウトが予想外の表示になる場合があります。
たとえば幅と高さが200px、全方向のパディングが10px、ボーダーが2pxのボックスについて考えてみてください。ブラウザーはこのボックスをシンプルに200pxとは解釈しません。むしろブラウザーはこのボックスの表示に必要な横方向の領域を224pxと算出します。つまり200(幅)+2(左border)+10(左padding)+10(右padding)+2(右border)=224pxというわけです。この要素が正四角形であるとすると、高さも224pxと算出されます。
一方、伝統的なボックスモデルでは、コンテンツ、padding、borderの合計が要素の幅と解釈されます。ボックスの幅を200pxとすると、ブラウザーはpaddingとborderを含めてボックスの表示に必要な幅を200pxと算出します。結果が予測しやすく扱いが簡単です。
すべてのブラウザーは、デフォルトでW3C仕様のボックスモデルを採用しています。box-sizingプロパティの値をcontent-box(W3C仕様ボックスモデル)かborder-box(伝統的ボックスモデル)のどちらかに設定することで、ボックスモデルを明示的に指定できます。伝統的なボックスモデルはより直感的で、多くのWeb開発者に好まれています。
伝統的なボックスモデルは以下のようにbox-sizingプロパティを設定することで指定できます。
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
百聞は一見にしかずです。Guy Routledgeのインタラクティブなデモがおもしろいので実験してみてください。
marginとpaddingの設定
プロパティpadding-top、padding-right、padding-bottom、padding-leftで要素の4方向に適用されるpaddingを調整できます。また、paddingのショートハンドプロパティを使った指定も可能です。
- padding値を1つだけ記述すると、4方向のpaddingがその値に設定される
/* all four sides */ padding: 10px;
- padding値を2つ記述すると、最初の値が上下、2番目の値が左右のpaddingに設定される
/* vertical | horizontal */ padding: 2em 4em;
- padding値を3つ記述すると、最初の値が上、2番目の値が左右、3番目の値が下のpaddingに設定される
/* top | horizontal | bottom */ padding: 1em 20px 2em;
- padding値を4つ記述すると、記述順に上、右、下、左方向のpaddingに設定される
/* top | right | bottom | left */ padding: 10px 10% 2em 15%;
次のデモのオレンジの背景色は要素のコンテンツ領域で、borderとコンテンツの間の白い領域は各要素に設定したpaddingです。
padding同様、プロパティmargin-top、margin-right、margin-bottom、margin-leftで要素の4方向に適用するmarginを調整できます。marginのショートハンドプロパティを使った要素の4方向のmargin指定も可能です。
/* all four sides */
margin: 10px;
/* vertical | horizontal */
margin: 2em 4em;
/* top | horizontal | bottom */
margin: 2em auto 2em;
/* top | right | bottom | left */
margin: 10px 10% 2em 15%;
注意したいこと
適切な単位を使う
フォントサイズや画面幅の変更に適応できないため、marginとpaddingの指定で「絶対単位」は使わないでください。
たとえば要素の幅を50%に設定し、そこに15pxのmarginを適用したとします。1200pxの場合、幅は600px、marginは15pxになります。769pxの場合、幅は384pxになりますがmarginは15pxのままです。
このケースでは要素の幅が36%変動しましたがmarginは最初の値のままです。ほとんどの場合は大きな問題にはならないでしょうが、要素のmarginを%で設定したほうが、あらゆる画面サイズに対してWebページのレイアウトを調整できます。marginとpaddingに適用された値で余白のバランスが変化せず全体の均整がとれます。
同様に、Webページのテキストにpaddingを設定するには、対応する要素のフォントサイズに比例することが望まれますが、絶対単位では実現できません。emで指定すればフォントサイズに比例してpaddingが拡大・縮小します。デモで確認してください。
ブラウザーがさまざまな単位のmarginとpadding値を計算する方法
ブラウザーによるmarginとpaddingの計算結果は、利用する単位で異なります。
marginとpaddingを%で指定すると親要素の幅を基準に計算します。つまりpaddingを5%に指定すると、親要素の幅が100pxのとき5px、1000pxのとき50pxとなります。上下方向のpadding値も親要素の幅を基準に計算します。
単位をemで指定すると、marginとpaddingの値は要素のフォントサイズに基づいて計算します。先ほどのCodePenのデモで、下3つのテキスト要素のpaddingは1emに設定しています。しかし3つのテキスト要素はフォントサイズが異なるので、paddingの計算値も異なっています。
ビューポートを基準とする4つの単位vw、vh、vmin、vmaxもあります。これらの単位ではmarginとpaddingの値はビューポートを基準に計算します。たとえば5vwにpaddingを指定すると、ビューポート幅が500pxのときは25pxになります。同じビューポート幅に対してpaddingを10vwとすると値は50pxになります。単位は知らないと損!CSSのvh/vwの使いこなしでレスポンシブなサイト制作が捗るを参考にしてください。
初心者は単位の機能を知ることで、HTML要素のpaddingやmarginが親要素のサイズやフォントサイズ、ビューポートのなにを基準にして変化するのか理解する近道となります。レイアウトを思いのままに調整する力がつくでしょう。
マージンの相殺
さらに理解して欲しいのは「マージンの相殺」です。特定の状況で、2つの要素の上方向と下方向のmarginが折りたたまれて1つのmarginになることがあります。この現象をマージンの相殺(margin collapsing)といいます。
隣接して並んだ2つの要素があるとします。1番目の要素のmargin-bottomプロパティが40px、2番目の要素のmargin-topプロパティが25pxに設定しても2つの要素間のmarginが65pxにはなりません。大きいほうのmargin値の40pxになります。
同様に、親要素と最初または最後の子要素との間でもmarginの相殺が起こります。子要素・親要素のmarginを分離するborderやpadding、インラインコンテンツが存在しない場合に起こります。この場合、親要素にpaddingやborderの設定がないと、子要素のmarginが親要素からはみ出て表示されます。
こうした状況を避けるには、親要素と子要素のmarginに境界を設定します。borderかpaddingのどちらかで実現できます。次のデモは親要素にborderやpaddingを追加してmarginのはみ出しを回避しています。
ネガティブマージンが関係している場合、相殺された結果のmargin値はポジティブマージンの最大値とネガティブマージンの最小値の和になります。
詳しくはAdam RobertsのCollapsing Margins(マージンの相殺)が参考になります。
marginとpaddingの興味深いテクニック
CSSのmarginとpaddingプロパティでレイアウトの課題を解決できる場合があります。以下に例をいくつか示します。
親要素内での要素の中央揃え
marginで、親要素のブロックレベルで横方向の中央揃えが簡単にできます。margin-leftプロパティとmargin-rightプロパティの値をautoに設定すればOKです。
.child {
margin: 10px auto;
}
次のデモで親要素の例を3つ確認できます。最初の例では親要素をブロックレベルに、2番目の例ではインラインブロックに、3番目の例では右にフロートしたブロックレベルに設定しています。すべての例で子要素が横方向の中央揃えになっています。
画像のアスペクト比を維持
Webページの画像のアスペクト比が固定されていないことがよくあります。すべての画像のアスペクト比を統一して表示するには、CSSのpaddingが便利です。
親要素のheightを0に設定し、padding-topプロパティを希望のアスペクト比の%で設定します。
たとえば、padding: 56.25% 0 0 0に設定すると16:9のアスペクト比が実現できます。ここでは(9/16)*100の計算結果として56.25という値を取得しました。この方法を使って任意のアスペクト比に対応するpaddingのパーセンテージを算出できます。
このテクニックはHow to Maintain Image Aspect Ratios in Responsive Web Design(srcsetでレスポンシブイメージを作成する方法)を参照してください。
marginとpaddingのちょっと高度でおもしろい用法に、Webページで 親要素に設定された条件下での全幅コンテナ(full-width containers inside limited width parents)の作成やモジュールで下方向の余白を統一(adding consistent spacing at the bottom of different modules)があります。CSSのmarginとpaddingをマスターする次のステップとして取り組めます。
最後に
CSSの初心者に、このチュートリアルがmarginとpaddingの違いを理解する助けになれば幸いです。さらにショートハンドシンタックスや適切な単位を使えばmarginとpaddingの設定が楽になるでしょう。最後のセクションではレイアウトに関連したmarginとpaddingの興味深い用法と、ステップアップのための追加情報を紹介しました。
本記事はDave Maxwell、Adrian Sandu、Panayiotis Velisarakosが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。
(原文:How to Set CSS Margins and Padding (And Cool Layout Tricks))
[翻訳:新岡祐佳子/編集:Livit]