视觉格式化模型
视觉格式化模型(visual formatting model)是用来处理文档并将它显示在视觉媒体上的机制,定义了盒(Box)的生成,盒主要包括了块盒、行内盒、匿名盒(没有名字不能被选择器选中的盒)以及一些实验性的盒(未来可能添加到规范中)。盒的类型由display
属性决定。
块盒(block)
- 当元素的
CSS
属性display
为block
,list-item
或table
时,它是块级元素 block-level; - 视觉上呈现为块,竖直排列;
- 每个块级元素至少生成一个块级盒,称为主要块级盒(principal block-level box)。一些元素,比如
<li>
,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。
行内盒(inline)
- 当元素的CSS属性
display
的计算值为inline
,inline-block
或inline-table
时,称它为行内级元素; - 视觉上它将内容与其它行内级元素排列为多行,典型的如段落内容,文本(可以有多种格式),或图片,都是行内级元素;
匿名盒(anonymous)
匿名盒分匿名块盒与匿名行内盒,因为匿名盒没有名字,不能利用选择器来选择它们,所以它们的所有属性都为inherit
或初始默认值;
定位方案
在定位的时候,浏览器就会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。
常规流
- 在常规流中,盒一个接着一个排列
- 在块级格式化上下文里面, 它们竖着排列
- 在行内格式化上下文里面, 它们横着排列
- 当
position
为static
或relative
,并且float
为none
时会触发常规流 - 对于静态定位(static positioning),
position: static
,盒的位置是常规流布局里的位置 - 对于相对定位(relative positioning),
position: relative
,盒偏移位置由这些属性定义top
,bottom
,left
andright
。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置
浮动
- 它位于当前行的开头或末尾
- 这导致常规流环绕在它的周边,除非设置 clear 属性
绝对定位
- 绝对定位方案中,盒从常规流中被移除,不影响常规流的布局
- 它的定位相对于它的包含块,相关CSS属性:
top
,bottom
,left
及right
- 如果元素的属性
position
为absolute
或fixed
,它是绝对定位元素 - 对于
position: absolute
,元素定位将相对于最近的一个relative
、fixed
或absolute
的父元素,如果没有则相对于body
BFC
(Block Formatting Context, 块格式化上下文),是 Web 页面的可视化 CSS
渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。它是一个封闭的黑盒子,里面元素的布局不会影响外部,反之亦然。
特点:
- BFC的块不会和浮动块重叠
- 计算BFC元素的高度时,会包括浮动元素
- 在同一个BFC下的块
margin
会发生重叠(margin collapse),不在同一个则不会
触发条件:
- 浮动:
float
的值不为none
overflow
的值为auto
,scroll
和hidden
display
的值为table-cell
,table-caption
和inline-block
position
设置为absolute
和fixed
- 弹性盒子(
display:flex
或者display:inline-flex
)
除此之外, html
元素本身默认就是一个 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的子元素的内部元素
<div id='div_1' class='BFC'>
<div id='div_2'>
<div id='div_3'></div>
<div id='div_4'></div>
</div>
<div id='div_5' class='BFC'>
<div id='div_6'></div>
<div id='div_7'></div>
</div>
</div>
div_1
创建了一个BFC,包括了div_2
、div_3
、div_4
、div_5
,即div_1
的所有子元素和div_2
的子元素,但是由于div_5
创建了新的BFC,所以div_6
、div_7
被排除在div_1
的BFC之外。
这表明一个元素不能同时存在两个BFC中。
举例理解:
html
的根元素就是<html>
,而根元素会创建一个BFC,创建一个新的BFC时就相当于在这个元素内部创建一个新的<html>
,子元素的定位就如同在一个新<html>
页面中那样,而这个新旧html
页面之间时不会相互影响的。