整体结构说明:
- CSS basic box model(标准盒模型)
- Visual formatting model (视觉格式化模型)
- Viewport
- containing block (包含块)
-
Normal flow
- Block formatting contexts(块格式化上下文)
- Inline formatting contexts(内联格式化上下文)
标准盒模型
上面这张图大家应该都很熟悉,我们知道在浏览器布局文档时,页面每一个元素会被当做一个个矩形的盒子对待,我们编写的css,决定这些盒子的大小、位置、以及各种属性(背景、颜色、等等等),这些盒子的特点如下:
1)拥有四个边界,分别是:content edge 、padding edge、border edge、margin edge
2)对应的,每一个盒子,划分4个区域:
- content box: 容纳子孙元素,对应上图中中心蓝色部分;
- padding box: 隔离自身与子孙,对应上图中的绿色部分;
- border box: 自身轮廓
- margin box: 隔离自身与相邻元素
这里说明一点:对于日常布局中使用的width属性来说,默认情况下width值设置的是content box 的宽度(但是早期ie版本的浏览器width值设定的是border box的宽度),这种计算方式对我们的布局元素来说会有一些不方便(如果涉及border、padding),所以这里提一个常用的属性:box-sizing,属性值与区域划分对应,分别为:content-box 、padding-box、border-box、margin-box。一般开发中最常用的选项为border-box,这里不多做说明。
视觉格式化模型
定义:
The CSS visual formatting model is an algorithm that processes a document and displays it on visual media. This model is a basic concept of CSS
所以,视觉格式化模型是什么?
是一个算法、一系列规则
那这个算法用来干嘛?
是用来描述用户代理(浏览器)如何为视觉媒体(屏幕)处理文档树。
而确定文档在屏幕上的显示,具体又涉及:
控制元素盒子的生成、定位体系、正常流、浮动、绝对定位、层级显示、文档方向等等,所以本文后面介绍的一些概念,都属于视觉格式化模型中的一部分。
下面简要说明一部分内容
在视觉格式化模型中,文档中的每一个元素会对应生成0个、1个、或多个遵从css 盒模型的盒子,每一个盒子布局由下列因素决定:
- 盒的尺寸和类型
- 定位体系 Positioning Scheme (常规流,浮动和绝对定位)
- 文档树中元素之间的关系
- 外部信息(如:视口大小,图片的固有尺寸等)
通俗来说,我们文档中的每一个元素,都被按照一个个盒子来对待,一个元素可能对应一个盒子,也可能对应多个盒子(例如列表项元素),这些盒子的特点符合css盒模型的定义,也就是说这些盒子都会有对应的内容区域、内边距区域、边框区域等等,这些盒子最终在屏幕上的显示,则取决于盒子各项 默认 或我们设定的属性值,像display、position、width、height等等。
盒子的生成:
从文档元素生成盒子,盒子区分不同的类型,对应不同的计算规则,取决于css display 属性。元素类型区分:
- 块级元素
- 行内元素
- 行内块级元素
盒子的定位:
生成盒子之后,css引擎需要定位每一个盒子完成布局,定位区分:
- 普通流:当css position 属性被设定为static或relative,并且 css float 值为none 盒子属于普通流定位,一个接着一个进行垂直or水平布局;
- 浮动:css float 属性值不为none,并且position 值为 static 或 relative ,盒子属性浮动定位。
- 绝对定位:如果元素的 position 为 absolute 或 fixed,该元素为绝对定位。绝对定位的元素相对于其包含块进行定位。
Viewport:
对于视口,这里给出w3c的定义:
User agents for continuous media generally offer users a viewport (a window or other viewing area on the screen) through which users consult a document. User agents may change the document's layout when the viewport is resized
个人理解:浏览器提供我们查阅文档的地方:即window窗口,即手机屏幕区域
containing block (包含块)
在CSS 2.1中,许多盒子的位置和大小是针对称为包含块的矩形框的边缘计算的。一般而言,生成的框充当后代框的包含块,一个盒子为它的后代“建立”包含块,每个盒子相对于其包含的块被赋予一个位置,但它不受该包含块的限制, 它可能溢出。
不同定位元素的包含块:
1:如果 position 属性是 static 或 relative 的话:包含块就是由它的最近的祖先块元素的内容区(content box)的边缘组成的。
2:如果 position 属性是 absolute 的话:包含块就是由它的最近的 非static定位 的祖先元素的padding box的边缘组成的。如果不存在满足条件的祖先元素,就为 ICB (初始包含块)
3:如果 position 属性是fixed 的话:这里需要区分当前的媒体类型,一般我们日常的使用情景就是在连续媒体下,包含块为 viewport
4:如果 position 属性是 absolute 或 fixed,包含块也可能是由满足以下条件的最近父级元素的padding box的边缘组成的:
- transform or perspective 属性值不为 none
- will-change 属性值为 transform 或 perspective
- filter 属性值不为none 或者 will-change 属性值为 filter (only works on Firefox).
另:ICB(initial containing block):
文档根元素所在包含块称为初始包含块;
初始包含块的的尺寸和位置,对于不同的媒体类型也是有不同的情况,但我们也只考虑连续媒体的情况:
尺寸:viewport的尺寸;
位置:首屏左上角
Normal flow:
即普通流:
正常流中的框属于格式化上下文,可以是块或内联,但不能同时使用。 块级框参与块格式上下文。 内联级别框参与内联格式化上下文。
Block formatting contexts
定义
A block formatting context is a part of a visual CSS rendering of a Web page. It is the region in which the layout of block boxes occurs and in which floats interact with other elements.
块格式化上下文是一个css的渲染区域,它是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。
创建BFC的方式:
- 根元素或包含根元素的元素;
- 浮动元素(元素的 float 不是 none);
- 绝对定位元素(元素的 position 为 absolute 或 fixed);
- 行内块元素(元素的 display 为 inline-block);
- overflow不为visible的块元素
- ….(这里mdn文档说明很全面,这里不全部列出)
BFC特性说明:
- BFC内部的元素按常规流的规则布局
- 一个BFC对应一个独立、封闭的渲染区域,子元素的CSS样式不会影响BFC元素外部,也就数说 ,BFC元素会隔离自身与父元素。
注:这里我们常见的例子就是对于外边距合并中:子元素的外边距溢出到父元素外边这种情况,我们为父元素设置 overflow:auto,可以解决这个问题,其背后的原理就是让父元素创建了一个BFC,这样父元素内部的css样式,就不会影响到外部。当然在BFC内部,兄弟元素之间的外边距,该合并还是会合并。 - 在计算BFC元素高度时,浮动的子元素,参与BFC父元素的高度计算
注:这里可以为父元素添加属性让其创建BFC,可以用来解决的就是因为浮动而造成的高度塌陷问题。 - 浮动盒区域不叠加到BFC上;
注:这里对于浮动元素后的块级元素,布局时会当浮动元素’不存在’来处理,这时候可能会发生块级元素被float元素遮盖的现象,这时候让被遮盖的元素创建BFC,可以避免被覆盖的情况出现。
Inline formatting contexts
特性:
- IFC内部的元素,按从左到右、从上到下的顺序排布(与文档方向有关)
- IFC内部的每个元素,都可以通过设置vertical-align属性,来调整在垂直方向上的对齐
- 包含这些内部元素的矩形区域,形成的每一行,被称为line box
另,除了BFC,IFC还有FFC(flex)、GFC(grid)等,这里不再详细说明。