【问题标题】:why float element works weird with negative margin?为什么浮动元素在负边距下很奇怪?
【发布时间】:2018-11-07 17:12:28
【问题描述】:

代码如下:

 * {
     margin:0;
     padding: 0;
    }
.first {
  float: right;
  width: 100%;
  height: 40px;
  background-color: black;
}

.second {
  float: right;
  background-color: red;
  width: 50%;
  height: 40px;
  margin-left: -50%;
}
<div class="first"></div>
<div class="second"></div>

由于第一个 div 的宽度是 100%,所以第一行没有第二个 div 的空间,我以为第二个 div 会显示在下一行,但第二个 div 消失了。然后我发现第二个div的offsetLeft值是视口的-50%,等于第二个div自己的宽度。所以第二个 div 与第一个 div 放在同一行,但它的 offsetLeft 是负数,所以我看不到它。为什么当浮动元素的边距为负时会如此奇怪?

【问题讨论】:

  • @Gerard 谢谢。我知道 clear 会消除第一个浮动 div 的影响。但我就是想不通如果我不使用 clear,为什么第二个 div 的 offsetLeft 值为负数。
  • 我认为第二个 div 没有放在第一个 div 的同一行。您的负左边距已从文档视图中删除了该元素。如果您检查并检查元素位置。
  • @Ashish 我检查了,我发现两个 div 的 offsetTop 值都是 0。所以我认为它们放在同一行。而第二个div的offsetLeft值是负数,这是我无法理解的。
  • 将第二个 div 设置为 width: 100%;

标签: css


【解决方案1】:

两个盒子都向右浮动,第二个盒子被放置在第一个盒子的左边

+------------------------------------------------+
|                                +-----++-------+|
|                                | red || black ||
|                                +-----++-------+|
|                                                |

在盒子上添加宽度后,第二个盒子被推到新的一行:

+------------------------------------------------+
|+----------------------------------------------+|
|| black                                        ||
|+----------------------------------------------+|
|                        +----------------------+|
|                        | red                  ||
|                        +----------------------+|
|                                                |

在第二个盒子上添加负左边距 >= 宽度时,第二个盒子被放置在第一个盒子旁边:

                       +------------------------------------------------+
+----------------------++----------------------------------------------+|
| red                  || black                                        ||
+----------------------++----------------------------------------------+|
                       |                                                |
                       |                                                |
                       |                                                |
                       |                                                |

对此行为的粗略解释是,当您添加一个等于/大于元素宽度的负边距时,它的表观宽度变为 0,并且浏览器会将其放在同一行上。

【讨论】:

  • precise rules for floats 规则 2 和 7 正式定义了这一点,但该文本有点让人难以阅读。
  • @Alohci 谢谢,但我没有在规则中找到负边距值的情况。
  • 谢谢,这些图表真的很有帮助。但是我在哪里可以找到最后一种情况记录的规则?
  • @T.T - 规则不描述负边距,它们描述左右外边缘,即边距边缘。当负边距等于边框框宽度时,边距框宽度为0,左右边距边缘重合,因此可以与第一个浮动放在同一行而不违反规则7。
  • @T.T 抱歉,尽管此处提到(未解释)负边距的副作用,但我无法在规范中找到详细信息:smashingmagazine.com/2009/07/…
【解决方案2】:

第二个 div 有 margin-left: 50% 和 50% 的宽度,这实际上将它放在屏幕之外。在这种情况下,浏览器无需将其向下移动,它可以根据您的样式将两个 div 放在同一行。

如果您希望两个 div 都向右浮动并且第二个应该占据屏幕的 50%,那么只需删除左边距。

* {
     margin:0;
     padding: 0;
    }
.first {
  float: right;
  width: 100%;
  height: 40px;
  background-color: black;
}

.second {
  float: right;
  background-color: red;
  width: 50%;
  height: 40px;
}
<div class="first"></div>
<div class="second"></div>

澄清

为什么第二个 div 放在外面? float: right 规则使 div 贴在屏幕的右侧。并且结合width:50%,最左边的点将位于屏幕的中心。然后,在添加margin-left:50%时,会添加一个屏幕大小为50%的边距,并且div的最左边的点将放在屏幕的右边缘,因此整个div实际上是在屏幕之外。

为了更清楚地看这个例子:

我将第二个 div 设置为 width:30%margin-left:30%,并添加了第三个 div,它也以 30% 的宽度向右浮动。

现在浏览器可以将两个 div 放在同一行,因为总宽度 + 边距为 90%。

* {
     margin:0;
     padding: 0;
    }
.first {
  float: right;
  width: 100%;
  height: 40px;
  background-color: black;
}

.second {
  float: right;
  background-color: red;
  width: 30%;
  height: 40px;
  margin-left: 30%;
}

.third {
  float: right;
  background-color: #e5e5e5;
  width: 30%;
  height: 40px;
}
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>

如果我们将 margin-left 增加到 45%,那么总宽度将是 105%,这会迫使浏览器将第三个 div 移动到下一行

* {
     margin:0;
     padding: 0;
    }
.first {
  float: right;
  width: 100%;
  height: 40px;
  background-color: black;
}

.second {
  float: right;
  background-color: red;
  width: 30%;
  height: 40px;
  margin-left: 45%;
}

.third {
  float: right;
  background-color: #e5e5e5;
  width: 30%;
  height: 40px;
}
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>

【讨论】:

  • 谢谢。但我只是想弄清楚为什么负边距会使第二个 div 以这种方式显示。
  • 但是为什么 margin-left: -50% 会出现在屏幕之外呢?
  • 我用示例添加了更详细的解释
  • 但是第二个div是向右浮动的,所以margin-left不应该影响自己,它应该影响下一个div。
  • 错了,边距和元素本身有关
猜你喜欢
  • 2023-03-23
  • 2010-12-25
  • 2011-10-11
  • 2015-02-10
  • 2016-06-22
  • 2016-11-03
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多