CSS之视觉格式化模型

@豆丁 / 通用部

主要内容

什么是“盒子”

如何定位

Q&A

大概介绍

大概介绍

CSS里面,布局需要确定的两个关键信息就是大小位置

这个就是视觉格式化模型所控制的事情

为什么要讲主题这个呢?

写 CSS 的时候头脑清晰,能在写的时候就知道最终的布局效果大概会是什么一个样子

在一些特殊布局场景下,能够想出更多解决方案

什么是“盒子”

盒子就是CSS渲染引擎用于确定布局的基本单位

HTML中的每个元素在布局的时候会生成一个(或者多个,情况较少,这里不展开)与其对应盒子

一个不是很恰当的例子

盒子

HTML元素

不恰当在哪里呢?

布局完成后盒子最终计算出来的大小和位置信息是精确的

有多少种盒子(块级)

块级盒子(block-level box)

块容器盒子(block container box)

块盒子(block box)

块级元素生成的盒子,侧重于描述盒子在布局中的作用和影响

块容器盒子,侧重于其作为“容器”这一个角色,描述盒子与其后代之间的关系

一个容器既是块级盒子,又是块容器盒子

有多少种盒子(块级)

会有一点点误导性...

有多少种盒子(行内级)

行内级盒子(inline-level box)

行内盒子(inline box)

原子行内级盒子(atomic inline-level box)

行内级元素生成的盒子,侧重于描述盒子在布局中的作用和影响,它包含了下面两种盒子

盒子所包含的内容会受盒子的布局影响

盒子包含的内容不受盒子所在的布局上下文影响(替换元素)

那么什么决定了盒子的类型呢?

display 属性

不同的 display 属性决定了盒子的类型

inlineinline-block 会生成行内级盒子

block 会生成块级盒子

如何布局

盒子一旦生成完毕,CSS 引擎就要决定它们在页面中的位置以及大小来完成布局

决定盒子排列的规则 - 格式化上下文

格式化上下文(formatting context)是一套规则,它规定了盒子该如何排列和盒子大小计算方式

 

并且不同类型的盒子会遵循不同的上下文

 

块级盒子一般会遵循 块格式化上下文(BFC)

行内级盒子一般会遵循 行内格式化上下文(IFC)

排列的参考系和边界 - 包含块

可以把包含块(containing block)理解为盒子的容器,盒子在布局的时候始终是以这个容器作为定位的参考系

包含块

小蓝的包含块是小红

小红小蓝是两个 div 元素生成的盒子

小红的包含块是HTML元素生成的盒子

HTML生成的盒子的包含块成为初始包含块

初始包含块(initial containing block)以浏览器视区作为参考系

包含块

display 为 block 或者 inline-block 的元素生成的盒子会作为其后代盒子的包含块

 

一个包含块要么采用块格式化上下文,要么采用行内格式化上下文,总之只会使用一种格式化上下文

块格式化上下文(Block FC)

大致规则(下文中的盒子都指的是块级盒

1.盒子的宽度会自动充满包含块的宽度

2.盒子会从上到下依次排列

3.相邻两个盒子的 margin 会合并

4.计算包含块高度的时候会把浮动元素考虑进去

只要包含块里面有一个块级盒子,这个包含块就会采用块格式化上下文

行内格式化上下文(Inline FC)

我们需要引入一个新概念叫行盒(line box)

用来包含一行内行内级盒的矩形区域称为行盒

行内格式化上下文(Inline FC)

为什么是一行呢?

这时候有两个行盒

行内格式化上下文(Inline FC)

大致规则

1.行内级盒子会从左往右水平依次排列

2.行盒由上往下垂直排列,它们之间没有垂直间距也没有重叠

行内格式化上下文(Inline FC)

大致规则

3.行盒一般情况下会充满包含块的宽度,但同时也会受浮动元素影响

行内格式化上下文(Inline FC)

大致规则

4.行盒一定会高到足以容纳该行的所有盒子

行内格式化上下文(Inline FC)

大致规则

4.行盒一定会高到足以容纳该行的所有盒子

行内格式化上下文(Inline FC)

大致规则

5.当行内级盒子的高度小于行盒的高度时,这个行内级盒的水平位置由 vertical-align 属性决定。

 

行盒高度计算还可以专门写一篇文章.. 所以我们这里先不解释

行内格式化上下文(Inline FC)

大致规则

6.行内级盒小于行盒的宽度时,可以通过 text-align 来控制行内级盒的位置

行内格式化上下文(Inline FC)

大致规则

6.行内级盒小于行盒的宽度时,可以通过 text-align 来控制行内级盒的位置

行内格式化上下文(Inline FC)

大致规则

7.如果一个行内级盒超过了行盒的宽度,那么它会被分割,分布在几个行盒中

行内格式化上下文(Inline FC)

大致规则

如果包含块里面包含的全是行内级盒子,那么这个包含块会采用行内格式化上下文

会使用哪种格式化上下文呢?

.container 会采用块格式化上下文

会使用哪种格式化上下文呢?

.container 会采用行内格式化上下文

会使用哪种格式化上下文呢?

.container 会采用块格式化上下文

为啥捏?

小小的总结

如果包含块内只包含行内级盒子,那么就会使用行内格式化上下文

如果包含块内包含了至少一个块级盒子,那么就会使用块格式化上下文

布局的类型

正常流(normal flow):前面所描述的所有格式化上下文都属于正常流的范畴,之所以叫”normal“,就是默认情况下如果我们没有使用 position 属性(或者使用了但属性值为 static 或者 relative)和 float 属性,盒子布局就属于正常流的范畴。

 

绝对定位:position 为 fixed 或 absolute

浮动定位:float 不为 none

痛点之我的vertical-align怎么无效?

给小文字加一个 middle

给大文字加一个 middle

痛点之我的vertical-align怎么无效?

痛点之我的vertical-align怎么无效?

1. 行盒会在能包含所有行内级盒的前提下,尽可能保证行盒生成的高度最小

2. vertical-align: middle 的效果是把当前盒子的垂直中点位置与行盒的 baseline 位置对齐

重现一下排列步骤

给“BIG”加一个 middle

重新生成行盒以保证高度尽可能小

总结

给高度最高的元素加上 vertical-align: middle 属性即可

Q&A

CSS之视觉格式化模型

By 小新

CSS之视觉格式化模型

  • 450