🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

2回答

1318閲覧

ネガティブマージンが理解出来ません!

murabito

総合スコア108

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2021/03/03 15:45

編集2021/03/04 04:44

質問

例えば、以下のデモのように子要素の上下左右にpaddingと同じ幅のネガティブマージンを指定してあげると、要素が膨らんで(???)、親要素全体がリンク領域になりますが、どういう仕組みでこのようになるのかが理解出来ません。

margin-topとmargin-leftにネガティブマージンを指定した場合に、左上に移動するのは感覚的に理解できるのですが、それらに加えて、margin-bottomとmargin-rightにもネガティブマージンを加えると、全体が上下左右に膨らむような挙動をするのが、なぜなのか理解出来ません。

どなたかどういう仕組みでこのようになっているか、ご存知の方がおりましたら、ご教示頂ければ幸いです。仕様が書かれている参照すべき対象ドキュメントを教えていただけるだけでも助かります!

結果

イメージ説明

HTML

<div class="parent"> <a href="#" class="child">Link</a> </div>

CSS

.parent { padding: 25px; background-color: #cccccc; width: 300px; display: inline-block; } .child { display: block; background: red; padding: 25px; margin-top: -25px; margin-left: -25px; margin-right: -25px; margin-bottom: -25px; }

#Lhankor_Mhyさんの回答を元に以下を追加

width of containing block(.parent)

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
0 + 0 + 25px + 300px + 25px + 0 + 0 = 350px

仮に.childを包含ブロックとした場合(.childは包含ブロックではないですよね?)

-25px + 0 + 25px + 300px + 25px + 0 + -25px = 300px

親は350pxである一方、子は300pxとなるので、なぜ、親要素と子要素の高さ、幅が一致するのかが、包含ブロックの幅の計算式によって、決まるのかが分からない。

仮に.childのマージンを取り除いた場合

0 + 0 + 25px + 300px + 25px + 0 + 0 = 350px

350pxになり親要素の幅と一致するが以下のように親と幅が一致しなくなる。

イメージ説明

追記2

以下は.childからpaddingを外した場合です。

HTML

<div class="parent"> <a href="#" class="child">Link</a> </div>

CSS

.parent { padding: 0 25px 0 25px; background-color: #cccccc; width: 300px; display: inline-block; } .child { display: block; background: red; margin-left: -25px; margin-right: -25px; }

結果

イメージ説明

Lhankor_Mhyさんの回答に当てはめてみる

.child の包含ブロックは、.parent のコンテンツ領域辺
.child の包含ブロックの幅は、300px

OK。

等式に当てはめると、-25+0+25+w+25+0+-25=300
つまり、.child のwidthは300px

追記2の例をもとに当てはめると、-25+0+0+w+0+0+-25=300
.child のwidth(計算式のwの部分)は350pxになる。

両パディングを合わせると、親要素のパディング領域辺の幅の350pxと一致する。

.childにはpaddingは追記2の例ではないので、親要素のパディング領域辺の幅の350pxと一致する。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/03/03 21:16

>仕様が書かれている参照すべき対象ドキュメント 自身では探されてないのでしょうか。
murabito

2021/03/04 02:34

探し方が悪いのだと思いますが、仕様書のmarginのセクションはみたのですが、ネガティブの値も指定できるよくらいしか書かれておらず、ネガティブマージンについては詳しく書かれていませんでした。
m.ts10806

2021/03/04 02:36

まあ確かに 設定可能な値のうちでしかないですからね。
guest

回答2

0

ベストアンサー

こんにちは。

仕様が書かれている参照すべき対象ドキュメントを教えていただけるだけでも助かります!

仕様はこちらです。
10.3.3 Block-level, non-replaced elements in normal flow | Visual formatting model details
10.6.3 Block-level non-replaced elements in normal flow when 'overflow' computes to 'visible' | Visual formatting model details

仕様に書かれたこの等式を見れば理解できるのではないでしょうか。
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

たとえば、width:1000pxの包含ブロック(containing block)で、両マージンに-100px、両パディングに100px、ボーダーなし、とすると、上記の等式は、
-100 + 0 + 100 + width + 100 + 0 + -100 = 1000となりますので、widthは1000pxになります。両パディングまで背景色が塗られますから、背景色のある領域は1200pxになります。

投稿2021/03/04 01:38

Lhankor_Mhy

総合スコア36930

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

murabito

2021/03/04 02:51

包含ブロックは質問の例でいうところの`.parent`のことであっていますでしょうか?これが、`.child`のネガティブマージンに影響するということでしょうか?
murabito

2021/03/04 03:28

包含ブロックは先日調べたので理解はしているつもりなのですが、包含ブロックのwidth(width of containing block)とその子要素のネガティブマージンによる膨らみの関連性がいまいちわかりません。。。
Lhankor_Mhy

2021/03/04 03:35 編集

回答に挙げた等式の意味が分からない、みたいな話ですか? 簡単な足し算なので、よく読んでご理解していただくほかないと思います。 もし、 murabitoさんが学生さんならば、方程式を学校で習うまではちょっと難しいかもです。
murabito

2021/03/04 03:45 編集

`-100 + 0 + 100 + width + 100 + 0 + -100 = 1000`はわかります。「両パディングまで背景色が塗られますから、背景色のある領域は1200pxになります。」もわかります。
murabito

2021/03/04 03:46 編集

その上で子要素(包含ブロックではない)にネガティブマージンを質問の例のように指定すると、親要素(包含ブロック)の高さ、幅と一致するようになる仕組みが理解出来ていないということです。
Lhankor_Mhy

2021/03/04 03:56

包含ブロックの幅は、100%-50px。 ここまではいいですか?
murabito

2021/03/04 03:59

質問文に理解している範囲を追記いたしました!
Lhankor_Mhy

2021/03/04 04:04

ああ、追記了解しました。 .child の包含ブロックは、.parent のコンテンツ領域辺 .child の包含ブロックの幅は、300-25-25=250px 等式に当てはめると、-25+0+25+w+25+0+-25=250 つまり、.child のwidthは250px 両パディングを合わせると、親要素のパディング領域辺の幅の300pxと一致する。 以上で、ご理解できますか?
murabito

2021/03/04 04:15 編集

「300-25-25=250px」のところですが、なぜ、25を2回引いたのですか?「.child の包含ブロック」の「包含ブロック」は.parentであるという前提はあっていますか?この25は.parentのpaddingの25でしょうか?`width of containing block`の計算式ではpaddingは引くのではなく足すものだと思うのですが、なぜ、マイナスをしているのかがわかりません。「.child の包含ブロックの幅」は「300+25+25=350px」ではないのですか?
murabito

2021/03/04 04:14 編集

「.parent のコンテンツ領域辺」の「コンテンツ領域辺」はbox modelのwidth、つまり、padding, borderを含まない領域を指しているのでしょうか?それとも、width of containing blockの計算式で導き出されたwidthを指していますでしょうか?後者の場合、300px + 25px + 25pxで350pxになるかと思います。前者の場合であれば、単純にwidthが300pxなので300pxになるかと思います。
Lhankor_Mhy

2021/03/04 04:31 編集

ついでに.parentについても書いておきますか。 .parent の親要素が width:1000px; margin:0; padding:0;と仮定すると、 .parent の包含ブロックの幅は、1000px 等式に当てはめると、0+0+25+300+25+0+0=1000 となり矛盾する。 この場合、回答で示した仕様にある"over-constrained"(定義しすぎ)の状態となり、margin-rightが無視される。 0+0+25+300+25+0+margin-right=1000 となり、margin-right: 650pxとして解決される。 以上です。
Lhankor_Mhy

2021/03/04 04:15

コメント行き違いました。拝読します。
Lhankor_Mhy

2021/03/04 04:17

ああ、ご指摘はそのとおりでした。訂正します。 .child の包含ブロックは、.parent のコンテンツ領域辺 .child の包含ブロックの幅は、300px 等式に当てはめると、-25+0+25+w+25+0+-25=300 つまり、.child のwidthは300px 両パディングを合わせると、親要素のパディング領域辺の幅の350pxと一致する。 大変失礼しました。
murabito

2021/03/04 04:22

「.child の包含ブロックの幅は、300px 等式に当てはめると、-25+0+25+w+25+0+-25=300」
murabito

2021/03/04 04:25 編集

「多くの場合、包含ブロックは要素から見て直近のブロックレベルの祖先のコンテンツ領域」とリンクしていただいたMDNの記事にも書いてあるのですが、.child の包含ブロックは.parentで大前提、合っていますよね?その前提が正しければ、「-25+0+25+w+25+0+-25=300」をみると、.parentにはネガティブマージンはついていないので、この式にはならないと思うのです。この式は.child自体を包含ブロックとした場合の式ではないでしょうか?
Lhankor_Mhy

2021/03/04 04:25

はい、そのとおりです。 これは、.childについての式です。
Lhankor_Mhy

2021/03/04 04:26

おっと、編集が入りましたか。 いいえ、この式は.child自体を包含ブロックとした場合の式ではありません。
murabito

2021/03/04 04:28 編集

> .child の包含ブロックの幅は、300px とあるのですが、.childの包含ブロックは.parentであり、その場合の幅は例の計算式によると350pxになりますよね?(0 + 0 + 25 + 300 + 25 + 0 + 0)
Lhankor_Mhy

2021/03/04 04:29

いいえ、.child の包含ブロックは、.parentのコンテンツ領域ですから、300pxです。 間違えやすいのですが、.parentのパディング領域ではありません。 (ちなみに、絶対配置をするとパディング領域になるのでご注意を)
murabito

2021/03/04 04:32

なるほど。包含ブロックは(多くの場合)親要素ではなく、それのコンテンツ領域ということだったのですね。見落としていました。それをふまえて、いただいた回答を読み返してみます。ありがとうございます!
murabito

2021/03/04 04:42

追記2を質問にくわえたのですが、これで認識は合っていますでしょうか?
Lhankor_Mhy

2021/03/04 04:54

はい、ご理解の通りだと思います。 途中で誤ったことを書いて混乱させてしまいました。すみませんでした。
murabito

2021/03/04 07:29

とても助かりました!ありがとうございまいした!
guest

0

marginは余白ですよね?

「プラス方向なら要素を押し込む」
「マイナス方向なら要素を引っ張る」

このように捉えると、
「上下左右から引っ張られると伸びそう」ということが感覚的に分かるかもです。
CSSって力学だったんですね。
※ものすごく乱暴な説明ではありますが。

参考URL MDN margin
https://developer.mozilla.org/ja/docs/Web/CSS/margin

以下蛇足です。
要素の幅と高さを固定してやると挙動が変わりそうな予感がします。

投稿2021/03/04 01:31

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問