CSS 盒模型描述了通过 文档树中的元素 以及相应的 视觉格式化模型 所生成的矩形盒子。简单来说,盒模型定义了一个 矩形盒子,当我们需要对文档进行布局时,浏览器的渲染引擎就会根据盒模型,将所有元素表示为一个个矩形的盒子,盒子的外观由 CSS 决定。
一个标准的盒子由四个部分组成,由内向外分别为:内容,内边距,边框,外边距:
标准的盒模型中,内容区域的大小可以明确地通过 width,min-width,max-width,height,min-height,max-height 控制,也就是说,通过 CSS 设置的元素宽高只是包含内容区域。你可能听说过 怪异盒模型,这种盒模型最早在 IE 浏览器中出现,也叫 IE盒模型,box-sizing 属性值为 border-box 时,元素会呈现怪异盒模型,此时,元素的宽高包含了内容,内边距和边框。
视觉格式化模型
CSS 视觉格式化模型描述了盒子是怎样生成的,简单来说,它定义了盒子生成的计算规则,通过规则将文档元素转换为一个个盒子。
每个盒子的布局由尺寸,类型,定位,盒子的子元素或兄弟元素,视口的尺寸和位置等因素决定。
视觉格式化模型的计算,取决于一个矩形的边界,这个边界,就是 包含块( containing block ):
CSS 属性值 display 为 block,list-item,table 时,它就是块级元素
视觉上,块级盒呈现为竖直排列的块
每个块级盒都会参与 BFC 的创建
每个块级元素都会至少生成一个块级盒,称为主块级盒;一些元素可能会生成额外的块级盒,比如
行内级元素
CSS 属性值 display 为 inline,inline-block,inline-table 的元素。
行内盒
行内盒具有以下特性:
CSS 属性值 display 为inline,inline-block,inline-table时,它就是行内级元素
视觉上,行内盒与其他行内级元素排列为多行
所有的非替换元素(display 值为 inline,如 , ,, 等)生成的盒都是行内盒,它们会参与
IFC(行内格式化上下文) 的创建
所有的可替换行内元素(display 值为 inline-block 或 inline-table)生成的盒称为原子行内级盒,不参与 IFC 创建
匿名盒
匿名盒指不能被 CSS 选择器选中的盒子,比如:
块盒
匿名盒2普通流中,所有的盒一个接一个排列
BFC 中,盒子会竖着排列
IFC 中,盒子会横着排列
静态定位中(position 为 static),盒的位置就是普通流里布局的位置
相对定位中(position 为 relative),盒的偏移位置由 top,right,bottom,left 定义,
即使有偏移,仍然保留原有的位置,其它普通流不能占用这个位置
浮动
浮动定位中,盒称为浮动盒(Floating Box)
浮动盒会脱离普通流,浮动到当前行的开头或结尾
普通流会环绕在浮动盒周围,除非设置 clear 属性
定位技术
定位技术允许我们将一个元素从它在页面的原始位置准确地移动到另外一个位置,有四种:静态定位,相对定位,绝对定位,固定定位。
静态定位
默认的定位方式(position为static),此时元素处于普通流中。
相对定位
相对定位通常用来对布局进行微调,position为relative时,元素使用相对定位,此时可以通过top,right,bottom,left属性对元素的位置进行微调,设置其相对于自身的偏移量。
绝对定位
绝对定位方案中,盒会从普通流中移除,不会影响其他普通流的布局。绝对定位具有以下特点:
元素的属性position为absolute或fixed时,它是绝对定位元素
它的定位相对于它的包含块,可以通过 top,right,bottom,left 属性对元素的位置进行微调,设置其相对于包含块的偏移量
position为absolute的元素,其定位将相对于最近的一个relative、fixed或absolute的父元素,如果没有则相对于body
固定定位
与绝对定位方案类似,唯一的区别在于,它的包含块是浏览器视窗。
块级格式化上下文
通过对盒模型,定位,布局等知识的了解,我们知道 BFC 这个概念其实来自于视觉格式化模型,
它是页面 CSS 视觉渲染的一部分,用于决定块级盒的布局及浮动相互影响范围的一个区域。
BFC 的创建
以下元素会创建 BFC:
根元素()
浮动元素(float 不为 none)
绝对定位元素(position 为 absolute 或 fixed)
表格的标题和单元格(display 为 table-caption,table-cell)
匿名表格单元格元素(display 为 table 或 inline-table)
行内块元素(display 为 inline-block)
overflow 的值不为 visible 的元素
弹性元素(display 为 flex 或 inline-flex 的元素的直接子元素)
网格元素(display 为 grid 或 inline-grid 的元素的直接子元素)
以上是 CSS2.1 规范定义的 BFC 触发方式,在最新的 CSS3 规范中,弹性元素和网格元素会创建 F(Flex)FC 和 G(Grid)FC。
BFC 的范围
A block formatting context contains everything inside of the element creating it, that is not also inside a descendant element that creates a new block formatting context.
直译过来就是, BFC包含创建它的元素的所有子元素, 但不包括创建了新BFC的子元素的内部元素
简单来说,子元素如果又创建了一个新的 BFC,那么它里面的内容就不属于上一个 BFC 了,这体现了 BFC 隔离 的思想,我们还是以 table 为例:
BFC_tr:td 元素
BFC_table:只有 tr 元素,不包括 tr 里的 td 元素
也就是所说,一个元素不能同时存在于两个 BFC 中。
BFC 的特性
BFC 除了会创建一个隔离的空间外,还具有以下特性,附CodePen链接地址,可结合示例进行理解:
BFC 内部的块级盒会在垂直方向上一个接一个排列 特性①
同一BFC下的相邻块级元素可能发生外边距折叠,创建新的BFC可以避免外边距折叠 特性②
每个元素的外边距盒(margin box)的左边与包含块边框盒(border box)的左边相接触(从右向左的格式化,则相反),即使存在浮动也是如此 特性③
浮动盒的区域不会和BFC重叠 特性④
计算BFC的高度时,浮动元素也会参与计算 特性⑤
BFC 的应用
自适应多栏布局
利用 特性③ 和 特性④,中间栏创建 BFC,左右栏宽度固定后浮动。由于盒子的 margin box 的左边和包含块 border box 的左边相接触,同时浮动盒的区域不会和 BFC 重叠,所以中间栏的宽度会自适应,点我查看示例。
防止外边距折叠
利用 特性②,创建新的 BFC ,让相邻的块级盒位于不同 BFC 下可以防止外边距折叠,示例。
清除浮动
利用 特性⑤,BFC 内部的浮动元素也会参与高度计算,可以清除 BFC 内部的浮动,示例。
写在最后
本文首发于我的 博客,才疏学浅,难免有错误,文章有误之处还望不吝指正!