
実際には消えていません。正しいhtml, 正しいCSSを書いているのに「消えた」「効いていない」と勘違いしてしまうことがあります。そんなパターン紹介と対処法についてです。
margin消失と思ってしまうパターン
ご質問がありましので、そちらへの回答として。
上下marginを指定しているpをdivで囲って、divに背景色を付けたらpのmarginが無くなってしまいます。 コメント内容より一部抜粋
以下のようなことだろうと思います。
<div style="background: red; color: white;">
<p>これは文章です。</p>
</div>
上記は div要素 を親に、そして背景色が付けてあります。子要素に p要素 があり、このp要素には予めスタイルシート内で p {margin: 1em 0;} といった余白指定が記されている、という状態ですよね。
たぶん以下のような結果を期待する方が少なくないのでは、と思います。
Sample と入れておきました。上記は画像による結果予想サンプルです。ところが実際は以下のようになります(実物です)
これは文章です。
「えぇ?!marginどこ行っちゃったの?!」ってなる (∵`)
今どういう状態になっているかと言うと
薄い茶色がmarginです。親である div要素 と、子である p要素 の高さは同一です。感覚的に「p要素には上下に1emのmarginがあるのだから、div要素はその分高さが増すのでは?」と考えてしまいがちですが、実際はそういう理論ではありません。何故か。
margin というCSSプロパティは、親子間の距離を取るのではなく 兄弟間 の距離を取るのに用いられる。
marginというのは、親子の間に距離を取らないんです。サンプルのhtmlの場合、divは「親」であり、pは「子」なのですからこれは兄弟ではなく「親子関係」です。なので距離は取らない。
そして、p要素のmarginが親のdivによって滅せられたのか、といえばそうではありません。ちゃんと残っています。見た目上も作用上も div要素の方に上下marginが付いているような形になる。ということです。
他にもよくあるケースを紹介すると、例えばテンプレートなどでもよく起こります。
この状態からもう少しページ最上部とヘッダーの位置(welcome to my blogからナビゲーションまで)を広げようと思って、単純に margin-top 50px とかなんとか入れたとします。すると以下のような結果に。
隙間ができてしまいましたね。理屈は同じです。margin-top を指定した要素が、親に対して最初の子要素であった、ということです。そのため背景画像を有している親が引っ張られて(という表現が正しいか微妙ですが)下へ落ちてしまったように見える、と。まぁ実際落ちてるようなものだが正しくは「上にmarginがあるためこういう見た目になっちゃった」ですね。直接のmarginは親の方でなく子の方に付いているわけです。
All-about-us - FC2ブログテンプレート All-about-usテンプレートはレスポンシブウェブデザインです。
パソコン・タブレット・スマートフォン等全デバイス間共通でお使いいただけます。
「スマートフォン版の表示設定」を「無効にする」に設定してご利用ください。
設定ページ...
こういった一連の作用を marginの相殺 (margin offset, まーじん おふせっと) と言います。
「相殺」って難しい単語ですが英語のoffsetというのは「埋め合わせ」とか「上手いことゴニョゴニョする」とか「差分を埋める」とかそういった意味です。
marginの相殺、というと「上下に隣接した要素の接する部分にmarginが指定されている場合、大きい方が小さい方を吸収する」というのは良く知られたところですが、今回説明しているのも同じくmargin相殺の見落としがちな特徴です。上下margin相殺については以下の記事でチョロっと触れています。
旧投稿画面「自動改行」で書いた記事の修正 2021年9月現在、FC2ブログでは 管理画面 に「旧」と「新」の2つのデザインがあります。そして 投稿画面 も「旧」と「新」の2つがあります。旧投稿画面は旧デザイン管理画面でしか利用できません。
旧投稿画面の 改行の扱い『自動』 設定を利用して作成した記事の修正の仕方についてです。...
やってしまいがちな正しくない対処
結局のところ本質は「divに高さがほしい」というところにあるのですから、divにpaddingを付けたらどうなのよ、と。そもそも左右に余白が無いのも気になるし全部divの方で調整すれば良いじゃない、と単純に考えてしまった結果がこちら。divに padding: 1em つまり上下左右に 1em の内側余白(marginは外側余白です)を指定。
<div style="padding: 1em; background: red; color: white;">
<p>これは文章です。</p>
</div>
これは文章です。
あっ!良さげ!
でもよく見てくださいね。これ ↓ が理想なのですよね。
高さが出過ぎた。何故か。
padding 及び border プロパティは margin 相殺 を阻害します。
阻害という表現は良くないのかな。適切な表現が見つかりませんが、親要素に padding や border があると、marginの相殺が阻止されるんですね。という性質から、高さが出すぎてしまった理由とは「親のpaddingと子のmarginが合算されたため」です。
1em(親のpadding) + 1em(子のmargin) = 2em
という計算です(一方の辺なので、上下合わせると倍)
で、この特徴を知ることでそのまま対処法に活かすこともできます。
対処法いくつか
対処法はいくつか、というよりもいくつもあります。あまり専門的だったり特殊なケースは今回考えず、「FC2の記事作成で起こりそう」を想定して紹介します。そしてアプローチとしては「html構造自体を変える」というのも一つの方法に数えることができますが、それだと手間なので簡単にできるものに絞ります。
親に padding か border を 1px で指定する
親にmarginとborderがあるとmargin相殺が起こらないのですから、わずかな数値のいずれかを用いれば解消できます。
【padding: 1px 1em; を指定】(上下1px、左右1em)
<div style="padding: 1px 1em; background: red; color: white;">
<p>これは文章です。</p>
</div>
これは文章です。
【border: 1px solid transparent; を指定】(+ 左右1emのpadding)
<div style="border: 1px solid transparent; padding: 0 1em; background: red; color: white;">
<p>これは文章です。</p>
</div>
これは文章です。
いずれかで行うとしたら迷わず padding の方かな、と思います。上記サンプルのようについでに左右にもゆとりを、と思えば結局paddingを書かなきゃいけないわけなので、相殺阻止だけのborderはあまり合理的ではない。
1px の padding はちょっと書き足すだけですし、おなじみのプロパティだと思いますので初心者さんへはおすすめです。とはいえ例え1pxでも計算のずれは生じます。
親に display: flow-root を指定する
これが一番のおすすめですが、Internet Explorerは非対応 なので注意。まだ言わないとあかんのか「ieの場合は」とか (;`ー´)o
親の display プロパティの値に flow-root を指定。flow-rootに関する説明を始めるとまた1ページ2ページかかりますので、今回は難しいことは考えずに「こういうdisplay値があるんだ!」程度で。
<div style="display: flow-root; padding: 0 1em; background: red; color: white;">
<p>これは文章です。</p>
</div>
これは文章です。
こちらも書き足すだけで簡単ですけれど、耳慣れない・見慣れない値かもしれませんのでパッと思いつかない可能性はありますね。なので初心者さんはpaddingを使うと良いと思います。どうせ左右調整も要るのだし (ノ゚ェ゚)
他にも display: flex を用いる方法などもありますが、flexはtableと似た性質を持っていて、内容物(入れ子された子要素)をよく考えないといけないので、今回はおすすめから外します。
さいごに
marginの理論・概念は個人的にとっても難しいと思っていて、webデザインなどを学び始めて一番最初につまずくのがmarginじゃないかなぁ、という気がします。
There are no comments yet.