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

评论

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

只需为元素的下边距设置一个值,但将上边距保留为0。

我制作了一个程序包来简化计算:npmjs.com/package/collapsed-margin

#1 楼

边距折叠主要有两种类型:


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

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

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


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

您可以在这里进行所有测试:http://jsfiddle.net/XB9wX/1/。 br />
我应该补充说,像往常一样,Internet Explorer是例外。更具体地说,在IE 7中,当为父元素指定某种布局(例如width)时,边距不会折叠。

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

评论


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

–Mladen Janjetovic
2014年11月24日14:18

请注意,overflow:auto可能导致滚动条出现在父元素中,而不是让溢出内容按照溢出:可见的方式溢出。

–狮子座
2015年4月20日的11:00

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

– alexcasalboni
17年1月25日在10:35

flex的任何值与其默认值不同都会禁用边距崩溃

–奥利
17-4-17在23:28



显示:一旦浏览器支持有所提高,flow-root可能是首选方法。

–詹姆斯·柯伊尔(James Coyle)
17年5月22日在0:41

#2 楼

据我所知,禁用没有视觉影响的边距折叠的一种巧妙技巧是将父级的填充设置为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.1更改为0.05。正如克里斯·摩根(Chris Morgan)在下面的评论中提到的那样,通过这个小测试,似乎Firefox确实考虑了0.1px填充。虽然,0.05px似乎可以解决问题。

评论


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

–尼克·曼宁(Nick Manning)
16-2-18在19:07



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

– Nicu Surdu
16-2-23在22:35

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

– Wiredolphin
16-2-24在9:09



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

–克里斯·摩根(Chris Morgan)
17年9月26日在2:04

0.05px似乎仍然是一个特定的选择,而不是随机的浏览器欺骗性数字,我希望使用0.01px。

– Volker E.
6月2日1:39

#3 楼

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

评论


将我的答案变成了社区Wiki。请随意扩展您的答案。谢谢。

–hqcasanova
14-10-24在20:43



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

–安迪
2015年5月14日下午2:25

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

– NicBright
2015年6月19日14:07



我可以更精确地说明这一点:clearfix方法只能防止父母和孩子之间的边际崩溃。它不会影响相邻兄弟姐妹之间的崩溃。

– NicBright
2015年6月19日14:14

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

– Stijn de Witt
2015年12月2日,13:15

#4 楼

overflow:hidden可以防止利润下降,但是它没有副作用-即...隐藏了溢出。当它们真正有用时(每3至5年出现一次)。

评论


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

–hqcasanova
2014-10-24 20:41



溢出:使用auto可以很好地防止隐藏的溢出并且仍然可以防止边距崩溃。

–加文
15年6月17日在15:01

@Gavin,溢出:自动;使我的内容区域在某些页面上具有滚动条。

–芦苇
2月18日21:10

#5 楼

实际上,有一种可以完美运行的东西:仅支持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> 




评论


为了使它能够用作通用解决方案,必须在.container中添加一个额外的
,否则.container将控制其子级的box-model。例如,内联元素将成为全宽块元素;如果他们有保证金,这些保证金也将崩溃。

– zupa
19年9月19日在6:35

#6 楼

每个基于Webkit的浏览器都应支持属性-webkit-margin-collapse。也有子属性只能将其设置为顶部或底部边距。您可以为其指定值折叠(默认),丢弃(如果有相邻边距,则将边距设置为0)和单独(防止边距崩溃)。版本的Chrome和Safari。不幸的是,我认为IE不会支持该功能,因为它不是基于webkit的。

阅读Apple的Safari CSS参考以获取完整的解释。 CSS webkit扩展页面,它们将这些属性列为专有属性,建议不要使用它们。这是因为它们可能不会很快进入标准CSS,只有基于Webkit的浏览器才能支持它们。

评论


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

– bjudson
15年6月19日在22:44

看起来-webkit-margin-collapse属性已在Chrome v85中删除。我在某些工具中使用了它,现在测试失败了。

–Möhre
10月2日10:14

#7 楼

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

评论


不仅针对其子元素,还防止了父级与第一个和最后一个子级之间的边距崩溃。

– Sven Marnach
17-10-18在19:56

#8 楼

由于父级将position设置为相对值,我对保证金崩溃也有类似的问题。以下是可用于禁用边距折叠的命令列表。

这里需要进行测试

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

禁用边折叠时,带有红色背景的div.absolute将位于页面的顶部。

边距缩小div.absolute将与div.margin放置在相同的Y坐标上





 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,带有示例,您可以编辑

#9 楼

在较新的浏览器(不包括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> 





DEMO(之后)




 .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> 




#10 楼

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

.parent {
  display: grid
}