专栏首页Golang语言社区一篇通俗易懂的CSS层叠顺序与层叠上下文研究

一篇通俗易懂的CSS层叠顺序与层叠上下文研究

网上有很多这方面的教程,但不是苦涩难懂就是从哪copy过来的,反正很长一段时间我是没看懂,时间长了也没打算去研究了,主要原因是,基本上很少会遇到那些问题(所以说啊,要是没有研究精神的才懒得管它)。但自从开始研究CSS以后就一发不可收拾,所以打算把CSS一系列的东西都给研究一遍,当然能研究懂自然是好的,不能就当自娱自乐了。话说这个层叠顺序和堆栈上下文没啥用对吧,你看我就是不学它,平时也没出什么问题。 …… 想让它出问题也很简单,不过既然你都说没用了,也就不打算告诉你了。

本篇属于短话长说型,前半部分比较简单,但不看会影响后面你是否有勇气看下去,建议全看,但如只是想了解一下,可以只看总结部分,但都看你自己。

层叠顺序和层叠上下文是两个概念,但它们又有着密不可分的关系,层叠顺序很简单^_^,认真思考即可,而堆栈上下文更是不值一提,我只需要迁根红线你就懂了,所有说,都太简单。第一段说难懂,主要是有了这篇文章,才化解位移。废话少说,看剑。

在考虑到两个元素可能重合的情况下,W3C提出了层叠这个概念,层叠是指如何去层叠另一个元素,比如两个元素重合的时候应该让谁在前面,谁在后面。那它们的规则又是什么?先来试水。

层叠顺序篇

当两个元素都是块级元素时,默认情况越后面的元素层级越高
<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>

可以看到item2item1给盖住了,说明越后面的元素层级越高,另外item1的文字还是隐隐约约的可以看到,这说明了背景的层级比文字小。

另外我们可以这样

<style>
    div{        width:100px;        height:100px;
    }    .item1{        color:red;
    }    .item2{        margin-top:-100px;
    }</style><div class="item1">item11111</div><div class="item2"></div>

可以看到好像没有item2这个元素一样,主要原因是,在没有设置背景的情况下,元素的背景是透明的(transparent),并且允许后面的元素透上来。

在这种条件下,你会发现一个很搞笑的事,如下:

<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>

如果不看代码,就好像这段代码真的是item2的。

当两个元素为行内块时
<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>

也是后一个元素的层级比前一个元素的层级高,不过和两个块级元素不同的是行内块元素的背景层级比文字高。

当两个元素为行内元素时
<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>

和行内块的行为一样,背景层级比文字高,并且也是后一个元素比前一个元素层级高。

小总结

  • 当两个元素为正常流时,默认情况下后一个元素比前一个元素层级高,并且允许后面的元素透上来。
  • 如果两个元素是块级元素,文字比背景层级高(因此不管是否设置背景文字始终会透上来)。
  • 如果是行内或行内块,背景比文字层级高(因此只要设置背景,后一个元素将透不上来)。
当一个元素为块级元素,另一个为行内块时
<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>

行内块比块级元素层级高,依然是文字比背景层级高。

如果另外一个元素是行内元素和这个效果也是一样的,代码如下:

<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 < 块 < 浮动 < 行内块 < 行内 < 定位 < 大于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层叠了。

总结

  • 创建了层叠上下文的元素比其他元素层级高。
  • 两个层叠上下文相遇时,后一个层级高。如果想改变层级可以使用z-index

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-10-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 定位浮动拾遗

    ---恢复内容开始--- 浮动元素处在正常文档流上的浮动流上,浮动元素的渲染方式很特殊,首先按照正常文档流进行布局,然后将该元素从 文档流中取出并对该元素尽量向...

    欲休
  • css截断长文本显示

    实现 截断长文本显示处理,以前是通过后台的截取,但这种方法容易丢失数据,不利于SEO。 而通过前端css的截断,则灵活多变,可统一运用与整个网站。 这项技术主要...

    欲休
  • 居中详解

     讲解 1,单行文本的居中:           <div class='center'><span>单行文本框居中</span></div>         ...

    欲休
  • js实现css3的过渡,需要注意的一点(浏览器优化)

    大部分浏览器对元素几何改变时候的重排做了优化。据说是这样子,一定时间内本应多次重排的改变,浏览器会hold住,仅一次重排。其中如果使用分离的一步处理过程,例如计...

    欲休
  • table-cell实现宽度自适应布局

    利用table-cell可以实现宽度自适应布局。 table-cell有一些比较好用的属性,比如垂直居中,自适应高度宽度等,为元素设置table-cell布局之...

    欲休
  • 隐藏的几种实现

     页面布局上隐藏,但是对屏幕阅读器可见的几种方式:      1, .h{position:relative; left:-900em;top:-900em;...

    欲休
  • IE6下的png透明图片的背景定位

    在IE6下PNG透明图片做背景,无法使用background-position进行定位。但是可以使用margin和绝对定位来进行。 另外,由于IE6下的 :ho...

    欲休
  • 关于IE6的PNG图像透明使用AlphaImageLoader的缺点

    PNG32的alpha透明效果在IE6下会出现bug,出现灰色背景。而目前的解决方案就是 IE提供的滤镜。需要注意的是滤镜并不是对原图片进行修改,而是对相应的h...

    欲休
  • 清除inline-block元素之间的空白

    一个元素如果被设置为display:inline-block,那么这个元素将表现为行内块的性质。被设为行内块的元素 对内(子元素)表现为块级框,具体为可以设置高...

    欲休
  • 清除浮动的原理剖析

    常用的清除浮动的几种方法总结下:   1,手动设置一个标签(在浮动元素下方),然后对其设置clear属性     2,给浮动元素设置 :after伪类,创建块元...

    欲休

扫码关注云+社区

领取腾讯云代金券