为什么负边距无法生效?

47

若一个元素的 margin-left: -10px 边界超出其父元素的边界,为什么 margin-right: -10px 不会出现同样的情况呢?

示例

div {
  background: red;
  width: 200px;
  height: 100px;
}

p {
  background: blue;
  width: 100%;
}

.left {
  margin-left: -10px;
}

.right {
  margin-right: -10px;
}
<div>
  <p class="left">Hello</p>
</div>
<div>
  <p class="right">Hello</p>
</div>

4个回答

66

好消息是负边距确实有效

为了看到负边距的效果,请考虑以下代码片段:

.wrapper {
  outline: 1px solid blue;
  padding: 40px;
}

.content {
  outline: 1px solid red;
  background-color: #D8D8D8;
}

.content p {
  outline: 1px dotted blue;
  background-color: rgba(255, 255, 0, 0.3);
  margin: 0 0 0 0;
  text-align: justify;
}

.content p.lefty {
  margin-left: -20px;
}

.content p.righty {
  margin-right: -20px;
}
<div class="wrapper">
  <div class="content">
    <p>Lorem ipsum dolor sit amet, ...</p>
    <p class="lefty">Sed ipsum ante, dictum vel rhoncus id, ...</p>
    <p class="righty">Curabitur aliquam tristique mattis...</p>
  </div>
</div>

我给所有的

标签添加了outline,以显示内容框的范围。

第一个段落没有边距,我将其中一个段落向左偏移,另一个段落向右偏移。

如果您有足够的内容来填满段落的宽度(或者显示轮廓),则会看到文本框流出content框。您还可以从段落的outline中看到,文本确实向左和向右延伸。

但是,要看到右侧的效果,您需要足够的内容来填满段落的整个宽度,或者需要在子元素上设置背景颜色或轮廓。

如果您开始修复content的宽度和高度,则会看到其他效果,例如段落超出content

研究这个简单的代码结构可以说明CSS盒模型的许多方面,并且花一些时间进行研究非常有益。

Fiddle参考:http://jsfiddle.net/audetwebdesign/2SKjM/

如果您从中删除填充,则可能无法注意到右边距的移动,因为元素将向外扩展以填充父容器或页面宽度,具体取决于HTML/CSS的特定细节。

为什么我的示例没有显示效果!!!???

在您的示例中,您没有看到效果,是因为通过指定width:100%,您固定了

元素的宽度,这会使段落占据父容器的宽度(在您的示例中为200像素)。

如果您将宽度从100%更改为auto

p {
    background: blue;
    width: auto;
}

您会看到第二段落就像您期望的那样向右移动。

注意:轮廓线与边框 另外,请注意红框是由于outline而产生的,它将文本框包围在content内部,即使文本框超出父级(content)元素。 因此,outline框可以比相应元素的border框大得多。


我理解如果没有为元素指定确切的宽度,那么它将增加宽度以适应其他水平框属性。因此,在您的示例中,实际宽度将是 width_of_containment_element + 20,因此它将比包含元素的宽度更大。我只是想知道为什么 margin-left 会将元素从父元素中拉出来,但 margin-right 却不会。 - anton_byrna
在我的演示中,您可以看到第三个(最下面的)段落延伸到“content”div(灰色背景)的右侧。您的问题是否与原始fiddle / demo有关? - Marc Audet
请注意轮廓和边框范围的附加说明。 - Marc Audet
21
简而言之:width: auto - inorganik
谢谢指点。在我的情况下,有一个不合适的 .something > * { max-width: 100% } 破坏了负右边距,因此使用 .something > .special { max-width: initial } 覆盖它对我有用。 - JamesWilson
对于那些无法通过width:auto;实现成功的人,请尝试max-width: none - Maxim Pokrovskii

8

这是因为元素默认是从左到右布局,而不是从右到左。当您将 <p> 右浮动时,您可以看到相反的效果。

jsFiddle

.right {
    margin-right: -10px;
    float:right;
}

在左侧类中搞乱了他的 margin-left。 - John Riselvato
很简单,只需要这样修复:.right{ float: right } 那就可以了。 - Frederik Wordenskjold
我不太明白。我们有一个宽度填充包含元素的容器,还有一个负的右边距,应该将元素拉出来,我猜。 - anton_byrna

4

简单来说,只需更改此 CSS:

p {
    background: blue;
    width: 100%;
}

to:

p {
    background: blue;
    display: block;
}

这里是演示代码: http://jsfiddle.net/pVKNz/ 如果想要创建类似移动元素的效果,请使用以下CSS代码:
.left {
    margin-left: -10px;
    margin-right:10px;
}

.right {
    margin-right: -10px;
    margin-left:10px;
}

这不会移动元素,只会使段落的宽度比包含元素更大。而段落的 display:block 是没有意义的。 - anton_byrna

0
如果有人想给flex box设置负的margin-right,请考虑使用justify-content: space-between。
HTML
<div class="parent">
  <div class="child">  
  </div>
  <div class="child negative-margin">
  </div>
</div>

CSS

.parent {
  box-sizing: border-box;
  /* please concentrate on flex, space-between */
  display: flex;
  justify-content: space-between;
  background-color: blue;
  width: 500px;
  height: 200px;
  border: 5px solid red;
}
.child {
  box-sizing: border-box;
  display: inline-block;
  width: 50%;
  background-color: yellow;
}
.negative-margin {
  background-color: cyan;
  margin-right: -250px;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接