CSSの負のマージンはどのように機能し、なぜ(margin-top:-5!= margin-bottom:5)なのですか?


108

垂直配置要素の一般的なトリックは、次のCSSを使用することです。

.item {
    position:absolute;
    top:50%;
    margin-top:-8px; /* half of height */
    height: 16px;
}

Chromeのようにメトリックビューで表示すると、次のようになります。

ここに画像の説明を入力してください

ただし、要素の上にカーソルを置いたときに表示される視覚的なマージンはありません。つまり、マージンは境界の「外側」にあり、視覚化できます。しかし、負のマージンは表示されません。彼らはどのように見え、それが違うのは何ですか?

なぜmargin-top:-8px 同じでないのmargin-bottom:8pxですか?

つまり、負のマージンはどのように機能し、その背後にある直感は何ですか。彼らはどうやってmargin-top < 0アイテムを「盛り上げる」(の場合)?

回答:


89

負のマージンはcssで有効であり、それらの(準拠)動作の理解は主にボックスモデルとマージンの縮小に基づいています。特定のシナリオはより複雑ですが、仕様を検討すれば、多くの一般的な間違いを回避できます。

たとえば、サンプルコードのレンダリングは、絶対配置された非置換要素の高さとマージンの計算で説明されているように、css仕様に基づいて行われます

グラフィック表現を作成する場合、おそらく次のようなものを使用します(縮尺どおりではありません)。

負の上マージン

マージンボックス失った8px上には、しかし、これは影響しません内容&パディングボックスを。要素は完全に配置されているため、要素を8ピクセル上に移動しても、レイアウトがさらに乱されることはありません。常にそうであるとは限らない静的インフローコンテンツを使用します。

ボーナス:

このような記事とは対照的に仕様を読むことが先方法であることを納得させる必要があります。)?要素を垂直方向に中央揃えしようとしているようですが、なぜ設定margin-top:-8px;せずに設定する必要があるのmargin-top:-50%;ですか?

まあ、CSSでの垂直方向の中央揃えは、本来あるべきものより難しいですまたは下のマージンを%で設定する場合、値は常に包含ブロックのに対するパーセンテージとして計算されます。これはかなり一般的な落とし穴であり、癖はw3 docosの外ではめったに説明されません


84

私はそれを視覚的に説明しようとします:

/**
 * explaining margins
 */

body {
  padding: 3em 15%
}

.parent {
  width: 50%;
  width: 400px;
  height: 400px;
  position: relative;
  background: lemonchiffon;
}

.parent:before,
.parent:after {
  position: absolute;
  content: "";
}

.parent:before {
  top: 0;
  bottom: 0;
  left: 50%;
  border-left: dashed 1px #ccc;
}

.parent:after {
  left: 0;
  right: 0;
  top: 50%;
  border-top: dashed 1px #ccc;
}

.child {
  width: 200px;
  height: 200px;
  background: rgba(200, 198, 133, .5);
}

ul {
  padding: 5% 20px;
}

.set1 .child {
  margin: 0;
  position: relative;
}

.set2 .child {
  margin-left: 75px;
  position: relative;
}

.set3 .child {
  margin-left: -75px;
  position: relative;
}


/* position absolute */

.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}

.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}

.set6 .child {
  top: 50%; /* level from which margin-top starts 
	- downwards, in the case of a positive margin
	- upwards, in the case of a negative margin	
	*/
  left: 50%; /* level from which margin-left starts 
	- towards right, in the case of a positive margin
	- towards left, in the case of a negative margin	
	*/
  margin: -75px;
  position: absolute;
}
<!-- content to be placed inside <body>…</body> -->
<h2><code>position: relative;</code></h2>
<h3>Set 1</h3>
<div class="parent set 1">
  <div class="child">
    <pre>
.set1 .child {
  margin: 0;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 2</h3>
<div class="parent set2">
  <div class="child">
    <pre>
.set2 .child {
  margin-left: 75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 3</h3>
<div class="parent set3">
  <div class="child">
    <pre>
.set3 .child {
  margin-left: -75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h2><code>position: absolute;</code></h2>

<h3>Set 4</h3>
<div class="parent set4">
  <div class="child">
    <pre>
.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 5</h3>
<div class="parent set5">
  <div class="child">
    <pre>
.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 6</h3>
<div class="parent set6">
  <div class="child">
    <pre>
.set6 .child {
  top: 50%;
  left: 50%;
  margin: -75px;
  position: absolute;
}
		</pre>
  </div>
</div>


33

余白は、パディングが要素の内側の間隔であるのと同様に、要素の外側の間隔です。

下余白を設定すると、現在のブロックの下の距離がわかります。負の上部マージンを設定すると、ブロックの上に負の間隔が必要になります。負の間隔はそれ自体が混乱を招く概念かもしれませんが、正の上部マージンがコンテンツを押し下げるのと同じように、負の上部マージンはコンテンツを引き上げます。


2
+1私はあなたの答えが好きです。それは言葉を注入することによって改善することができるonsetoffset。多くの人が(ポジティブ)を意味するときは常にoffsetネガティブ)という単語を使用しているのは事実です。回答を更新すると、このメッセージは自動的に破棄されます。乾杯!onset
arttronics 2012

1
どうmargin-bottom: -8px;ですか?なぜmargin-bottom:-8px同じではないのmargin-top:-8pxですか?
Rick

27

margin-topが-8pxの場合、マージンが0の場合よりも8px高くなります。

マージン下部が8pxの場合、マージンの下にあるものは、マージンが0の場合よりもさらに8px下になります。


1
私は単に物事をシンプルにしようと努めていましたが、私は同意します、これはおそらく私の答えの中で最悪のものです!
リッチブラッドショー

2
かなりいい答えだと思います。私たちの半分がそれを取得しないという非常に技術的な答えの使用はありません。
Number945

1
どうmargin-bottom: -8px;ですか?なぜmargin-bottom:-8px同じではないのmargin-top:-8pxですか?
Rick

22

ここですでに良い点が述べられていますが、マージンのレンダリングがブラウザーによってどのように行われるかについては多くの情報がありますが、その理由はまだ完全には答えられていません。

「margin-top:-8pxがmargin-bottom:8pxと同じではないのはなぜですか?」

私たちが尋ねることもできます:

正の下部マージンが前の要素を「バンプアップ」しないのに対し、正の上部マージンは後続の要素を「バンプダウン」しないのはなぜですか?

つまり、マージンの適用側によってマージンのレンダリングに違いがあることがわかります。上部(左)のマージンは下部(および右)のマージンとは異なります。

ブラウザによってスタイルが適用される方法を(簡略化して)見たときに、物事はより明確になります。要素は、左上隅から始まり、ビューポートのトップダウンでレンダリングされます(今のところ、垂直レンダリングに固執しましょう。水平のものは同じように扱われます)。

次のhtmlを検討してください。

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

コード内でのそれらの位置と同様に、これらの3つのボックスはブラウザで「上から下」に重ねて表示されます(物事を簡単に保つため、ここorderではcss3 'flex-box'モジュールのプロパティは考慮しません)。したがって、スタイルがボックス3に適用されるときは常に、(ボックス1と2の)先行する要素の位置はすでに決定されており、レンダリング速度のためにこれ以上変更するべきではありません。

ここで、ボックス3の-10pxの上余白を想像してください。先行するすべての要素を上にシフトしてスペースを集めるのではなく、ブラウザーはボックス3を上に押し上げるだけなので、zインデックスの上部(または下部)にレンダリングされます。 )先行する要素。パフォーマンスに問題がなくても、すべての要素を上に移動すると、要素がビューポートから外れる可能性があるため、現在のスクロール位置を変更して、すべてを再び表示できるようにする必要があります。

同じことがボックス3の下部マージンにも適用されます。負と正の両方です。既に評価された要素に影響を与える代わりに、次の要素の新しい「開始点」のみが決定されます。したがって、下マージンを正に設定すると、次の要素が押し下げられます。負の値はそれらを押し上げます。


最良の答え。これは「なぜ」を説明しているのに対して、他の回答は「方法」のみを説明しています。
アミールホセインアフマディ

1
この答えは、なぜより良いのかを理解するのに役立ちました。ありがとう@schellmax
iRamesh

3

絶対配置を使用し、上位のパーセンテージを指定したので、margin-topのみが.itemオブジェクトの場所に影響します。代わりに、bottom:50%を使用して配置した場合、中央に配置するにはmargin-bottom -8pxが必要であり、margin-topは効果がありません。

マージンは、要素の配置に関連して、要素の境界に影響を与えます。これは、絶対的に、または隣接する要素に対して相対的です。そのマージンが、それが置かれている要素の基礎であると想像してください。通常は同じサイズですが、4つのエッジのいずれかまたはすべてを大きくしたり小さくしたりできます。

CSSはブラウザに、要素の上部をページの50%の位置にマージンを配置するように指示します。ただし、すべての要素が単一のピクセルではないため、ブラウザは、ページの50%の位置に配置するために、要素のどの部分を認識する必要があります。要素の上部を揃えるには、上部マージンを使用します。デフォルトでは、これは要素の上部と一致していますが、CSSを使用して変更できます。

あなたの場合、上位50%の場合、要素の上部がページの中央から始まります。負の上部マージンを適用することにより、ブラウザーは、要素の上部から8pxのポイント(つまり、その中央を横切る線)を50%の位置として使用します。

下部に正のマージンを適用すると、ブラウザが下部を要素自体から離して配置するために使用する線が延長され、要素とその下の隣接要素との間にギャップが生じます。ボトム。


+1。理にかなっています... 視覚化を完了するために視覚的な手がかりでそれを増強することは素晴らしいでしょう。
PhD

3

この質問はうまく答えられたのでしょうか。CSSマージンのしくみと、なぜそれがマージントップ:-5なのか。margin-bottom:5 ;?と同じではありませんか?

マージンは、要素の周囲からの距離です。margin-topは、「...要素の「ボックス」の上部「側」から測定した周囲からの距離であり、マージン-下部は「ボックス」の下部「側」からの距離であることを示しています。次にmargin-top:5; 上部の「側面」周囲に関係し、その場合は-5。上部の「側面」から近づくものはすべて、要素の上部の「側面」と5オーバーラップでき、margin-bottom:5; 要素の下部「側面」と周囲の距離が5であることを意味します。

基本的には、フロートされた要素などの影響を受けますhttp : //www.w3.org/TR/CSS2/box.html#margin-properties

http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

私は修正される立場にあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.