这篇文章主要介绍BFC和层叠上下文的相关知识点。
块格式化上下文(BFC)
一、BFC的定义
BFC(块级格式化上下文 Block Formatting Context): 是一个独立的渲染区域,盒子内部元素的布局不会影响到盒子外部。它属于普通流。
二、那些方式会创建块格式化上下文
1) 根元素(<html>) body
2) 浮动元素(元素的 float 不是 none)
3) 绝对定位元素(元素的 position 为 absolute 或 fixed)
4) 行内块元素(元素的 display 为 inline-block)
5) overflow 值不为 visible 的块元素
6) 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
7) 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
8) 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
9) 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
10) 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
11) display 值为 flow-root 的元素
12) contain 值为 layout、content或 paint 的元素
13) 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
14) column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
三、BFC特性及应用:
1) 同一个BFC下外边距会发生折叠,若想避免外边距的折叠,可以将其放在不同的BFC容器中
2) BFC可以包含浮动元素,也就是清除浮动
3) BFC可以阻止元素被浮动元素覆盖,可以用来实现两栏自适应
四、普通流定义
普通流: 就是元素按照其在HTML中的先后顺序自上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。
五、margin折叠规则
外边距折叠: 块级元素的上外边距和下外边距有时会合并(或折叠)为一个外边距,其大小取其中的最大者。注意浮动元素和绝对定位元素的外边距不会折叠。
发生外边距折叠的三种基本情况:
1) 相邻的两个元素之间的外边距会折叠(除非后一个元素需要清除之前的浮动)。
2) 如果在父元素与其第一个子元素之间不存在边框、内边距、行内内容,也没有创建块格式化上下文、或者清除浮动将两者的 margin-top 分开;或者在父元素与其最后一个子元素之间不存在边框、内边距、行内内容、height、min-height、max-height将两者的 margin-bottom 分开,那么这两对外边距之间会产生折叠。此时子元素的外边距会“溢出”到父元素的外面。
3) 如果一个块级元素中不包含任何内容,并且在其 margin-top 与 margin-bottom 之间没有边框、内边距、行内内容、height、min-height 将两者分开,则该元素的上下外边距会折叠。
参考链接:
MDN上的BFC概念
关于Block Formatting Context--BFC和IE的hasLayout
10分钟理解BFC原理
外边距重叠
层叠上下文
一、定义
层叠上下文: 假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。默认情况下,网页内容是没有偏移角的垂直视觉呈现,当内容发生层叠的时候,一定会有一个前后的层叠顺序产生。所有的元素都有层叠水平,文档根元素会创建层叠上下文。普通元素的层叠水平优先由层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义。
二、折叠顺序
图片侵权删
CSS的层叠顺序(从低到高): 层叠上下文元素的background/border(装饰属性) -> 负z-index -> block块状水平盒子(布局) -> float浮动盒子(布局) -> inline/inline-block水平盒子(内容) -> z-index:auto或看成z-index:0或者不依赖z-index的层叠上下文 -> 正z-index
注:z-index:0实际上和z-index:auto单纯从层叠水平上看,是可以看成是一样的。注意这里的措辞——“单纯从层叠水平上看”,实际上,两者在层叠上下文领域有着根本性的差异。z-index不为0时,position值为absolute和relative以及flex的项目z-index不为0时才能够产生层叠上下文。
三、折叠规则和特征
层叠规则:
1) 在同一个层叠上下文领域,层叠水平大的覆盖小的
2) 当元素层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素
层叠上下文元素的特征:
1) 层叠上下文的层叠水平要比普通元素高
2) 层叠上下文可以阻断元素的混合模式
3) 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文
4) 每个层叠上下文和兄弟元素独立,也就是当进行更改过层叠变化或渲染的时候,只需要考虑后代元素
5) 每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中
四、如何创建层叠上下文:
1) 文档根元素(<HTML>);
2) position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
3) position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
4) flex (flexbox) 容器的子元素,且子元素的 z-index 值不为 auto;
5) grid (grid) 容器的子元素,且 z-index 值不为 auto;
6) opacity 属性值小于 1 的元素。opacity的值不为1时,层叠顺序是z-index:auto级别,跟没有值的absolute绝对定位元素是平起平坐的;
7) mix-blend-mode 属性值不为 normal 的元素;
8) 以下任意属性值不为 none 的元素:
a. transform
b. filter
c. perspective
d. clip-path
e. mask / mask-image / mask-border
9) isolation 属性值为 isolate 的元素;
10) -webkit-overflow-scrolling 属性值为 touch 的元素;
11) will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素
12) contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。
例:
<!-- html -->
<div class="wrap">
<div class="box">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1575261998206&di=575862b8836db6fbf9b81b76b8e0aa47&imgtype=0&src=http%3A%2F%2Fimg8.zol.com.cn%2Fbbs%2Fupload%2F19571%2F19570481.jpg"
alt="">
</div>
</div>
/* style */
/* 1.文档根元素下,创建层叠上下文,那怕z-index为负,也会显示在背景色之上 */
body {
background: yellow;
}
.box {
position: relative;
z-index: -1;
}
/* 2.利用定位生成CSS层叠上下文,如果去掉wrap的定位或z-index就会导致图片跑到背景下面 */
.wrap {
position: relative;
z-index: 0;
width: 300px;
height: 300px;
background-color: yellowgreen;
}
.box {
position: relative;
z-index: -1;
}
img {
width: 200px;
}
/* 3.利用父元素flex和子元素z-index不为auto来使子元素生成层叠上下文 */
.wrap {
display: inline-flex;
width: 300px;
height: 300px;
}
.box {
z-index: 0; /* 此处生效 */
background-color: yellowgreen;
}
img {
position: relative;
z-index: -1;
width: 200px;
}
/* 4.利用opacity不为1生成层叠上下文 */
.wrap {
width: 300px;
height: 300px;
}
.box {
opacity: .5;
background-color: yellowgreen;
}
img {
position: relative;
z-index: -1;
width: 200px;
}
五、为什么inlin-block和inline的层叠顺序比浮动元素和块级元素都高?
因为float和块级元素一般都作布局,内联元素都是内容。而一个网页中最重要的就是内容,所以一定要让内容的层叠顺序相当高,这样可以在发生层叠时,重要的图片、文字内容可以优先暴露在屏幕上。
参考来源: MDN层叠上下文
张鑫旭CSS层叠上下文
以上内容如有不对,希望大家指出,谢谢。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。