好的,所以一些间距走进酒吧,绊倒并跌倒在地板上。 酒保问他是否应该被切断,间距回答说,“不,我只是一个折叠的边距。”
对不起,愚蠢的笑话。
更严肃地说,折叠边距是真实存在的,如果您不知道它们是什么以及它们的行为方式,它们会让您非常头疼。 以下是一些我们看到这些小家伙发挥作用的场景。
当垂直世界发生碰撞时
当两个垂直边距彼此接触时,就会发生折叠边距。 如果一个边距大于另一个,则该边距将覆盖另一个,只留下一个边距。
假设我们在彼此之上堆叠元素,一个带有底部边距,一个带有顶部边距
.module {
display: block;
width: 100%;
height: 150px;
}
.module__top {
margin-bottom: 25px;
background-color: #f38a6d;
}
.module__bottom {
margin-top: 50px;
background-color: #3bbfef;
}
如果上面的模块在 HTML 标记中彼此相邻放置,那么我们可能会期望它们之间垂直有 75px
(25px
来自顶部模块加上 50px
来自底部模块),对吧?
好吧,在本期《CSS 生存法则》中,我们只获得了其中的 50 个像素。 这就像较大的边距直接吃掉了另一个边距,没有留下任何东西。
查看 Pen 折叠边距:垂直 来自 CSS-Tricks (@css-tricks) on CodePen.
继续测量。 这两个模块之间的空间总计 module__bottom
的 50px,并将 module__top
的边距踢到路边。
自然反应可能是不断增加较小的边距,直到它产生效果。 但是,当两个边距都是正数时
较大的边距 = 总垂直边距
你们中比我更善于数学的人可能会巧妙地问:负边距怎么样? 答案是它确实有重大影响,并减少了两个元素之间的边距。
50px + (-25px) = 25px
用英语来说,如果一个边距为负数,则负边距将从正边距中减去,从而减少总垂直边距。 以下是它的样子
查看 Pen 折叠边距:垂直和负数 来自 CSS-Tricks (@css-tricks) on CodePen.
如果两个边距都是负数呢? 与两个边距都是正数的情况相同。 但是,折叠的边距是两个中较大的负数,而不是最接近正数的边距。 例如,如果一个边距是 -25px
,另一个是 -50px
,则 -50px
将是边距。
您可能会遇到的另一种情况是,当一个垂直边距遇到一个相等的垂直边距时。 如果这确实是“适者生存”,那么两个相互冲突的相等边距应该要么共同生存,要么共同死亡,对吧? 这是一个很好的想法,但最终发生的是,一个继续使用,另一个被折叠。 它有点像一个吞掉了另一个,虽然我们不确定哪个被吞掉了。
当父母管教孩子时
当子元素的边距跨过其父元素的边距时,也会发生折叠边距。 让我们考虑以下情况
/* Parent */
div {
margin: 15px;
}
/* Here come the children */
.red {
background-color: #ff6b6b;
}
.orange {
background-color: #ff9e2c;
}
.yellow {
background-color: #eeee78;
}
.green {
background-color: #4ecd9d;
}
.blue {
background-color: #4e97cd;
}
.purple {
background-color: #6c4ecd;
}
在这个例子中,div
是父元素,每个后面的类都是嵌套的子元素。 这就建立了父子关系。
同样,我们的自然倾向可能是期望总边距是父边距和子边距的总和。 但是,情况并非如此,子边距将被父边距覆盖——至少只要子元素生活在父元素的屋檐下。 父母可以是如此霸道。
但是就像任何父母的惩罚一样,有一种方法可以绕过它,即在父元素中添加一些实心内容。 在这种情况下,添加 1px
的填充可以让两个边距都被使用。
查看 Pen 折叠边距:父母和孩子比较 来自 CSS-Tricks (@css-tricks) on CodePen.
如果我们在父元素中添加 border-top
,情况也是如此。 只要父元素和子元素之间存在一些实心内容,两个边距都会被使用。
最后
您是否看到了折叠边距如何使事情变得棘手? 我个人在处理排版时经常遇到这种情况。 我很想为 <h1>
和 <h2>
等内容添加边距,但这通常会导致以后出现许多麻烦,因为垂直边距会彼此碰撞。
我很想知道你们对折叠边距的看法。 特别是,您如何在基于模式的系统中管理它们? Harry Roberts 提供了一些很好的技巧。 请分享!
这就是为什么,通常,我只对元素应用 margin-top 的原因。
我也是。 顶部边距,尤其是在排版中,最初是一种很好的做法,并成为 kodmunki 的实际标准! 这是一个出色的“模式”,它节省了无数的开发时间,并使许多设计师免受鼻梁塌陷、眼睛发黑、将脸猛烈地砸向键盘的痛苦! :{)}
好文章,信息清晰有用。 我曾经多次被折叠边距困扰 :-)
在冲突的元素之间使用 clearfix 也可以解决这个问题。
我使用 Harry Roberts 的技巧,只使用 margin bottom。 它需要一些时间来适应,但非常值得。
作为额外的好处,我的项目的排版节奏更加一致,也更容易管理。
自从他发表文章以来,我一直遵循 Harry 的规则,到目前为止,我一直避免了折叠边距带来的任何麻烦。 但是,如果我在我接触到的项目中遇到折叠边距(一些代码已经编写好),它会提醒我为什么要避免双向边距。
我一直想知道的是为什么会出现边距折叠——它是否存在任何有用的情况?
边距折叠来自图形设计。
在那里,您有标题和副标题的边距,但是当副标题紧接在标题之后时,您不应该将边距加倍。 这就是为什么他们开发了折叠边距的概念,这也是为什么它只发生在垂直边距上的原因。
当边距被引入网页设计时,网站只是带有格式化文本的白色页面。 因此,边距基本上用于文本或文本内的图像。 基本上所有元素都是 display:inline,因此折叠边距是正确的方法,并成为规范。
因为在排版方面(例如),它们更有意义。 是否存在任何它没有用处的情况? ;)
我认为值得一提的是,overflow hidden 也会阻止边距折叠——> http://codepen.io/anon/pen/wazRXY
如果我没记错的话,这就是微型 clearfix 也具有 before 伪元素的原因。 否则,overflow hidden 和 clearfix 将产生不同的结果。
我总是努力避免使用 margin-top css 属性。只使用 margin left、right 和 bottom 来实现 100% 的宽度。但如果水平线上有一些标签,我会使用 tag+tag 并只写 left 或 right margin。
对于没有任何内容的空父级和子级,我总是使用诸如 display block 以及特定高度和宽度的属性。
如果我们始终如一地这样做,我们应该能够得到预期中的任何空间。
再补充一点,如果我使用 ::before 和 ::after 这样的伪元素来进行任何装饰,比如使用颜色创建空的空间,我会添加一个额外的属性,它用于给伪元素提供“一个空空格”内容,比如 content:” “;。
正如其他人所说,我只使用
margin-bottom
,并在绝对必要时才进行例外处理。如果有必要,可以通过一些专门针对兄弟行为的样式来处理这种情况。值得庆幸的是,我们有兄弟选择器+
来帮助我们做到这一点。很棒的文章!消除了我对边距折叠的所有疑问,尤其是在一个边距为正另一个边距为负的情况下的疑问。
以下是避免边距折叠的更简洁方法(没有 1px 内边距或边框技巧)
http://codepen.io/Merri/pen/rVMRpq
是的,display:inline-block 是一个不错的替代方案。
对于那些无法使用 width 100% 的情况(旧的 IE 以及右/左内边距/边框/边距),可以使用这个技巧
http://codepen.io/anon/pen/RPoLRJ
使用 before 和 after 伪元素,并为其设置高度和负边距,以强制父级内边距,而不会影响原始内容的大小。
当然,它也有一些缺点,因为你需要能够使用 before 和 after 伪元素,而这些元素可能已经被用于其他目的。
有效的 codepen(另一个是匿名创建的)
{ float: left; width: 100% }
也应用了两种边距,尽管这种方法因为使用了 float 不太酷...多年来我一直只使用 margin-bottom,效果很好。我尽量让我的网站尽可能模块化,所以只使用 margin-bottom 可以让我不必担心不同模块组合的排列方式。如果我遇到任何独特的边距需求,我倾向于使用“相邻兄弟”(
.this + .that
)或:last-child
选择器来修复这些特定情况。我在元素前使用 margin-top:http://alistapart.com/article/axiomatic-css-and-lobotomized-owls。
嗯……绝对不是。数学给了我们一个非常具体的
max(x,y)
函数的含义。如果x==y
那么max(x,y)==x==y
。认为max(x,y)
会是 0 或x+y
没有任何意义。虽然我可以看到容器等方面的一些(很容易解决的)问题,但你如何在没有边距折叠的情况下创建正确间距的段落和标题?
我通常使用 display: inline-block、float: left 和 clear: both...
两个有洁癖的女人站在地铁站台上,两人都要求与对方保持 12 英寸的“气泡”间隔。两人都对自己维持了她们认为的“气泡”感到满意,但她们之间仍然只有 12 英寸(而不是 24 英寸)。
我并没有真正纠结于这个概念,因为我一直将边距视为“给我至少这么大的呼吸空间,远离任何外部元素”。但是,如果你想让这个气泡是“我的,都是我的”,那么请使用内边距。内边距更像是“我不想接触任何东西,既不想接触外部元素,也不想接触我自身容器的边缘”。边距似乎很适合折叠(哦,还有那个漂亮的水平居中,比如
margin: x auto;
)。没错!奇怪的是,在 CSS 世界中,只要她们并排站在一起(在水平轴线上),这两个女人之间的空间仍然是 24 英寸。只有当一个女人漂浮在另一个女人的上面时,它才会折叠成 12 英寸。
感谢分享这篇文章,我刚开始接触网站设计和开发。你的文章将帮助我设计我即将到来的网站。
我正在尝试组建一个通用的样式表。
我认为几乎所有元素都有一个0px 的上边距,并使用下边距来控制垂直间距的想法很好。我确实遇到过很多情况下,为元素设置上边距会让我头疼。
问题 1:我想要 P 元素通常具有 1.5em 的下边距,但如果 P 元素位于另一个 P 元素之上,我想要它的下边距稍微小一点,比如 1em。换句话说,一堆 P 元素之间的间距应该比整个 P 元素堆栈的上下间距小。如果我们有一个选择器可以像这样作用于某个东西的前兄弟元素:
p+p
,这将很容易。但我们知道这只会选择语句中的最后一个 P 元素。问题 2:同样地,我希望 P 元素(以及其他一些块级元素,如 UL、Table 等)具有 1.5em 的下边距,除非它们后面跟着一个 H1-6 标签,在这种情况下我想要 1.8em。同样,我需要一个选择器可以作用于语句中的第一个元素(例如 p+H1)。
所以……
有人知道如何仅在 P 元素后面跟着一个 H1 的情况下选择它吗?
或者一个后面跟着另一个 P 元素的 P 元素?
想法
如果没有一个选择器能够自然地完成这项工作……
解决这两个问题的方法可能是创建一个类(可能命名为“needExtraSpacingBecauseImTheLastOne”),为任何在 H1 之前的元素提供更多边距,或者其他标题标签。
对于问题 2,我可以在标题上设置上边距,但创建一个类,我可以将它放在其中任何一个标题上,以将上边距归零(比如,如果它是块/页面中的第一个标题,并且我不希望有额外的上间距)。
或者简单地使用
p+h1
并增加上边距,因为你想要的是定位后面跟着标题的段落(或者后面跟着段落的标题,这两种情况是一样的)。更简单,避免了不必要的类。感谢你的回复,Lazza。
但是,P 不是我需要放入这种兄弟元素表示法的唯一标签。我需要添加 blockquote+h1、form+h1、ul+h1 以及其他几个标签。因此,如果你将大约 9 个块级标签遍历所有 6 个 H 标签,最终将得到 54 个语句,而不是 6 个 H.noMarginAbove 类。这使得类值得考虑。
但是,你的想法可能适合我的情况。我一定会考虑一下。谢谢!