🎭

【HTML / CSS】あなたはmargin-top派? margin-bottom派?

2021/12/10に公開

あなたはmargin-top派? margin-bottom派?

こちらは「エンジニアリングに興味があるデザイナー、デザインに興味があるエンジニア Advent Calendar」10日目の記事です。

https://qiita.com/advent-calendar/2021/design-code

突然ですが皆さんは要素に上下方向のマージンをつける際に、margin-topmargin-bottomどちらを使用しますか?これは昔から論争されている議題であり、margin-top派の方もいれば、margin-bottom派の方もいるかと思います。この論争には「絶対にこっちを使え!」というような明確な答えはありません。(それぞれにメリット、デメリットがあるためです)
個人的な意見としては、margin-top派です。
この記事では、margin-top派の人間がmargin-topを使うべき理由を述べていく内容となっています。

なぜ、margin-topが良いのか?

結論から言うと、以下の理由で私はmargin-topが良いと考えます。

  • 要素は基本的に上から詰まっていくため、上の要素が下の要素の関心を持ちたくない。
  • first-childlast-childよりもサポートされている。
  • 隣接セレクタを使用すれば、よりいい感じに余白の指定ができる。

以下で詳しく説明していきます。

要素は基本的に上から詰まっていくため、上の要素が下の要素の関心を持ちたくない

表題のとおりなのですが、以下のように要素は基本的に上から詰まっていきます。

各領域の表示位置はその上の要素に依存しており、その下の領域には依存しておりません。
例えば「メイン」領域で考えると、「ヘッダー」領域の高さによって「メイン」の表示位置は決まりますが、「フッター」領域の高さには当然影響は受けません。つまり、下に存在する領域には関心を持つ必要がないのです。そう考えれば、マージンは依存される上の領域に対してつけるものだと言えるでしょう。

first-childはlast-childよりもサポートされている

liタグ同士の間隔をあけたい場合に、first-childmargin-topを使用して以下のように書くことができます。

index.html
<main>
    <section>
        <h1>タイトル</h1>
        <ul>
            <li>テキストテキストテキスト</li>
            <li>テキストテキストテキスト</li>
            <li>テキストテキストテキスト</li>
        </ul>
    </section>
    <section>
        <h1>タイトル</h1>
        <ul>
            <li>テキストテキストテキスト</li>
            <li>テキストテキストテキスト</li>
            <li>テキストテキストテキスト</li>
        </ul>
    </section>
</main>
style.css
main ul li {
    margin-top: 16px;
}

main ul li:first-child {
    margin-top: 0;
}

一方、last-childmargin-bottomを使用しても書くことができます。

style.css
main ul li {
    margin-bottom: 16px;
}

main ul li:last-child {
    margin-bottom: 0;
}

どちらのパターンでも、以下のような表示になります。

どちらでもできるのであれば、どっちでもいいのでは?と思う方がいるかと思いますが、ここでのmargin-topを使うべき理由は以下です。
これはIEに関してなのですが、擬似クラスであるfirst-childはIE7.0からサポートされているのに対し、last-childはIE9.0から対応されています。非推奨なものでない限り、幅広いバージョンでサポートされている方がありがたいですよね。

隣接セレクタを使用すれば、よりいい感じに余白の指定ができる

上の節で、first-childlast-childでマージンを打ち消すような書き方をしていました。特に問題はないのですが、一箇所だけ打ち消したりするようなやり方は正直ナンセンスだと私は思います。もっとスマートでいい感じに指定する方法があればそちらを採用したいところではあります。隣接セレクタを使用すればよりスマートにかけるようです。

先ほどの例と同様に、liタグ同士の間隔をあけたい場合を考えます。

index.html
<main>
    <section>
        <h1>タイトル</h1>
        <ul>
            <li class="text">テキストテキストテキスト</li>
            <li class="text">テキストテキストテキスト</li>
            <li class="text">テキストテキストテキスト</li>
        </ul>
    </section>
    <section>
        <h1>タイトル</h1>
        <ul>
            <li class="text">テキストテキストテキスト</li>
            <li class="text">テキストテキストテキスト</li>
            <li class="text">テキストテキストテキスト</li>
        </ul>
    </section>
</main>

隣接セレクタを使用すれば、CSSの指定としては以下のみです。

style.css
.text + .text {
    margin-top: 16px;
}

以下のように、異なる要素でも隣接セレクタは使用可能です。

style.css
h1 + ul {
    margin-top: 〇〇px;
}

ただし、隣接セレクタにmargin-bottomを使用するだけではうまく実現できません。

style.css
.text + .text {
    margin-bottom: 16px;
}

この場合は以下のような表示になります。

隣接セレクタにmargin-bottomで実現するためには、さらにCSSを付与して調整しなければなりません。したがって、隣接セレクタとmargin-topを使用した方がスマートにかけます。

最後に

margin-bottomを使うべき理由は割愛しますが、もちろんmargin-bottomを使うべき理由も存在すると思っています。あくまでも個人の意見ですので、この記事の内容に納得できない人もいるでしょう。それは悪いことではありません。「そんなやり方もあるんだ。」と様々なアプローチを自分の引き出しとして持つことが一番大事だと思っています。

参考

https://developer.mozilla.org/ja/docs/Web/CSS/:first-child

https://developer.mozilla.org/ja/docs/Web/CSS/:last-child

http://www.htmq.com/selector/adjacent.shtml

まとめ

この記事では、margin-top派の人間がmargin-topを使うべき理由を述べました。ここでは割愛しましたが、margin-bottomを使うべき理由ももちろん存在します。正直、最終的には自分の好みにはなるとも思っています。
もしあなたがプログラマー、もしくはコーダーであれば、何となく使うのではなく、明確な理由を持った上で実装していけばもっともっと成長できると思っています!

Discussion