Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. CSS中級編 - marginとpadding

marginとpadding

みなさまどうもこんにちは。

続きまして余白を決定する『margin』プロパティと『padding』プロパティについて解説していきます。

marginプロパティは『外側の余白(隙間)』、
paddingプロパティは『内側の余白(隙間)
を指定します。

外側と内側という違いがありますね。ちなみにmarginは『マージン』、paddingは『パディング』と読みます。

余白を決定するだけのプロパティなので
「何も難しくないんじゃね?解説いらなくね?」
と思ってしまう方がいらっしゃるかもしれませんがこれがなかなかややこしい項目となっています。かなり妙なレンダリングを行うプロパティです。というわけでちょっと学習するのに時間がかかってしまうかもしれませんが頑張っていきましょう。

ではまず記述方法ですが以下のように普通にプロパティと値を記述すればOKです。

p {
    margin: 20px;
    padding: 20px;
}

『margin』の値に取る単位は主に『px』か『auto』となります。他の単位もありますがあまり使われません。

『padding』で使用する単位に関してはほぼ『px』のみとなります。他には『%』などがたまに使われますね。

プロパティに『margin』や『padding』と記述した場合は以下のように半角スペースを挟んで値を記述することで四方をまとめて指定できます。

p {
    margin: 20px;               /* 上下左右の外側の余白を20pxで指定 */
    margin: 20px 10px;          /* 上下が20px,左右は10pxで外側の余白を指定 */
    margin: 20px 10px 5px;      /* 上が20px,左右が10px,下が5pxで外側の余白を指定 */
    margin: 20px 10px 5px 3px;  /* 上が20px,右が10px,下が5px,左が3pxで外側の余白を指定 */

    padding: 20px;              /* 上下左右の内側の余白を20pxで指定 */
    padding: 20px 10px;         /* 上下が20px,左右は10pxで内側の余白を指定 */
    padding: 20px 10px 5px;     /* 上が20px,左右が10px,下が5pxで内側の余白を指定 */
    padding: 20px 10px 5px 3px; /* 上が20px,右が10px,下が5px,左が3pxで内側の余白を指定 */
}

記述する値を省略できることに注意してください。例えば『margin: 20px 10px;』と記述すると『上下が20px、左右は10pxで外側の余白を指定』したことになります。この省略形は良く使用されるので覚えておきましょう。

四方全てを指定する場合は『上から時計回りに上、右、下、左と指定していく』と覚えてしまいましょう。まあちょっと迷ったらその都度ネット検索すれば良いだけなのでそのうち自然と覚えられます。

そして『margin-top』、『padding-top』などのように四方を個別に指定することもできます。

以下が記述例です。

p {
    margin-top: 20px;       /* 上の外側の余白を20pxで指定 */
    margin-right: 20px;     /* 右の外側の余白を20pxで指定 */
    margin-bottom: 20px;    /* 下の外側の余白を20pxで指定 */
    margin-left: 20px;      /* 左の外側の余白を20pxで指定 */

    padding-top: 20px:      /* 上の内側の余白を20pxで指定 */
    padding-right: 20px;    /* 右の内側の余白を20pxで指定 */
    padding-bottom: 20px;   /* 下の内側の余白を20pxで指定 */
    padding-left: 20px;     /* 左の内側の余白を20pxで指定 */
}

注意点ですが、『margin』や『padding』とだけ記述して値をまとめて設定すると四方を個別に設定したことと同義になります。ですので以下のようにすると値が上書きされてしまうので注意してください。

p {
    margin-top: 20px;
    margin-right: 20px;
    margin-bottom: 20px;
    margin-left: 20px;

    margin: 200px; /* このように後述するとすべて200pxに上書きされます */

    /* これらを後述したことと同義です */
    /*
    margin-top: 200px;
    margin-right: 200px;
    margin-bottom: 200px;
    margin-left: 200px;
    */

    padding-top: 20px:
    padding-right: 20px;
    padding-bottom: 20px;
    padding-left: 20px;

    padding: 200px; /* paddingもこのように後述するとすべて200pxに上書きされます */

    /* これらを後述したことと同義です */
    /*
    padding-top: 200px;
    padding-right: 200px;
    padding-bottom: 200px;
    padding-left: 200px;
    */
}

div {
    /* 逆にこのパターンはmargin-leftのみ20pxとして上書きされます */
    margin: 100px;
    margin-left: 20px;
}

つまり『margin』というプロパティは四方をまとめて記述するためにあるプロパティで、その実態は『margin-top』『margin-right』『margin-bottom』『margin-left』の4つというわけです。『padding』も同じことが言えますね。

さて、ではmarginプロパティからちょっとややこしい振る舞いをみていきましょう。

marginプロパティは外側の余白を決定するプロパティです。

以下のHTMLソースで挙動をみてみましょう。

<div style="width: 200px; height: 200px; background-color: red; margin-left: 20px;"></div>

大きさを200px、背景色を赤色に指定したdiv要素です。marginプロパティで左側の余白を20pxとして取るように指定しました。

実際にレンダリングさせるとこのようになります。
(注 ブラウザのデフォルトのレンダリングでbody要素に多少の隙間が生成されているため検証用に『body { margin: 0; padding: 0;}』と指定し隙間を消しています。)

サンプルをみてみる。

記述どおり左側の余白が20px空いてるようにみえますね。念のためサンプルページで開発ツールを開いて要素を検証してみてください。右側あたりにある『Computed』の項目で確認することができます。以下の画像のところですね。
※開発ツールを忘れちゃった方はこちらへどぞ

問題ないかと思います。

ではdiv要素はブロックレベル要素となっていますので今度はインラインレベル要素のspan要素にmarginを設定してみましょう。
※ブロックレベル要素とインラインレベル要素ってなんだったっけという方はこちら

<span style="background-color: silver; margin: 100px;">ここはspan要素だよ。</span>

さてこれをレンダリングさせてみると

サンプルをみてみる。

サンプルページで開発ツールを開いて確認してみてください。『Computed』で確認するとmarginが効いているようになっていますがなんだか視覚的に上下の隙間が空いていませんね。

ここがミソです。ブラウザの計算上ではmarginに値が設定されていますが、実際のレンダリングではインラインレベル要素は上下のマージンは反映されません。左右はOKです。インラインレベル要素は左右のマージンしか効かない、と覚えておきましょう。

ちなみにこちらの記事で解説したimg要素などの『置換要素』に関してはブロックレベル要素と同じように全てのマージンを指定することができます。こちらも覚えておいてください。

さて、先ほどちょっと出てきた『auto』という値を使ってみましょう。

まず値に『auto』と取る場合は必ず『width』(横幅)を指定するようにしてください。『width』を指定しないで『auto』ととった場合は値はすべて『0』となります。

というわけで先ほどのソースをこのように書きなおしました。

<div style="width: 200px; height: 200px; background-color: red; margin: 0 auto;"></div>

marginプロパティに『0 auto』と記述しているので上下が0、左右がautoとしてレンダリングされます。

さて、これをブラウザで表示してみましょう。こうなります。

サンプルをみてみる。

なんと左右中央揃えになりました。

この『auto』という値は横幅を自動算出してくれる値です。自動算出の方法は状況によって変更され、上記のように左右に『auto』という値をとった場合は左右均等分の余白が自動算出され、結果左右中央揃えとして表示されます。

では今度は左側だけ『auto』にしてみましょう。

<div style="width: 200px; height: 200px; background-color: red; margin-left: auto;"></div>

これをブラウザで表示させるとこうなります。

サンプルをみてみる。

右寄せになりました。これは自分の要素の幅を算出したあとの残りの余白がautoとして計算されるので結果右寄せになっています。

日本語や英語の場合は左から右へと読み進む言語なのでブラウザも基本的なレイアウトは左詰めになります。ですので日本国内のウェブサイトでは『margin-right: auto』のみ記述する場合はほぼありません。

注意点ですが、autoという値は左右のみ指定することができます。上下に対してautoという値を記述しても何も変化はありません。そしてインラインレベル要素やインラインブロック要素に関してはautoという値をいれても自動算出されません。autoを使って中央寄せにしたり右寄せにできるのはブロックレベル要素やテーブル要素となります。インラインレベル要素を位置寄せする場合には親要素に『text-align』プロパティを記述します。間違いやすいので覚えておきましょう。
※『text-align』プロパティを忘れちゃった方はこちらへどうぞ

あ、先ほど説明したとおり『width』の値も同時に記述しておくのを忘れないようにしてくださいね。

ちなみにこのように

<div style="width: 200px; height: 200px; background-color: red;"></div>
<div style="width: 200px; height: 200px; background-color: aqua; margin-left: auto;"></div>

サンプルをみてみる。

左寄せの要素と右寄せの要素を2つ並べたところでdiv要素はブロックレベル要素なので開いたスペースに次の要素が収まるわけではありません。ブロックレベル要素は上下に改行が入ります。この改行をなくすには先の記事で紹介するfloatプロパティやpositionプロパティが必要です。

さて続いてmarginのややこしい点ですが、お互いのマージンの相殺処理が行われます。

以下のように記述してみましょう。

<div style="width: 200px; height: 200px; background-color: red; margin-bottom: 40px;"></div>
<div style="width: 200px; height: 200px; background-color: aqua; margin-top: 60px;"></div>

上の要素に下のマージンを40px、下の要素に上のマージン60pxを指定しています。

普通に考えると40px+60pxで計100pxの余白が生まれそうですね。これをブラウザでレンダリングさせるとあら不思議。

サンプルをみてみる。

なんか余白がちっちゃいです。開発ツールで検証してみてください。開発ツール上で要素にカーソルを当てるとマージン部分に色がつきますのでそれで確認できます。

どうやら60pxしか空いていないようです。これがマージンの相殺です。

お互いに向い合って同じ方向にマージンを指定した場合は数値が大きいほうが反映されるという不思議仕様です。

しかもマージンの相殺が起こるのは上下のみとなっています。以下のように左右のマージンでは相殺は起こりません。ここもややこしいです。以下に左右のマージンを40pxで設定したインラインレベル要素を用意したので確認してみましょう。

<span style="margin: 0 40px; background-color: red">ここはspan要素だよ</span><span style="margin: 0 40px; background-color: aqua">ここはspan要素だよ</span>

サンプルをみてみる。

このように左右のマージンは相殺されず普通に反映されます。ここは初心者の方がつまずきやすいところなので気をつけましょう。

さらにマージンの相殺には先があったりします。なんと親子関係でも相殺が起こるのです。

以下の記述をみてください。

<div style="width: 200px; height: 200px; background-color: red; margin-top: 40px;">
    <p style="width: 100px; height: 100px; background-color: yellow; margin-top: 60px;"></p>
</div>

親要素であるdiv要素に上のマージンを40px、子要素であるp要素の上のマージンを60px指定しています。

さて、こちらは親要素の上のマージンが40px、子要素の上のマージンが60pxで親要素と子要素の間に隙間ができそうですがそういったレンダリングになりません。以下を確認してみてください。

サンプルをみてみる。

こんな感じで親子関係でもマージン同士で相殺が起こり数値の大きいほうが反映されます。子要素のマージンが親要素を突き抜けてしまうようなイメージですね。ちなみにこちらも左右のマージンの場合は相殺が行われません。

さらにこの親子関係の相殺は親要素のCSSプロパティに境界線を設定する『border』プロパティや次に解説する『padding』プロパティなどが記述されていた場合相殺が起こりません。以下を確認してみてください。

<div style="width: 200px; height: 200px; background-color: red; margin-top: 40px;">
    <p style="width: 100px; height: 100px; background-color: yellow; margin-top: 60px;">何も指定してない要素です!</p>
</div>

<div style="width: 200px; height: 200px; background-color: red; margin-top: 40px; border: solid 1px black">
    <p style="width: 100px; height: 100px; background-color: yellow; margin-top: 60px;">borderプロパティを指定している要素です!</p>
</div>

<div style="width: 200px; height: 200px; background-color: red; margin-top: 40px; padding: 1px;">
    <p style="width: 100px; height: 100px; background-color: yellow; margin-top: 60px;">paddingプロパティを指定している要素です!</p>
</div>

サンプルをみてみる。

ここまで来ると何だかどうでも良くなってきますね。

実際、marginは余白を決定しているだけのプロパティです。思い通りの余白にならない場合は他のCSSプロパティの影響を受けているか相殺が起こってるのではと考え、その際は他のCSSプロパティの値をいじったりせずにmarginの値だけを調整すれば思い通りの形で実装できるかと思います。

何となく
「ああ、そういえばmarginプロパティは相殺が起こったり他のCSSプロパティの影響をうけるんだっけか。」
と覚えておけば大丈夫です。

marginの値はマイナスの値を取ることができます。マイナスの値を取ると余白がマイナスになる、つまり要素と要素を重ねることができます。

<div style="width: 200px; height: 200px; background-color: red;"></div>
<div style="width: 200px; height: 200px; background-color: aqua; margin-top: -60px; margin-left: 20px;"></div>

このソースをレンダリングさせるとこうなります。

サンプルをみてみる。

バッチリ重なっていますね。ちょっと型から外れたレイアウトを設計したい場合によく使われるテクニックです。覚えておきましょう。

かなり長くなりましたが続きましてpaddingの解説へ進みます。こちらはmarginほど複雑ではないですのでご安心ください。相殺なんかもありません。

paddingというのはmarginが外側の余白を指定するプロパティなのに対して内側の余白を指定できるプロパティです。

では早速記述してレンダリングしてみましょう。

<div style="width: 200px; height: 200px; background-color: aqua; padding: 50px;">ここはdiv要素だよ。paddingを50pxに指定しているよ</div>

さてこちらをレンダリングしてみると

サンプルをみてみる。

ふむ、無事内側の余白が反映されているようですね。でもよく見ると少しおかしいです。widthとheightに200pxと指定しているのにも関わらずちょっとp要素が大きい気がしなくもないです。

サンプルページで要素を検証してみましょう。要素にカーソルを合わせたあと右クリックして『要素を検証』という項目を選択するとその要素の大きさが吹き出しででてきます。

調べてみると縦横が300pxとしてレンダリングされているようです。やはり大きくなってますね。これは要素の大きさが決定される際はwidthの値やheigntの値などで算出した元々の大きさに、さらにpaddingの値が合計されてレンダリングされるからです。

つまりこの場合だと
縦幅はheightの200pxに上下のpadding 50pxが加算され計300px、
横幅はwidthの200pxに左右のpadding 50pxが加算され計300px
として横300px、縦300pxのボックスとしてレンダリングされています。

要素の大きさはpaddingの値が加算されてレンダリングされる、と覚えておいてください。

あと注目すべきは背景色です。上記の要素は『 background-color: aqua』と設定しているので水色の背景になっています。paddingで追加された50pxの領域もどうやらそのまま水色の背景になっているようです。

上記のサンプルで確認した通り、paddingで追加された領域は背景色の設定をそのまま引き継ぎます。これは『background-image』プロパティなどで背景画像を指定したときも同じです。

では続いてブロックレベル要素ではなくインラインレベル要素にpaddingを設定してみましょう。

<div style="background-color: aqua;"><span style="padding: 100px; background-color: purple; color: white;">ここはspan要素だよ。paddingを100pxに設定しているよ</span></div>

さてこれをレンダリングさせてみるとこうなります。

サンプルをみてみる。

paddingが上下左右共に問題なく設定されているようにみえますが何だか変ですね。これはどういうことになっちゃってるかというと子要素のインラインレベル要素のspan要素が親のp要素を突き破って表示されている状態です。

heightプロパティに値を設定していない場合はブロックレベル要素の縦の大きさはその内包している子要素の大きさを算出し自動で決定されるのですが、子要素のインラインレベル要素にpaddingを設定してもそのpaddingの大きさは親要素の大きさを決定付ける数値として加算されず子要素が親要素を突き破った形でレンダリングされます

ちょっと頭がこんがらがってきてしまうかと思いますが、あくまでも子要素がインラインレベル要素だったときのみ、この突き破りの現象が起こります。以下のようにブロックレベル要素であるdiv要素の中に同じdiv要素が入れ子になっていた場合はちゃんとpaddingの大きさが加算された数値が親要素の高さになります。

<div style="background-color: aqua;">
    <div style="width: 200px; padding: 100px; background-color: purple; color: white;">ここはdiv要素だよ。paddingを100pxに設定しているよ</div>
</div>

サンプルをみてみる。

そしてimg要素などの置換要素ならば親要素に子要素のpaddingの大きさが加算されてレンダリングされます。marginの時のように置換要素だけは特殊なレンダリングになりますので注意してください。

<div style="background-color: aqua;">
    <img src="/css-intermediate/img/04_01.jpg" style="width: 200px; height: auto; padding: 100px;">
</div> 

サンプルをみてみる。

実際の実装の際は置換要素以外のインラインレベル要素にpaddingを設定することはあまりないパターンですが、こちらも何となく覚えておきましょう。

これらのmarginやpaddingのレンダリングは『包含ブロック』という仕様が大きく関わってきます。包含ブロックとはその要素に対しブロックボックスを形成できる最も近い祖先要素の領域の事を指し、ブラウザはこの包含ブロックを元に子孫要素の表示位置を決定しています。

包含ブロックの話はちょっと難しい項目なので当記事では割愛しますが、参考書などでたまに出てきますので『包含ブロックとはその要素の配置位置が決定される祖先要素の領域のことである』ということだけは覚えておくと良いかもしれません。

以上でmarginとpaddingの説明を終わります。かなりながーくなってしまったので大変だったかと思います。

というわけで次の記事ではこのmarginとpaddingの超まとめをしたいと思います。疲れてしまったら続きは明日にしてしまって今日はゆっくり休んじゃってください。

( ´・ω・)つ旦 オチャデモドゾー

ではまたお会いしましょう。

この記事は桜舞が執筆致しました。

著者が愛する小型哺乳類

桜舞 春人 Sakurama Haruto

ISDN時代から様々なコンテンツを制作しているちょっと髪の毛が心配な東京在住のプログラマー。生粋のロングスリーパーで、10時間以上睡眠を取らないと基本的に体調が悪い。好きなだけ寝れる生活を送るのが夢。ゲームとスポーツと音楽が大好き。誰か髪の毛を分けて下さい。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。