margin相殺のさらに詳しい説明と3つの解決法

画像offset-of-margin010

この記事は「margin相殺とは?」の続きの記事になります。

前回の記事はこちら↓

こんにちは、tanakaです。

今回は、
margin相殺について「さらに一歩踏み込んだ説明」をします。

どのような説明かと言いますと

 1:margin相殺は「条件さえ揃えば」どの状態でも起こる。
 2:margin相殺3つのパターン
 3:解決法

この3つのです。

文字化けします

<コピー、ペーストすると文字化けします>

このページのコードをコピー、ペーストすると
「ダブルクオーテーションなどの一部が文字化け」
して正常に機能しなくなります。

十分ご注意ください。

margin相殺おさらい

まずは少し「margin相殺のおさらい」してみましょう。

margin相殺とは、
「display: block」が「タテ方向」に並んだ時「marginを調節する」機能のことでした。

それでは「margin相殺」では、
具体的にどのようなことが起きているのでしょうか?

<margin相殺で起きること>

下のような2つの「display:block」があったとします。
そして「紫色部分はmargin」です。

画像offset-of-margin006

今からこの2つを上下に置きます。

どうなるでしょうか?

↓普通は上下に置くと、こうなるとおもいますよね?

画像offset-of-margin007

ところが!

↓実際はこうなります!

画像offset-of-margin008

下にあった100pxは相殺され消えてしまいました。

これが「margin相殺で起きること」です。

なぜこんな機能が?

それでは、なぜ「margin相殺」のような機能があるのでしょうか?

おそらく「均等に並べるため」でしょう。

<なぜmargin相殺があるのか>

下のような「diaplay:block」を3つ並べておくとします。

画像offsetmargin05

margin相殺があると、
それぞれの間が同じ高さになります。

画像offset-of-margin001

おそらく

このような調節のために「margin相殺」があるのでしょう。

困った事態を引き起こす「margin相殺」

とはいえmargin相殺は、
いつもいい感じにしてくれる訳ではありません。

むしろ

多くの困った事態を引き起こします。

その困った事態を見ていきましょう。

margin相殺は「条件さえ揃えば」どの状態でも起こる。

margin相殺は「条件さえ揃えば」どの状態でも起こります。

その条件とは、

 1:「display:block」
 2:タテに並んでいる
 3:marginが2つ以上接触している

この条件です。

実際のページ作成では、
この3条件がどう当てはまるのか具体的にみていきましょう。

ページ作成で起こり得るmargin相殺

ページ作成で実際に起こり得る「margin相殺」は、
以下の3つだと考えられます。

 1:上下
 2:親要素と子要素
 3:自らの上下(htmlの中身がカラの場合のみ発生)

それぞれ説明します。

1:上下

上下は、
2つの「display:block」が上下に置かれたパターンです。

margin相殺といえば
この形を思う人が多いのではないでしょうか。

marginを追加しても数値通りにならないのは、
大体このパターンのせいです。

<margin相殺の上下>

margin相殺の上下の例です。

「display:block」が上下に2つあったとします。

画像offsetmargin03

それを並べておくと以下のようになります。

画像offsetmargin04

片方が相殺されて消え、大きい値の方が残ります。

2:親要素と子要素

親要素と子要素は、
とても難しいmargin相殺です。

親要素と子要素が「display:block」で
親要素と子要素のmarginが上下で接触すると

margin相殺を起こします。

おそらく文面ではよく分からないと思われるので
1つ例を挙げます。

<margin相殺の親要素、子要素>

説明するためサンプルを用意しました。

緑色が親要素です。

その中に黒色の子要素があります。

画像offset-of-margin007

今から「黒色の子要素」へmarginを入れます。

入れるmarginは全周です。(margin: 50px;)

普通は、
全周へmarginを入れるのだから

下のようになると思いますよね?

画像offset-of-margin008

ところが実際は、
下のようになります。

画像offset-of-margin010

どうしてこんな事になったのでしょうか?

それは

親要素のmargin
子要素のmargin

それらが「上下で接触」したからです。

説明するとこうなります。

画像offset-of-margin009

しかも

子要素のmarginがいつの間にか親要素のmarginへとすり替わっています。

そもそも親要素のmarginは0です。

 親要素 margin: 0;
 子要素 margin: 50px;

この2つがmargin相殺を起こしています。

どうしてこうなったのでしょうか?

その答えは「私には分からない」です。

こういう仕様だったとしか言いようがありません。(申し訳ない)

<重なり合うなら全てmargin相殺>

先ほどは、親要素と子要素のmargin相殺を見てきました。

次は、
数を増やしてみます。

先ほどの「親要素と子要素」を上下に2個置きます。

そして、
その間はどうなるのかを見ていきます。
(上のmargin2つ、下のmargin2つ「合計4つが接触」します)

結果から言いますと、
「接触するところは全てmargin相殺」が起こります。

画像offsetmargin01-01

その中央では上下4つのmarginが「margin相殺」を起こしています。

とにかく

 1:「display:block」
 2:上下
 3:接触している

この3条件が当てはまれば「margin相殺」するようです。

(注意)「子要素のmarginが親要素扱いになっている」
これは「わたしの考え」であって確証はありません

3:自らの上下

次は「自らの上下」を見ていきましょう。

自らの上下は、
かなり特殊なパターンです。

html要素に何も入っていないと
「自身の上下のmarginが接触」して
margin相殺を起こします。

html

<h1></h1> ←中身がない

css

h1 {
 margin-top: 50px; ←これと
 margin-bottom :100px; ←これが、接触して「margin相殺」を起こす
}

中身のないhtml要素を作ることは、
ほぼ無いので気にすることはありません。

しかし

「このようなこともあったなー」
ぐらいで覚えておいてください。

解決法

「それではどうすればいいの?」

そうお思いでしょう。

方法はたくさんあります。

ですが

「display:blockではmarginを使わない」

これが一番わかりやすいのでは無いでしょうか。

しかし

marginを使わないとなると「代わりの何か」が必要です。

そこで

marginの「代わりになる何かを3つ紹介」します。

marginの代用3選

marginの代わりになる方法を3つ紹介します。

 1:transform: translateX(10px) translateY(10px)
 2:border-color: transparent
 3:フレックスボックス

それぞれ詳しく説明します。

1:transform: translate

1つ目は「transform: translate」です。

transform: translateは、
要素を簡単に移動させることができます。

px単位で指定でき、微調整にも使える
とても便利なプロパティです。

しかし欠点として

「自分には分かるけど、他の人には分かりにくい」
ということが挙げられます。

ページ作成を自分一人で完結するなら問題はありません。

他の人が見るのなら
コードは分かりやすく作る必要があります。

transform: translateがたくさん入っていると、
とても分かりにくいコードとなります。

とはいえ

transform: translateは、
marginの代わりとしては十分使えます。

2:border-color: transparent

2つ目は「border」です。

「border?」

と思われるかもしれません。

borderは、
border-colorに「transparent」を使うと線が透明になります。

border-color: transparent;
border-style: solid;
border-bottom-width: 30px;

background-clip: content-box;

* {
  border: 0px solid transparent;
}

透明になったborderは、
marginの代わりに使えると思いませんか?

しかも

borderは、
margin相殺などの問題を起こしません。

しかし欠点として

「borderの線が使えない」が考えられます。

marginの代わりにborderを使ってしまったので、
もうborderは使えません。

border線が必要になった場合
borderとは別の手段を考えなければなりません。

とはいえ

border-color: transparentは、
marginの代わりとして十分使えます。

<Googleガイドラインとtransparent>

ここの記事は、
「transparent」は、Googleガイドラインに引っかかるのでは?
という内容です。

基本的にホームページは、Google検索で上位に表示されることを目指して作ります。

それでは、どのようなページが上位に表示されるのでしょうか?

それは「Googleガイドラインに沿って作られたページ」が上位に表示されます。

ここでGoogleガイドラインの一部を紹介します。

1:ユーザーの利便性を最優先にしてページ作成する
2:ユーザーをだまさない
3:検索順位で不正行為をしない
4:自分のウェブサイトを独自性、価値、魅力あるようにする

Googleガイドラインには、このようなことが書かれています。

そこで問題になってくるのが「transparent」です。

「transparent」は、透明にする値です。

そしてGoogleガイドライン「2:ユーザーをだまさない」には、「小さすぎるテキスト」「隠しテキスト」などがあります。

「transparent」は「隠しテキスト」として認識されるのでは?
という心配が出てきます。

今回「transparent」を使うのは、あくまで「border」です。

ですが、「transparent」が入っているというだけでガイドライン違反なるという可能性も捨てきれません。

ということで「transparent」は、使わない方が良いかもしれませんね。

本当のところは全く分かりませんけど。

<Googleガイドラインとは>

Googleは、より良いページ作りの指標「Googleガイドライン」を公表しています。

「Googleガイドライン」には、このようなことが書かれています。

1:ユーザーの利便性を最優先にしてページ作成する
2:ユーザーをだまさない
3:検索順位で不正行為をしない
4:自分のウェブサイトを独自性、価値、魅力あるようにする

ページ作りの参考になるので、一度見ることをおすすめします。

「Googleガイドライン」の詳しい内容は、

「ウェブマスター向けガイドライン」 の下の方「品質に関するガイドライン」の辺りです。

3:フレックスボックス

3つ目は「フレックスボックス」です。

全体のスペースを「display:block」で大きくを取り、

その中へコンテンツを「フレックスボックス」で並べていく。

これは一番の良い方法だといえます。

「display:block」は連結させるだけなので
「margin」も使いません。

これといった欠点がないため「かなりおすすめの方法」です。

まとめ

<margin相殺とは>

margin相殺とは、
「display: block」がタテ方向に並んだ時「marginを調節する」機能のこと。

<margin相殺3つのパターン>

 1:上下
 2:親要素と子要素
 3:自らの上下(htmlの中身がカラの場合のみ発生)

margin相殺は、3つのパターンに分けられます。

<3つの解決法>

margin相殺の解決法としては、
そもそも「display:blockではmarginを使わない」ことです。

しかし

marginを使わないとなると
それに代わる方法が必要になります。

その方法を3つ挙げます。

 1:transform: translateX(10px) translateY(10px)
 2:marginの代わりにborderを使う
 3:フレックスボックス

2のborderの説明。

border-color: transparent;
border-style: solid;
border-bottom-width: 30px;

background-clip: content-box;

* {
  border: 0px solid transparent;
}

以上、
margin相殺のさらに詳しい説明と3つの解決法
の話でした。

ありがとうございました。

タイトルとURLをコピーしました