这是我参与「第四届青训营」笔记创作活动的第5天
视觉格式化模型
视觉格式化模型(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,leftandright。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置
浮动
- 它位于当前行的开头或末尾
- 这导致常规流环绕在它的周边,除非设置 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和hiddendisplay的值为table-cell,table-caption和inline-blockposition设置为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页面之间时不会相互影响的。