Home > Article > Web Front-end > An easy-to-understand study of CSS cascading order and cascading context
Stacking order and stacking context are two concepts, but they are inseparable. The stacking order is very simple^_^, just think about it carefully, and the stack context is not worth mentioning. I only need to move the red line to you. I understand, everything said is too simple. The first paragraph is difficult to understand, but it is mainly because of this article that the displacement is resolved. Without further ado, let’s take a look at the sword.
Considering that two elements may overlap, W3C proposed the concept of cascading. Stacking refers to how to stack another element. For example, when two elements overlap, who should be in front and who should be in the back. So what are their rules? Let’s test the waters first.
Stacking order
When both elements are block-level elements, by default, the element at the back has a higher level
<style> div{ width:100px; height:100px; } .item1{ color:red; background-color:pink; } .item2{ margin-top:-100px; background-color:orange; }</style><div class="item1">item11111</div><div class="item2">item22222</div>
You can see that item2 covers item1, indicating that the level of the element at the back is higher The higher it is, the text of item1 is still vaguely visible, which shows that the level of the background is smaller than that of the text.
In addition, we can do this
<style> div{ width:100px; height:100px; } .item1{ color:red; } .item2{ margin-top:-100px; }</style><div class="item1">item11111</div><div class="item2"></div>
It seems that there is no item2 element. The main reason is that when no background is set, the background of the element is transparent and allows subsequent elements to be transparent. Come up.
Under this condition, you will find a very funny thing, as follows:
<style> div{ width:100px; height:100px; } .item1{ color:red; } .item2{ background-color:orange; margin-top:-100px; }</style><div class="item1">我是item2</div><div class="item2"></div>
If you don’t look at the code, it seems like this code really belongs to item2.
When two elements are inline blocks
<style> div{ display:inline-block; width:100px; height:100px; } .item1{ background-color:pink; } .item2{ background-color:orange; margin-left:-108px; }</style><div class="item1">item1111</div><div class="item2">item2</div>
The level of the latter element is higher than that of the previous element. However, unlike the two block-level elements, the background level of the inline block element is higher than the text.
When two elements are inline elements
<style> div{ display:inline; width:100px; height:100px; } .item1{ background-color:pink; } .item2{ margin-left:-48px; background-color:orange; }</style><div class="item1">item1</div><div class="item2">item2</div>
behaves the same as inline blocks, the background level is higher than the text, and the latter element is also higher than the previous element.
Small summary
When two elements are in normal flow, by default the latter element is higher level than the previous element and allows the following elements to show through.
If the two elements are block-level elements, the text level is higher than the background level (so the text will always show through regardless of whether the background text is set).
If it is an inline or inline block, the background is higher than the text level (so as long as the background is set, the latter element will not be visible).
When one element is a block-level element and the other is an inline block
<style> div{ width:100px; height:100px; } .item1{ display:inline-block; background-color:pink; } .item2{ margin-top:-100px; background-color:orange; }</style><div class="item1">item1</div><div class="item2">item2</div>
The inline block is higher than the block-level element, but the text is still higher than the background.
If another element is an inline element, the effect is the same. The code is as follows:
<style> div{ width:100px; height:100px; } .item1{ display:inline; background-color:pink; } .item2{ margin-top:-30px; background-color:orange; }</style><div class="item1">item1</div><div class="item2">item2</div>
当一个元素是行内块另一个是行内元素时
<style> div{ width:100px; height:100px; } .item1{ display:inline-block; background-color:pink; } .item2{ display:inline; margin-left:-100px; background-color:orange; }</style><div class="item1">item1</div><div class="item2">item2</div>
行内元素层级比行内块元素高,背景比文字层级高。
浮动系列
浮动和浮动,后一个比前一个层级高。
浮动和块元素,浮动层级高。
浮动和行内块,行内块层级高。
浮动和行内,行内层级高。
效果如下:
层叠顺序总结
当两个元素类型一样时,默认情况下后一个元素层级比前一个元素层级高。
在没有设置背景的情况下,元素的背景是透明的,并且允许后面的元素透上来。
块元素和其他任意除定位元素以外,文字层级比背景层级高。
浮动和块元素,浮动层级高。
浮动和行内块,行内块层级高。
浮动和行内,行内层级高。
定位和定位,后一个元素层级高。
定位比所有元素层级高。
它们的前后顺序:小于0的z-index
层叠上下文
如果你认真看完上一节,会不会奇怪一个问题,那就是在无特殊情况下为什么定位元素总是比普通元素层级高,另外一点就是,大部分情况下为什么总是后一个元素比前一个元素层级高,而罪魁祸首就是层叠上下文。
在HTML中有一个三维概念,也就是我们面向电脑屏幕的这一端为Z轴。
而凡是拥有层叠上下文的元素,将离用户最近,也就是越靠在Z轴前面。默认情况下只有根元素HTML会产生一个层叠上下文,并且元素一旦使用了一些属性也将会产生一个层叠上下文,如我们常用的定位属性。如两个层叠上下文相遇时,总是后一个层叠前一个,除非使用z-index来改变。如下:
<style> .box1{ width:100px; height:100px; background-color:red; } .box1 .item{ position:relative; height:100px; } .box2{ margin-top:-50px; width:100px; height:100px; background-color:orange; } </style> <div class="box1">box1 <div class="item"></div> </div> <div class="box2">box2</div>
虽然item产生了一个层叠上下文,但并不影响它父元素。它的父元素依然被box2层叠了。另外上面还说只要是产生层叠上下文的元素总是比其他元素层高,如下:
只需要给item加上一个背景即可,上一个案例只所以没看到item元素是因为背景默认是透明的,并且允许后面的元素透上来。
除了定位元素可以创建层叠上下文以外,还有如下几个属性也可以做到。以下来自MDN
根元素 (HTML),
z-index 值不为 "auto"的 绝对/相对定位,
一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
opacity 属性值小于 1 的元素
transform 属性值不为 "none"的元素,
mix-blend-mode 属性值不为 "normal"的元素,
filter值不为“none”的元素,
perspective值不为“none”的元素,
isolation 属性被设置为 "isolate"的元素,
position: fixed
在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
-webkit-overflow-scrolling 属性被设置 "touch"的元素
这里再拿opacity试水。
<style> .box1{ opacity:.9; width:100px; height:100px; background-color:red; } .box2{ margin-top:-50px; width:100px; height:100px; background-color:orange; }</style><div class="box1">opacity</div><div class="box2">box2</div>
原本应该是box2层叠box1的,但因为box1创建了一个层叠上下文,所以把box2层叠了。
知道层叠上下文有什么用?
最大的好处就是当你想要改变元素的层级又不想用定位时,你还可以用很多其他的方法。如下:
原本浮动比块元素层级高,但当使用了opacity之后,块元素层级比浮动层级高,代码如下:
<style> .box1{ float:left; width:100px; height:100px; margin-right:-20px; background-color:red; } .box2{ overflow:hidden; width:100px; height:100px; background-color:orange; opacity:.99; } </style> <div class="box1">float</div> <div class="box2">opacity</div>
总结
创建了层叠上下文的元素比其他元素层级高。
两个层叠上下文相遇时,后一个层级高。如果想改变层级可以使用z-index