如何禁用保证金倒闭?


202

有没有一种方法可以完全禁用边距收缩?我发现的唯一解决方案(名称为“ uncollapsing”)需要使用1px边框或1px填充。我发现这是不可接受的:无关紧要的像素无缘无故使计算复杂化。有没有更合理的方法来禁用此保证金倒塌?


4
使用不存在边距折叠的Flex或Grid布局:stackoverflow.com/a/46496701/3597276
Michael Benjamin

简单地给元素的值,margin-bottom但保留margin-top为0
丹布雷

我制作了一个程序包来简化
Owen M,

Answers:


254

保证金崩溃的主要类型有两种:

  • 相邻元素之间的边距崩溃
  • 父元素和子元素之间的折叠边距

仅在后一种情况下,使用填充物或边框可以防止塌陷。此外,与父级应用的overflow默认值(visible)不同的任何值都可以防止崩溃。因此,两者overflow: autooverflow: hidden将具有相同的效果。也许唯一的区别hidden是如果父母的身高固定,则隐藏内容的意外结果。

一旦应用于父级,其他可以帮助解决此问题的属性是:

  • float: left / right
  • position: absolute
  • display: inline-block / flex

您可以在这里进行所有测试:http : //jsfiddle.net/XB9wX/1/

我应该补充一点,像往常一样,Internet Explorer是例外。更具体地说,在IE 7中,当为父元素指定某种布局时,边距不会折叠width

资料来源:Sitepoint的文章“ 利润率下降”


1
请注意,如果填充值不为零,也会影响填充效果
Mladen Janjetovic

3
请注意,这overflow: auto可能导致滚动条出现在父元素中,而不是使溢出内容按照溢出overflow: visible
Leo

在Chrome v44中似乎无法使用“溢出:自动”功能。
tkane2000

3
感谢您的展示:inline-block,它救了我:)
alexcasalboni

3
flex与其默认值不同的任何值都将禁用保证金缩减
Oly

60

您也可以为此使用良好的旧版micro clearfix。

#container:before, #container:after{
    content: ' ';
    display: table;
}

查看更新的小提琴:http : //jsfiddle.net/XB9wX/97/


已将我的答案转变为社区Wiki。请随时将其扩展为您的答案。谢谢。
hqcasanova

3
当我看到该示例的边距正在崩溃时(我在div上只有10px的垂直间距,而不是20px),我不明白这一点
Andy

1
这仅有助于消除都应用了该clearfix的兄弟姐妹之间的崩溃。我分叉了示例来演示这一点: jsfiddle.net/dpyuyg07 ---甚至还不是全部。它仅消除了由于应用了此修复程序的元素的子元素而引起的页边距崩溃。如果您要在容器本身上添加边距,则边距仍然会崩溃,这可以在此fork中看到:jsfiddle.net/oew7qsjx
NicBright

4
我可以更准确地说:clearfix方法只能防止父母和孩子之间的边距崩溃。它不会影响相邻兄弟姐妹之间的崩溃。
NicBright

我想我现在了解了Bootstrap用:beforeand :after元素填充DOM的趋势。现在,我将此规则添加到了样式表中:div:before, div:after{content: ' '; display: table;}。太棒了 突然,东西开始按预期运行。
Stijn de Witt

59

据我所知,禁用边缘折叠没有任何视觉影响的一种巧妙技巧是将父级的填充设置为0.05px

.parentClass {
    padding: 0.05px;
}

填充不再为0,因此不会再发生崩溃,但是与此同时,填充足够小以至于在视觉上将其舍入为0。

如果需要其他填充,则仅将填充应用于例如不需要边缘塌陷的“方向” padding-top: 0.05px;

工作示例:

.noCollapse {
  padding: 0.05px;
}

.parent {
  background-color: red;
  width: 150px;
}

.children {
  margin-top: 50px;

  background-color: lime;      
  width: 100px;
  height: 100px;
}
<h3>Border collapsing</h3>
<div class="parent">
  <div class="children">
  </div>
</div>

<h3>No border collapsing</h3>
<div class="parent noCollapse">
  <div class="children">
  </div>
</div>

编辑:将值从更改0.10.05。就像克里斯·摩根(Chris Morgan)在下面的评论中提到的那样,通过这次小型测试,看来Firefox确实采用了0.1px填充。虽然,0.05px似乎可以解决问题。


2
这是我最喜欢的解决方案。您甚至可以将此作为默认样式。为什么不?*{padding-top:0.1px}。我们确定它可以在所有浏览器中运行吗?
尼克·曼宁

到目前为止,对我来说还算不错,但是我并不声称已经在大多数浏览器中对其进行了全面的测试。
Nicu Surdu '16

2
非常好的解决方案,它似乎可以在大多数浏览器上正常工作。感谢分享!
–wiredolphin

1
这是一个狡猾的解决方案,因为由于高DPI显示和子像素计算,它确实会在各种情况下添加额外的像素。(Firefox进行亚像素布局已经有很长时间了,我相信其他浏览器也相对较新。)
克里斯·摩根

0.05px我更喜欢似乎仍然是一个特定的选择,而不是一个随机的浏览器欺骗号码0.01px
Volker E.

22

overflow:hidden 可以防止页边空白,但是它也没有副作用-即...隐藏了溢出。

除了这些以及您提到的内容之外,您只需要学习它,并在这一天实际有用时(每3至5年出现一次)学习这一天。


已将我的答案变成社区Wiki。我想我确实涵盖了您在第二段最后两行中提到的副作用:也许使用隐藏选项的唯一区别是,如果父项的高度固定,则隐藏内容的意外结果。但是,如果您需要进一步说明,请随时做出贡献。谢谢。
hqcasanova

7
overflow: auto可以很好地防止隐藏的溢出并仍然防止边距崩溃。
加文2015年

@Gavin,overflow:auto;使我的内容区域在某些页面上具有滚动条。
里德

13

实际上,有一种可以完美运行的方式:

显示:flex; flex-direction:列;

只要您可以只支持IE10或更高版本

.container {
  display: flex;
  flex-direction: column;
    background: #ddd;
    width: 15em;
}

.square {
    margin: 15px;
    height: 3em;
    background: yellow;
}
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>


为了使它能够用作通用解决方案,必须<div>在内添加一个附加项.container,否则.container会控制其子项的Box模型。例如,内联元素将成为全角块元素;如果他们有保证金,这些保证金也将崩溃。
zupa

9

每个基于Webkit的浏览器都应支持属性-webkit-margin-collapse。还有一些子属性只能将其设置为顶部或底部边距。您可以为其设置值折叠(默认值),丢弃(将边距设置为0(如果存在相邻边距))和单独(防止边距折叠)。

我已经测试过,它可以在2014版的Chrome和Safari上使用。不幸的是,我不认为IE支持该功能,因为它不是基于webkit的。

阅读Apple的Safari CSS参考以获取完整说明。

如果您查看Mozilla的CSS webkit扩展页面,它们会将这些属性列为专有属性,建议不要使用它们。这是因为它们可能不会很快进入标准CSS,只有基于Webkit的浏览器会支持它们。


很好,因为它可以帮助我们消除Safari和Chrome处理利润率方面的不一致。
bjudson

8

我知道这是一篇非常老的文章,但只想说在父元素上使用flexbox会禁用其子元素的边距折叠。


不仅是其子元素-还可以防止页边距在父级与第一个和最后一个子级之间崩溃。
Sven Marnach '17

2

由于父级已position设为相对,我也遇到了利润下降的类似问题。以下是可用于禁用边距折叠的命令列表。

在这里进行测试

只需尝试将任何parent-fix*类分配给div.containerelement,或将任何类分配children-fix*div.margin。选择最适合您的需求。

什么时候

  • 边际折叠功能禁用div.absolute红色背景将位于页面的顶部。
  • 边距崩溃 div.absolute将位于与Y相同的Y坐标div.margin

html, body { margin: 0; padding: 0; }

.container {
  width: 100%;
  position: relative;
}

.absolute {
  position: absolute;
  top: 0;
  left: 50px;
  right: 50px;
  height: 100px;
  border: 5px solid #F00;
  background-color: rgba(255, 0, 0, 0.5);
}

.margin {
  width: 100%;
  height: 20px;
  background-color: #444;
  margin-top: 50px;
  color: #FFF;
}

/* Here are some examples on how to disable margin 
   collapsing from within parent (.container) */
.parent-fix1 { padding-top: 1px; }
.parent-fix2 { border: 1px solid rgba(0,0,0, 0);}
.parent-fix3 { overflow: auto;}
.parent-fix4 { float: left;}
.parent-fix5 { display: inline-block; }
.parent-fix6 { position: absolute; }
.parent-fix7 { display: flex; }
.parent-fix8 { -webkit-margin-collapse: separate; }
.parent-fix9:before {  content: ' '; display: table; }

/* Here are some examples on how to disable margin 
   collapsing from within children (.margin) */
.children-fix1 { float: left; }
.children-fix2 { display: inline-block; }
<div class="container parent-fix1">
  <div class="margin children-fix">margin</div>
  <div class="absolute"></div>
</div>

这是jsFiddle带有示例的您可以编辑


1

在较新的浏览器(不包括IE11)中,可以使用防止父子边距崩溃的简单解决方案display: flow-root。但是,您仍然需要其他技术来防止相邻元素塌陷。

演示(之前)

.parent {
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

演示(之后)

.parent {
  display: flow-root;
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>


0

供您参考,您可以使用网格但有副作用:)

.parent {
  display: grid
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.