教學推薦:css影片教學
#當我們學習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
大於第二個元素底部margin
20px。
html
<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; }
需要了解更多,可以阅读有关MDN上的逻辑属性和值的更多信息。
英文原文地址:https://www.smashingmagazine.com/2019/07/margins-in-css/
更多编程相关知识,请访问:编程学习!!
以上是關於CSS margin的一些你需要知道的知識點的詳細內容。更多資訊請關注PHP中文網其他相關文章!