CSS内外边距及格式化上下文

基本概念

替换元素

替换元素是浏览器根据其标签的元素与属性来判断显示具体的内容。典型的替换元素有<img>和表单元素等。

非替换元素

大多数元素是不可替换元素,其内容直接表现给浏览器。
比如<p>this is a paragraph.</p>

块级元素

块级元素占据其父元素(容器)的整个空间,因此创建了一个“块”。

行内元素

一个行内元素只占据它对应标签的边框所包含的空间。

流内/流外元素

An element is called out of flow if it is floated, absolutely positioned, or is the root element. An element is called in-flow if it is not out-of-flow.

如果一个元素是浮动的(float: left/right),绝对定位的(position: absolute/fixed)或者是根元素(html),那么它被称之为流外的元素(out-of-flow)。如果一个元素不是流外的元素,那么它被称之为流内元素(in-flow)。

行内元素设置内外边距

Example

结论

  • 对于行内非替换元素,设置margin-top和margin-bottom不起作用;

    在向一个行内非替换元素应用外边距,它对行高没有任何影响。由于外边距实际上是透明的,所以这个声明没有任何视觉效果。其原因在于行内非替换元素的外边距不会改变一个元素的行高。——《CSS权威指南》 P227

  • 对于行内替换元素,设置margin-top和margin-bottom正常表现;

  • 对于行内非替换元素,设置padding-top和padding-bottom不会影响其行高,不会撑开父元素;

  • 对于行内替换元素,设置padding-top和padding-bottom正常表现。

外边距合并

块级元素的上外边距和下外边距有时会合并(或折叠)为一个外边距,这种行为称为外边距折叠(margin collapsing)。

参考文档

规则

相邻元素之间

流内块级元素的bottom margin总会与它的下一个流内块级兄弟的top margin合并,除非该兄弟(元素)具有间隙。

<p>元素默认有margin-topmargin-bottom值,相邻两个<p>元素外边距发生折叠。


空的块级元素

如果一个块级元素中不包含任何内容,并且在其 margin-top 与 margin-bottom 之间没有边框、内边距、行内内容、height、min-height 将两者分开,则该元素的上下外边距会折叠。


父元素与其第一个或最后一个子元素之间

如果在父元素与其第一个子元素之间不存在边框、内边距、行内内容,也没有创建块格式化上下文、或者清除浮动将两者的 margin-top 分开;或者在父元素与其最后一个子元素之间不存在边框、内边距、行内内容、height、min-height、max-height将两者的 margin-bottom 分开,那么这两对外边距之间会产生折叠。此时子元素的外边距会“溢出”到父元素的外面。

合并结果计算规则

  • 两个相邻的外边距都是正数时,合并结果是它们两个之间较大的值;
  • 两个相邻的外边距都是负数时,合并结果是两者绝对值的较大值;
  • 两个相邻的外边距一正一负时,合并结果是两者相加的和。

BFC(块格式化上下文,Block Formatting Context)

概念

W3C CSS2.1 规范中BFC定义:

浮动元素、绝对定位元素,非块盒的块级容器(例如inline-blocks,table-cells和table-captions),以及”overflow”不为”visible”的块盒,会为其内容建立新的块格式化上下文。

BFC 的实际应用

清除浮动

原理:块格式化上下文中的’Auto’高度

如果该元素(建立了块格式化上下文的元素)含有任意下外边距边界位于元素的内容下边界下方的的浮动后代,那么高度增加至能够包含这些边界。只考虑参与此块级格式化上下文的浮动,例如,不考虑绝对定位的后代中的浮动或其它浮动。

简单来说,就是创建了块级格式化上下文的元素会根据子元素的情况自动适应高度。

两栏布局

原理:浮动盒区域不叠加到BFC上

右侧区域未创建块级格式化上下文时,左侧float区域叠加在右侧区域上。
右侧区域使用overflow: hidden;创建了一个块级格式化上下文,实现两栏布局。

IFC(内联格式化上下文,Inline Formatting Context)

概念

W3C CSS 2.1 规范 内联格式化上下文

display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box,并且参与 IFC;

包含来自同一行的盒的矩形区域叫做行盒(line box),行盒的高度由line-height的计算结果决定,高度由其包含行内元素中最高的实际高度计算而来,不受竖直方向的padding/margin影响。

Example

  • 当几个内联级盒在水平方向上不能共存于一个行盒时,它们会被分到两个或多个垂直堆叠的(vertically-stacked) 行盒里。因此,段落就是个行盒的垂直栈(vertical stack)。行盒没有垂直间隔地堆放(除非在其它地方有特别说明)并且它们不会重叠;

  • 一个行盒总是足够高,能够容纳它包含的所有盒。然而,它可能比它所包含的最高的盒还要高(例如,如果盒是以基线对齐的)。当盒B的高度小于它所在的行盒的高度时,行盒中B的竖直对齐方式由vertical-align属性决定;

  • 当一行的内联级盒的总宽度小于它们所在的行盒的宽度时,它们在行盒里的水平分布由text-align属性决定。

FFC(自适应格式化上下文,Flex Formatting Context)

概念

display值为flex或者inline-flex的元素将会生成弹性容器(flex container)。

一个弹性容器为其内容建立了一个新的弹性格式化上下文环境(FFC)。

GFC(网格格式化上下文,Grid Formatting Context)

概念

CSS Grid Layout Module Level 1

当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。

兼容性

https://caniuse.com/#search=grid

推荐文章