您需要了解的有关CSS保证金的所有信息

我们许多人在学习CSS时学到的第一件事就是CSS块中各个元素的功能,称为“ CSS块模型”。 块模型中的元素之一是空白(外边距),它是块周围的透明区域,可从该块内容中排斥其他元素。 margin-topmargin-rightmargin-bottommargin-left属性早在CSS1时就已描述,同时还提供了用于同时设置所有四个属性的缩写margin属性。

保证金似乎很简单,但是,在本文中,我们将探讨人们在使用它时偶然发现的一些问题。 特别是,边距如何相互影响以及外部边距的崩溃实际上如何工作。



CSS块模型


与所有有关CSS CSS Block Model组件的文章一样,我们必须确定其含义以及如何在不同版本的CSS中对模型进行分类。 块模型是指块的不同组件(内容(填充),填充(填充),边框(框架)和边距(填充))如何相互定位和交互。 在CSS1中,使用下图所示的ASCII图描述了块模型。

块每一侧的所有四个属性以及缩写的margin属性在CSS1中定义。

CSS2.1规范用插图说明了块模型,还定义了我们将继续用来描述不同块的术语。 该规范描述了内容框,填充框,边框和边距框,它们分别由内容边框,边距,边框和边距定义。



当前有一个块模型3版本的规范作为工作草案。 在定义Block Model和margins时 ,它使我们返回CSS2,因此在整篇文章中,我们将使用CSS2中的定义。

倒塌幅度


CSS1规范不仅定义了边距,还定义了它们的瓦解。 这种行为已成为许多失望的根源。 当您考虑到在那个年代,CSS被用作文本文档的标记语言时,折叠边距很有意义。 折叠页边距意味着当标题较低的页眉后跟具有最高页边距的段落时,这两个缩进点不会相加,从而在元素之间造成巨大的间隙。

当两个边距塌陷时,元素之间的间距将等于两个凹口中的较大者。 较小的缩进实际上在较大的内部结束

在以下情况下保证金崩溃:

  • 相邻兄弟姐妹(单亲)
  • 空块
  • 父母和第一个/最后一个孩子

相邻的护理要素


我将通过说明相邻兄弟姐妹之间的边距如何塌陷来开始描述。 除非如下所述,否则如果您在正常流中一个接一个显示两个元素,则第一个元素的下边距将与后续元素的上边距折叠。

在下面的CodePen示例中,有三个div元素。 对于第一个元素,上下边距为50px,第二个元素为20px,第三个为3em。 前两个元素之间的边距为50px,因为较低元素的较低边距被较高元素的较高边距吸收。 第二个两个元素之间的边距为3em,因为3em在第二个元素的下边距处大于20个像素。


空块


如果该块为空,则其上下边界可以彼此折叠。 在下面的CodePen示例中,具有empty类(不可见,因为它为空)的第二个元素的上下边距为50px,但是,第一个元素和第三个元素之间的间距不是100像素,而是50。这是两个边距折叠的结果。

在块中添加一些内容(甚至填充)将导致使用上下边距,而不是塌陷。


父母和第一个/最后一个孩子


由于不直观,这种利润下降的情况比其他人更容易使人困惑。 在下一个CodePen中,我们有一个带有类wrapper (wrapper)的div并将此div设置为red div outline属性,以便可以看到其边框。 三个孩子的边距均为50像素。 但是,第一个和最后一个元素与包装器元素的边界相邻; 在元素和包装之间没有50像素的缩进。


这是因为子级的边距会随着父级的任何边距崩溃,从而终止于父级之外。 如果使用开发人员浏览器面板测试孩子,则可以看到此信息。 黄色突出显示的区域是边距。



仅折叠保证金


最后一个示例还重点介绍了利润率下降的问题。 在CSS2中,仅垂直(上和下)边距被设计为折叠。 因此,在上面的示例中,左侧和右侧的边距不会折叠并在包装纸内结束。

注意:值得记住的是,页边空白仅在块方向上(例如在段落之间)折叠。

防止倒塌


如果将元素设置为绝对定位或float属性,则保证金不会折叠。 但是,如果您处于页边距崩溃的情况下,如何防止这种情况发生?

介于两者之间的情况下,不会发生边距崩溃。

例如,如果将空白块设置为边框或填充,则空白块的上下边界不会折叠。 在下面的示例中,我添加了一个1px的填充块。 现在,在块的顶部和底部有一个50px的边距。


这是逻辑:如果一个空块没有边框或填充,则几乎看不见。 例如,它可能是放置在CMS标记中的空段落。 如果CMS添加了多余的段落元素,则可能不希望它们在其他段落之间造成较大的缩进,因为考虑到了它们的边距。 在块中添加一些内容并获得这些缩进。

从第一个或最后一个孩子的边距超出父对象的边距可以看到类似的行为。 如果我们给父级添加边框,则子级的边距将保留在内部。


同样,这种行为有逻辑。 如果您具有出于语义目的而无法视觉显示的包装器元素,则可能不希望它们在显示时创建较大的缩进。 当网络主要是文本时,此功能更为有用。 而且,当我们使用布局元素时,这种行为不太有用。

创建“块格式化上下文”


新的“块格式设置上下文”(BFC)将防止边距脱离父元素。 如果再看一个示例,其第一个和最后一个子项的边距超出wrapper元素的边界,并将包装器设置为display: flow-root ,从而创建BFC,则子级的边距将保留在内部。


要了解有关display: flow-root更多信息display: flow-root ,请阅读我的文章“ 了解CSS布局和块格式化上下文 ”。 将overflow属性的值更改为auto将具有相同的效果,因为它还会创建一个新的BFC,尽管在某些情况下可能会导致不需要滚动条

Flex和网格容器


Flex和Grid容器为子级设置Flex和Grid格式化上下文,因此它们具有不同的块布局行为。 这些差异之一是页边距不会崩溃:
一个伸缩容器为内容设置一个新的伸缩格式上下文。 这与设置块格式化上下文相同,不同之处在于,使用了Flex标记而不是块标记。 例如,浮点数在flex容器内不起作用,并且flex容器的边界不会随着子元素的边界而收缩。
-Flexbox 1级
如果我们以上面的示例为例,并用Flex容器包装它,指示flex-direction:列的主轴方向,那么很明显,现在子代的边距不会超出包装范围。 此外,相邻的弹性项目之间的边距不会折叠,因此弹性项目之间的距离为100像素,这是顶部和底部边距的总和,每个边距均为50px。


您网站的保证金策略


由于崩溃,一个好的解决方案是提供一致的方式来处理您网站上的保证金。 您可以做的最简单的事情就是将规则设置为仅在元素的顶部或底部设置边距。 在这种情况下,您不应该经常遇到崩溃问题,因为设置了边距的一侧将始终与另一个元素的没有边距的一侧相邻。

注意 :哈里·罗伯茨(Harry Roberts)的著作非常出色,详细说明了为什么仅沿一个方向设置边距是一个好主意的原因,而不仅仅是解决倒塌问题的原因。

这种方法不能解决您可能遇到的超出父项限制的子项元素超出边距的问题。 这个特殊的问题通常不太常见,了解为什么会发生这种情况可以帮助找到解决方案。 解决此问题的理想方法是设置需要display: flow-root的组件display: flow-root ,对于较旧的浏览器,其具有后备(fallback)功能,您可以使用overflow来创建BFC(块格式化上下文)。 将父母变成一个弹性容器; 甚至将padding设置为1px。 请记住,您可以使用浏览器支持的属性请求来确定是否支持display: flow-root属性,以便只有较旧的浏览器才能获得较差的解决方案。

我认为,在大多数情况下,了解利润率为何下降(或不下降)是关键。 这将使您确定在每种情况下如何处理此问题。 无论选择哪种方法,都要与团队共享此信息。 通常,边距的崩溃有点神秘,因此处理它的方法并不总是很明显。 在代码中添加注释可能是适当的-您甚至可以在其中添加指向本文的链接,并帮助分享有关折叠边距的知识。

我决定在本文中补充一些与边距有关的其他数据。

利息保证金


在CSS中使用百分比时,它应该是某物的百分比。 设置为百分比的边距(以及填充)将始终相对于父元素的宽度进行计算。 这意味着当使用百分比时,元素周围的所有边将始终具有相等的边距。

在下面的CodePen示例中,我有一个宽度为200px的包装器,其内部是一个边距= 10%的块。 从各个方面来看,边距均为20像素,占200像素的10%。


流量依赖世界中的保证金


在整篇文章中,我们都讨论了垂直边距,但是,现代CSS通常会考虑元素相对于流的位置而不是相对于物理面的位置。 因此,当我们谈论垂直边距时,实际上是在讨论块尺寸中的边距。 在水平书写模式下,这些边距可以是上或下,在垂直模式下,这些边距可以是右或左。

在处理了与流程有关的逻辑方向之后,谈论块的开始和结束要比谈论顶部和底部要容易得多。 为了简化操作,CSS中引入了布尔属性和值的规范。 它用与流动相关的特性代替了物理特性。

如果我们谈论页边距,这为我们提供了以下选择(如果我们使用英语或任何其他水平记录的模式(文本方向从左到右))。

  • margin-top = margin-block-start
  • 右边距=边距
  • 底部边距=边距块结束
  • margin-left = margin-inline-start

我们还有两个新的缩写属性:

  • 保证金块
  • 行内边距

在下面的CodePen示例中,我使用了与流相关的关键字,然后更改了块拼写模式。 您可以看到页边距跟随文本流的方式,而不是局限于实际情况。


您可以在MDN上或我在Smashing Magazine上的文章“ 了解逻辑属性和值”中了解更多有关逻辑属性和值的信息。

总结


现在,您了解了有关保证金的大部分知识。 简要地:

  • 保证金可能会崩溃。 了解何时发生和何时不发生将帮助您解决它们可能造成的任何问题。
  • 仅在一个方向上安装边距可以解决许多与之相关的问题。
  • 与任何CSS情况一样,与您的团队共享决策并评论您的代码
  • 考虑到块和线的测量值,而不是物理的侧面,顶部,右侧,底部和左侧,这将对您有所帮助,因为网络正逐渐独立于书写模式

Source: https://habr.com/ru/post/zh-CN465839/


All Articles