CSS属性flow-root
是CSS Display Module Level3中的一个属性,了解flow-root
显示属性前需掌握BFC概念,掌握BFC前又需要先理解Box和Formatting Context的概念。
盒子(Box)
所有的HTML元素都可以看作是盒子,在CSS中Box Model
盒子模型用来设计和布局。盒子模型本质上是一个盒子并封装了周围的HTML元素,盒子由内到外依次包括内容(Content)、填充/内边距(Padding)、边框(Border)、边距/外边距(Margin)四大区域组成。

区域 | 标识 | 描述 |
---|---|---|
内容 | Content | 盒子的内容区域,显示文本、图像等。 |
内边距 | Padding | 清除内容周围的区域,内边距是透明的。 |
边框 | Border | 围绕在内边距和内容区域之外的边框 |
外边距 | Margin | 清除边框外的区域,外边距是透明的。 |
CSS盒模型描述了为文档树中的元素生成的矩形框,并根据可视化格式模型进行布局。浏览器在解析和渲染页面时会生成DOM树(DOMTree)和渲染树(RenderTree),CSS的作用是RenderTree,而盒模型就是RenderTree上的节点。

Margin、Border、Padding、Content分别定义了元素的4种边框,每种边框的4条边定义了一个盒子,分别对应的的是margin-box、border-box、padding-box、content-box。也就是说一个盒子实际上是由四个盒子组成的。

盒子 | 必须 | 描述 |
---|---|---|
content-box | 是 | 内容盒子由content area和4条inner edge组成 |
padding-box | 否 | 填充盒子由padding area和4条padding edge组成,若pading宽度为0则padding edge和content edge重叠。 |
border-box | 否 | 边框盒子由border area和4条border edge组成,若border宽度为0则border edge和padding edge重叠。 |
margin-box | 否 | 边框盒子由margin area和4条margin edge组成,若margin宽度为0则margin edge和border edge重叠。 |
box-sizing
CSS3中提供了box-sizing
属性用来控制盒子模型的表现形式,其取值范围包括content-box
、border-box
、inherit
。
box-sizing: <content-box> | <border-box> | <inherit>;
取值 | 描述 |
---|---|
content-box | 默认值,W3C标准盒模型。 |
border-box | IE盒模型 |
inherit | 从父元素继承box-sizing 的值 |
W3C标准和模型和IE盒模型只是在设置width和height时所指定的对象不同,若无特殊指定则默认使用的是W3C标准盒模型content-box
,即HTML文件开头指定<!DOCTYPE html>
即可。
视觉格式化模型(VFM)
视觉格式化模型(Visual Formatting Model)是用来处理文档并将其显示在视觉媒体上的一种机制(计算规则),视觉格式化模型会根据盒子模型将文档中的元素转换为盒子,每个盒子的布局由以下因素决定:
因素 | 描述 |
---|---|
盒子尺寸 | 分为精确指定、由约束条件指定、没有指定 |
盒子类型 | 分为行内盒子、行内级盒子、原子行内级盒子、块级盒子 |
定位方案 | 分为普通流定位、浮动定位、绝对定位 |
文档树相关元素 | 当前盒子的子元素或兄弟元素 |
视口尺寸与位置 | - |
图片尺寸 | 所包含的图片的尺寸 |
其他 | 其他外部因素 |
视觉格式化模型会根据盒子的【包含块】(Containing Block)的边界来渲染盒子,通常盒子会创建一个包含其后代元素的包含快,但盒子并不由包含块所限制,当盒子的布局跑到包含块的外边时则称之为溢出(overflow。)
视觉格式化模型定义了盒子Box的生成,盒子的类型由此可分为块盒、行盒、匿名盒以及一些实验性的盒子,盒子的类型主要由display
属性所决定。
盒子类型
CSS视觉格式化模型的一部分工作是从文档元素生成盒子,生成的盒子拥有不同类型,并对视觉化模型的处理产生影响,生成盒子的类型取决于CSS属性display
,盒子的类型会影响到视觉格式化模型中的表现。
Box盒子是CSS布局的对象和基本单位,简单来说,一个页面就是由若干个Box盒子组成。元素的类型和display
属性决定了Box盒子的类型。不同类型的Box盒子会参与不同的Formatting Context,这里的Formatting Context指的是一个决定如何渲染文档的容器,Box盒子内的元素会以不同的方式渲染。
CSS中常见的Box盒子类型分为块级盒子(块盒)和行级盒子(行盒)
类型 | 标识 | 属性 |
---|---|---|
块盒 | Block-Level Box |
display:block; / display:list-item; / display:table;
|
行盒 | Inline-Level Box |
display:inline; / display:inline-block; / display:inline-table;
|
块(Block)
关键词:块级元素(Block-Level Element)、块级盒子(Block-Level Box)、块格式化上下文(Block Formatting Context)、块级容器盒子(Block Container Box)
块级元素(Block-Level Element)是指源文档中以【块】的形式被格式化(比如段落),是生成【主要的块级盒子】(Principal Block-Level Box)的元素。为什么是主要的块盒?因为每个块级元素会生成一个主要的块级盒子(Principle Block-Level Box),而某些元素比如li
和list-item
则会生成【额外的盒子】来放置项目符号,这些额外的盒子会相对于主要块级盒子(Principle)来摆放。当然大多数元素只会生成一个主要的块级盒子,主要的块级盒子将包含后代盒子和生成的内容,同时会参与定位体系。
display
属性取值为block
、list-item
、table
的元素会自动转化为块级元素
块级盒子(Block-Level Box)是参与块格式化上下文(BFC,Block Formatting Context)的盒子
块级盒子也是一个块级容器盒子,除非它是一个表格盒子或替换元素的主盒,一个块容器盒子要么只包含块级盒子,要么只建立一个内联的格式化上下文并因此只包含行级盒子
一个主盒是块级容器盒子的元素是一个块容器盒子,当display
为block
、list-item
、inline-block
时是一个非替换元素会生成一个块容器。并非所有的块级容器盒子都是块级盒子,非替换的行内块和非替换的表格单元格也是块容器但并非是块级的。即是块级盒子同时也是块容器盒子的盒子才能称为块盒。

https://www.jianshu.com/p/60d747bf4e85
格式化上下文(Formating Context)
Formatting Context格式上下文是W3C CSS2.1规范中的概念,它是页面中的一块渲染区域,并有一套渲染规则,它决定了子元素将如何定位,以及和其他元素的关系和相互作用。
格式化上下文是初始化元素定义的环境,主要包括两个要点,一个是元素定义的环境,一个是初始化。
CSS中元素定义的环境分为两种分别是BFC块格式化上下文和IFC行内格式化上下文,这两种上下文定义了在CSS中元素所处的环境。格式化表明在这个环境中元素应当如何被初始化如何布局等。
常见的Formatting Context格式上下文分为
名称 | 全称 | 描述 |
---|---|---|
BFC | Block Formatting Context | 块级格式化上下文 |
IFC | Inline Formatting Context | 行内格式化上下文 |
FFC | Flex Formatting Context | 弹性格式化上下文 |
GFC | Grid Formatting Context | 栅格格式化上下文 |
块级格式化上下文(BFC)
BFC(Block Formatting Context)块级格式上下文是一个独立的布局环境,可立即为一个箱子,箱子中物品的摆放是不受外界的影响的。因此利用BFC可以消除浮动元素对非浮动的兄弟元素和子元素带来的影响。在BFC中块盒和行盒都会垂直的沿着父元素的边框排列。
BFC块级格式上下文是一个独立的渲染区域,只会有Block-Level Box
块级盒子参与,BFC规定了内部的块级盒子如何布局,并且与此区域外部毫不相干。
自动会为内容创建BFC块级格式上下文的属性
- 浮动元素,float属性值不为none。
- 绝对定位元素,position属性不为static或relative。
- 非块级盒子的块级容器,比如:inline-block、table-cell、table-captions、flex、inline-flex。
-
overflow
不为visible
的块级盒子
BFC块级格式上下文的布局规则
- BFC内部的Box会在垂直方向一个接一个地放置
- Box垂直方向的距离由margin决定
- 同一个BFC的两个相邻的Box的margin会发生重叠
flow-root
display:flow-root;
display:flow-root
是一种新的块级布局方式,它在display:block
块级布局的基础上对子元素的浮动float
属性进行了修正。由于display:block
块级布局的父级容器中若出现浮动的子元素,当浮动子元素的高度大于父级容器时,会存在父级容器高度塌陷的问题。因为块级布局不会考虑到浮动元素的大小,当浮动元素很大的时候会出现浮动元素溢出容器的情况。
例如:块级布局高度坍塌
<style>
*{margin:0; padding:0;}
.container{display:block; width:300px; margin:50px; background-color:#eee; text-align:left;}
.item-1{float:left; width:50px; height:150px; background-color:#f00;}
.item-2{width:100px; height:50px; background-color:#0f0;}
.item-3{width:100px; height:50px; background-color:#00f;}
</style>
<div class="container">
<div class="item-1">1</div>
<div class="item-2">2</div>
<div class="item-3">3</div>
</div>
当父容器.container
采用display:block
设置为块级布局时,子元素item-1
同时设置了浮动。由于item-1
子元素的高度大于父级容器,所以此时出现浮动元素溢出容器的情况。如果需要让浮动的子元素撑开父级元素,此时可以将父级容器.container
的布局修改为flow-root
。


什么是flow-root
布局呢?
flow-root
布局的元素会生成一个块容器框,块盒中的内容使用流动布局,并为容器中的内容建立一个新的块级格式化上下文(BFC)。简单来说,flow-root
是创建BFC块级格式化上下文的一个显示属性。
由于BFC中元素的布局不会受到外界的影响,而且在一个BFC中,块级元素和行内元素都会垂直的沿着父元素的边框排列,因此可用来清除浮动元素对其兄弟元素和子元素的影响。
例如:在卡片布局中使用浮动时出现的问题
<style>
.container{outline:solid #ddd; padding:1em; background-color:#f2f2f2;}
.container .img{float:left; margin-right:1em;}
</style>
<div class="container">
<img src="https://source.unsplash.com/300x300/?book,library" class="img" />
<div class="text">标题文本</div>
</div>
父容器中图片使用浮动后,图片高度大于父容器,此时发生了内容溢出,父容器高度坍塌。

当为父容器添加display:flow-root
以触发BFC块级格式化上下文时,此时图片子元素浮动带来的高度坍塌问题得以解决。
.container{outline:solid #ddd; padding:1em; background-color:#f2f2f2; display:flow-root;}

例如:分栏时使用flow-root清除浮动元素对兄弟元素的影响
<style>
.side{width:10%; min-height:400px; background-color:#f2f2f2; float:left; margin-right:1%;}
.main{min-height:400px; background-color:#d2d2d2; display:flow-root;}
</style>
<div class="side">side</div>
<div class="main">main</div>
当给左侧side
元素添加浮动以脱离文档流,此时side
的margin-right
对main
并非生效。

当为main
设置了display:flow-root
后,side
的margin-right
开始生效。

例如:使用flow-root解决magin合并问题
网友评论