# 格式化上下文
页面上的所有内容都是格式化上下文 formatting context 的一部分,或者是一个以特定方式显示的区域。
块格式上下文(BFC)将根据块布局规则布局子元素,灵活格式上下文 flex formatting context 将其子元素布局为灵活项 flex items 等。
每个格式上下文在其上下文中都有特定的布局规则。
格式化上下文的分类
- 块级格式化上下文
block formating contexts
- 内联格式化上下文
inline formating contexts
- 灵活格式化上下文
flex formating contexts
- 网格格式化上下文
grid formating contexts
# BFC
文档最外层元素使用块布局规则或称为初始块格式上下文。这意味着<html>
元素块中的每个元素都是按照正常流程遵循块和内联布局规则进行布局的。
# 创建新的 BFC
<html>
元素不是唯一能够创建块格式上下文的元素。任何块级元素都可以通过应用某些 CSS 属性来创建一个 BFC
以下情况都会创建新的块格式化上下文
- 使用
float
使其浮动的元素 - 使用
fixed
和sticky
进行绝对定位的元素 overflow
不为visible
的块级元素contains
为layout
content
或strict
的元素display: inline-block
的元素display:flow-root;
或display:flow-root list-item;
的元素display: table-caption;
的元素或表格的标题display: table-*;
的元素或表格的单元格flex
容器内的items
grid
容器内的items
columns
多列布局的items
column-span
为all
的元素
新的 BFC 的行为与最外层的文档非常相似,它在主布局中创造了一个小布局。
flow-root
display: flow-root;
flow-root
关键字的意义是,创建的内容本质上类似于一个新的根元素(如 <html>
所做),并确定这个新的上下文如何创建及其流布局如何实现。
# 清除浮动的问题
直接清除
子盒子设置浮动之后,父盒子如果没给高度就会自动变为 0,但是设置高度又不方便排版,因此我们需要给父盒子清除浮动带来的影响。
clear: left | right | both; 常用both直接清除左右浮动
额外标签法
在浮动元素末尾添加一个空的标签,例如
<div style="clear:both"></div>
、<br>
通俗易懂,但添加很多无意义的标签,结构化较差
伪元素
和额外标签法同理,不过是在 CSS 中添加 ,常常在公用 CSS 文件中设定
.clearfix:after {
content: "";
display: block; /* 设置为块级元素 */
clear: both; /* 清除两侧浮动 */
}
新的 BFC overflow
overflow: hidden;
新的 BFC flow-root
display: flow-root;
# 外边距合并的问题
- 两块级元素垂直,外边距合并,合并后的距离取两者间的较大值
- 两行内元素并排,外边距叠加,行内块元素同理
- 两块级元素嵌套,外边距合并
1 和 3 这两种情况是我们不想要的,需要解决,如何解决?
由于外边距仅在同一格式上下文中的元素之间折叠,因此我们可以给父元素创建新的 BFC。
overflow: hidden;
overflow: auto;
display: flow-root;
# IFC
行内格式化上下文是一个网页的渲染结果的一部分。其中,各行内框(inline boxes)一个接一个地排列,其排列顺序根据书写模式(writing-mode)的设置来决定。
在行内方向上,各行框(Line Boxes)通常具有相同的尺寸,即在水平书写模式下,它们有同样的宽度;在垂直书写模式下,它们有同样的高度。但是,如果同一个块格式化上下文中存在一个 float,则这个浮动元素将导致包裹了它的各行框变短。
内联格式上下文存在于其他格式上下文中,可以将其视为段落的上下文。段落创建了一个内联格式上下文,其中在文本中使用诸如 <strong>
、<a>
或 <span>
元素等内容。
# FFC
一个弹性容器建立一个新的弹性格式化上下文为其内容。这与建立块格式化上下文相同,只是使用 flex 布局而不是块布局。例如,浮动不会侵入 flex 容器,并且 flex 容器的边距不会与其内容的边距一起折叠。Flex 容器为它们的内容形成一个包含块,就像块容器一样。
# GFC
网格容器为其内容建立独立 的网格格式化上下文。这与建立独立的块格式化上下文相同,只是使用网格布局而不是块布局:浮动不会侵入网格容器,并且网格容器的边距不会与其内容的边距一起折叠。网格容器的内容被布置到网格中,网格线形成每个网格项的包含块的边界。