当我们学习css时,我们大多数人学到的第一件事是CSS中盒子的各个部分的细节,这部分通过叫做 CSS盒、模型。“盒模型”中的元素之一是margin,即盒子周围的透明区域,它会将其他元素从盒子内容中推开。
CSS1中描述了 margin-top、margin-right、margin-bottom和margin-left属性,以及一次设置所有四个属性的简写 margin。
margin看起来是一个相当简单的事情,但是,在本文中,咱们将看一些在使用margin一些让人迷惑有有趣的事情。 特别是,margin之间如何相互作用,以及 margin 重叠效果。
CSS 盒模型指的是一个盒子的各个部分——content、padding、border和margin,它们各自之前是如何布局及相互作用的, 如下所示:
盒子的的四个margin属性和maring缩写都在CSS1中定义。
CSS2.1规范有一个演示盒模型的插图,还定义了用来描述各种盒子的术语,其中包括 content box、填padding box、border box和 margin box。
现在有一个 Level 3 Box Model specification 的草案。这个规范引用了CSS2作为盒模型和margin的定义,因此我们将在本文的大部分内容中使用CSS2定义。
CSS1 规范定义了margin,也定义了垂直 margin 重叠。如果考虑到在早期,CSS被用作文档格式语言,那么 margin 重叠是有意义的。 margin 重叠意味着,当一个有底部margin的标题后面跟着一个有顶部 margin 的段落时,它们之间就不会出现较大的空白。
当两个 margin 发生重叠时,它们将组合在一起,两个元素之间的空间取较大的一个。 较小的 margin 在较大的里面。
在以下情况下,margin 会重叠:
依次来看看这些场景。
对 margin 重叠的最初描述是演示相邻兄弟姐妹之间的 margin 是如何重叠的。除了下面提到的情况之外,如果有两个元素在正常流中依次显示,那么第一个元素的底部 margin 将与下面元素的顶部 margin 一起重叠。
在下面示例中,有三个div元素。第一个 div 的顶部和底部的margin都是50px。第二个 div 的顶部和底部 margin 都是20px。第三个 div 的顶部和底部 margin 都是3em。前两个元素之间的 margin 是50px,因为较小的顶部 margin 与较大的底部 margin 相结合。第二个元素与第三个元素之间的 margin 是 3em,因为3em大于第二个元素底部margin20px。
<div class="wrapper">
<div class="box example1">
margin-top: 50px; margin-bottom: 50px;
</div>
<div class="box example2">
margin-top: 20px; margin-bottom: 20px;
</div>
<div class="box example3">
margin-top: 3em; margin-bottom: 3em;
</div>
</div>
css
.wrapper {
border: 5px dotted black;
}
.example1 {
margin: 50px 0 50px 0;
}
.example2 {
margin: 20px 0 20px 0;
}
.example3 {
margin: 3em 0 3em 0;
}
body {
font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
margin: 2em 3em;
}
.box {
background-color: rgb(55,55,110);
color: white;
padding: 20px;
border-radius: .5em;
}
运行效果:
如果一个盒子是空的,那么它的顶部和底部 margin 可能会相互重叠。在下面的示例中,class为empty的元素的顶部和底部 margin 各为50px,但是,第一项和第三项之间的 margin不是100px,而是50px。这是由于两个 margin 重叠造成的。如果向空盒子中放入内容就会阻止 margin 合并。
html
div class="wrapper">
<div class="box">
A box
</div>
<div class="box empty"></div>
<div class="box">
Another box
</div>
</div>
css
.wrapper {
border: 5px dotted black;
}
body {
font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
margin: 2em 3em;
}
.box {
background-color: rgb(55,55,110);
color: white;
border-radius: .5em;
}
.empty {
margin: 50px 0 50px 0;
}
运行效果:
margin 重叠让人猝不及防,因为它有时候不是很直观。在下面的示例中,有一个类名为 wrapper 的div,给这个div一个红色的outline,这样就可以看到它在哪里了。
这个div里面的三个子元素的 margin 都是50px。但是你会发现实际的效果是第一项和最后一项与父元素的的margin齐平,好像子元素和父元素之间没有50px的margin一样。
html
<div class="wrapper">
<div class="box">
Item 1
</div>
<div class="box">
Item 2
</div>
<div class="box">
Item 3
</div>
</div>
css
.wrapper {
outline: 1px solid red;
}
.box {
margin: 50px;
}
body {
font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
margin: 2em 3em;
}
.box {
background-color: rgb(55,55,110);
color: white;
padding: 20px;
border-radius: .5em;
}
运行效果:
这是因为子节点上的margin会随着父节点上的任何一边的margin相互重叠,从而最终位于父节点的外部。如果使用DevTools检查第一个子元素,就可以看到这一点,显示的黄色区域就是是 margin。
在CSS2中,只指定垂直方向的 margin 重叠,即元素的顶部和底部 margin。因此,上面的左右边距不会重叠。
值得注意的,margin 只在块的方向上重叠,比如段落之间。
如果一个元素是绝对的定位,或者是浮动的,那么它的margin永远不会重叠。然而,假设你遇到了上面示例中的几种情况,那么如何才能阻止 margin 重叠呢?
例如,一个完全空的盒子,如果它有border或padding,它的上下 margin就不会重叠。在下面的例子中,给这个空盒子添加了1px的padding。现在这个空盒子的的上方和下方都有一个50px的 margin。
html
<div class="wrapper">
<div class="box">
A box
</div>
<div class="box empty"></div>
<div class="box">
Another box
</div>
</div>
css
.wrapper {
border: 5px dotted black;
}
body {
font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
margin: 2em 3em;
}
.box {
background-color: rgb(55,55,110);
color: white;
border-radius: .5em;
}
.empty {
margin: 50px 0 50px 0;
padding: 1px;
}
运行效果:
这背后是有逻辑,如果盒子是完全空的,没有border或padding,它基本上是不可见的。 它可能是CMS中标记为空的段落元素。 如果你的CMS添加了多余的段落元素,你可能不希望它们在其他段落之间造成较大的空白,这时 margin 重叠就有一定的意义。
对于父元素和第一个或最后一个子元素 margin 重叠,如果我们向父级添加border,则子级上的margin会保留在内部。
...
.wrapper {
border: 5px dotted black;
}
...
同样,这种行为也有一定的逻辑。如果出于语义目的而对元素进行包装,但这些元素不显示在屏幕上,那么你可能不希望它们在显示中引入大的 margin。当web主要是文本时,这很有意义。当我们使用元素来布局设计时,它的重叠行为就没有多大的意义了。
BFC(Block Formatting Context)格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
BFC 可以阻止边距的重叠。 如果我们再看父元素和第一个或最后一个子元素的示例,可以在 wrapper 元素加上 display: flow-root就会创建一个新的BFC,从而阻止 margin 合并
...
.wrapper {
outline: 1px solid red;
display: flow-root;
}
...
display: flow-root 是CSS3新出来的一个属性,用来创建一个无副作用的 BFC。将overflow属性的值设为auto也会产生同样的效果,因为这也创建了一个新的BFC,尽管它也可能创建一些在某些场景中不需要的滚动条。
flex 和 grid 容器为其子元素建立flex和grid格式化上下文,因此它们也能阻止 margin 的重叠。
还是以上面的例子为例,将 wrapper 改用 flex 布局:
...
.wrapper {
outline: 1px solid red;
display: flex;
flex-direction: column;
}
...
由于margin 会重叠,最好能找到一种一致的方法来处理网站的 margin。最简单的方法是只在元素的顶部或底部定义 margin。这样,就很少会遇到 margin 重叠的问题,因为有margin的边总是与没有margin的边相邻。
这个解决方案并不能解决你可能遇到的问题,因为子元素的margin会与父元素相互重叠。这个特定的问题往往不那么常见,但知道它为什么会发生可以帮助你想出一个解决方案。
对此,一个理想的解决方案是给元素设置 display: flow-root,但有的浏览器并不支持,可以使用overflow创建BFC、或将父元素设置成flex容器,当然还可以设置padding来解决。
当你在CSS中使用百分比的时候,它必须是某个元素的百分比。使用百分比设置的 margin(或 padding)始终是父元素内联大小(水平写入模式下的宽度)的百分比。这意味着在使用百分比时,元素周围的padding大小都是相同的。
在下面的示例中,有一个200px 宽的 d当,里面是一个类名为 box 的div,它的 margin值为10%,也就是 20px(200*10%)。
html
<div class="wrapper">
<div class="box">
I have a margin of 10%.
</div>
</div>
css
* {
box-sizing: border-box;
}
.wrapper {
border: 5px dotted black;
width: 200px;
}
.box {
background-color: rgb(55,55,110);
color: white;
padding: 20px;
border-radius: .5em;
margin: 10%;
}
body {
font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
margin: 2em 3em;
}
我们在本文中一直在讨论垂直 margin ,然而,现代CSS倾向于以相对于流的方式而不是物理方式来考虑事情。因此,当我们讨论垂直边距时,我们实际上是在讨论块维度的边距。如果我们在水平写作模式下,这些 margin 将是顶部和底部,但在垂直写作模式下,这些 margin 将是右侧和左侧。
一旦使用逻辑的、流相关的方向,就更容易讨论块的开始和结束,而不是块的顶部和底部。为了简化这一过程,CSS引入了逻辑属性和值规范。这将流的相关属性映射到物理属性上。
还有两个新的快捷键,可以同时设置两个块或者两个内嵌块。
在下面示例中,使用了这些流相关关键字,然后更改了盒子的编写模式,你可以看到 margin 是如何遵循文本方向的:
html
<div class="wrapper horizontal-tb">
<div class="box">
A box with a horizontal-tb writing mode.
</div>
</div>
<div class="wrapper vertical-rl">
<div class="box">
A box with a vertical-rl writing mode.
</div>
</div>
css
* {
box-sizing: border-box;
}
.wrapper {
border: 5px dotted black;
inline-size: 200px;
}
.horizontal-tb {
writing-mode: horizontal-tb;
margin-bottom: 1em;
}
.vertical-rl {
writing-mode: vertical-rl;
}
.box {
background-color: rgb(55,55,110);
color: white;
padding: 20px;
border-radius: .5em;
margin-block-start: 30px;
margin-block-end: 10px;
margin-inline-start: 2em;
margin-inline-end: 5%;
}
body {
font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
margin: 2em 3em;
}
原文:https://www.smashingmagazine.com/2019/07/margins-in-css/
外边距合并:指的是,当两个垂直外边距相遇时,它们将形成一个外边距。 合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。 外边距合并(叠加)是一个相当简单的概念。但是,在实践中对网页进行布局时,它会造成许多混淆。
用margin还是用padding这个问题是每个学习CSS进阶时的必经之路。CSS边距属性定义元素周围的空间。通过使用单独的属性,可以对上、右、下、左的外边距进行设置。也可以使用简写的外边距属性同时改变所有的外边距。
marigin:就是外边距。padding:就是内边距。怎么就容易记住两者呢?马蓉大家都知道吧,给王宝强带帽子的那位,假如你认识了马蓉是不是想离他远点呢?而马蓉的拼音是marong,是不是和margin特别像呢?
在web网站开发中,有时候我们给html元素设置的margin-top或margin-bottom属性,但是无效,并没有取到任何作用,这是什么原因呢?常出现两种情况:
今天在修改页面样式的时候,遇到子元素设置margin-top 但是并没有使得子元素与父元素之间产生间隔,而是作用在了其父元素上,导致父元素产生了一个margin-top 的效果。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!