浅谈为什么我的 z-index 又不生效了


Posted in HTML / CSS onJuly 15, 2022

表面看起来,z-index 似乎是一个很简单的属性,你给它设置哪个值,元素就会位于 z 轴的哪个位置。但它实际上并没有我们想象的这么简单,这个属性背后是一系列决定元素所在层级的规则。

在进行今天的介绍前,我们先列出三个问题,如果你能一眼看出它们的解决方案,那么恭喜你掌握了z-index,也就不需要阅读本文了;如果不行,那么耐心看完本文,相信能找到答案。

三个自测问题

  • 问题一:为什么z-index 数值更大,但 Content 没有在 Box 2 之上?
<div id="box1">
    Box 1
</div>

<div id="content">
    Content <br/>
    z-index: 2;
</div>

<div id="box2">
    Box 2 <br/>
    z-index: 1;
</div>
div {
    padding: 25px;
    font-size: larger;
}

#box1 {
    background-color: chocolate;
    width: 200px;
    height: 100px;
    margin-bottom: -50px;
}

#content {
    background-color: gold;
    width: 300px;
    height: 200px;
    z-index: 2;
}

#box2 {
    background-color: cyan;
    width: 200px;
    height: 100px;
    margin-top: -50px;
    z-index: 1;
}

浅谈为什么我的 z-index 又不生效了

  • 问题二:明明 z-index 数值更小,为什么 Content 这次反而在Box 2 之上了?
<div id="box1">
    Box 1
</div>

<div id="content">
    Content <br/>
    transform: rotate(90deg); <br/>
    z-index: 1;
</div>

<div id="box2">
    <br/>
    Box 2 <br/>
    z-index: 2;
</div>
div {
    padding: 25px;
    font-size: larger;
}

#box1 {
    background-color: chocolate;
    width: 200px;
    height: 100px;
    margin-bottom: -10px;
}

#content {
    background-color: gold;
    width: 250px;
    height: 200px;
    z-index: 1;
    transform: rotate(90deg);
}

#box2 {
    background-color: cyan;
    width: 200px;
    height: 100px;
    margin-top: -10px;
    z-index: 2;
}

浅谈为什么我的 z-index 又不生效了

  • 问题三:为什么明明 z-index 是最大的,但Box 2-3Content 之下?
<div id="box1">
    Box 1
</div>

<div id="content">
    Content <br/>
    z-index: 2; <br/>
    position: relative;
</div>

<div id="box2">
    <br/><br/>
    Box 2 <br/>
    z-index: 1; <br/>
    position: relative;
    <div id="box2-3">
        Box 2-3 <br/>
        z-index: 5;  <br/>
        position: absolute;
    </div>
</div>
div {
    padding: 25px;
    font-size: larger;
}

#box1 {
    background-color: chocolate;
    width: 200px;
    height: 100px;
    margin-bottom: -50px;
}

#content {
    background-color: gold;
    width: 200px;
    height: 100px;
    margin-left: 50px;
    z-index: 2;
    position: relative;
}

#box2 {
    background-color: cyan;
    width: 200px;
    height: 100px;
    margin-top: -50px;
    z-index: 1;
    position: relative;
}

#box2-3 {
    background-color: green;
    width: 200px;
    height: 100px;
    padding-left: 150px;
    left: 180px;
    top: -50px;
    z-index: 5;
    position: absolute;
}

浅谈为什么我的 z-index 又不生效了

z-index 简介

没有使用 z-index 的时候,元素的层叠关系由2个因素决定:

  • 该元素的position是否是static,如果是static,那么这个元素就称为 non-positioned ;反之,如果 position 值是 relative, absolute, fixed, 或 sticky 则称 positionedpositioned 元素享受特权,会覆盖 non-positioned 元素。而 non-positioned 元素中,有 float样式的元素覆盖没有 float 的。
  • 元素的“出场”顺序 —— 即在html中的顺序,同类型元素遵循后来者居上的原则。

z-index 属性设定了一个定位元素及其后代元素或 flex 项目的 z-order。当元素之间重叠的时候,z-index 较大的元素会覆盖较小的元素在上层进行显示。

所谓 z-index,只有在以下场景适用。分别为:

  • 首先,z-index这个属性并不是在所有的元素上都有效果。它仅仅只在 positioned 元素上有效果。
  • 要判断元素在 z轴 上的堆叠顺序,并不仅仅是直接比较两个元素的 z-index 值的大小,同时,这个堆叠顺序还由元素的层叠上下文和层叠等级共同决定。

层叠上下文

z-index 存在的一个背景是 Stacking Context ,中文常译作层叠上下文(其实数据结构中的栈的单词也是 stack,所以层叠上下文中已经蕴含了后来者居上的意思)。

层叠上下文,是HTML中一个三维的概念。在 CSS2.1 规范中,每个盒模型的位置是三维的,分别是平面画布上的X轴Y轴以及表示层叠的Z轴

一般情况下,元素在页面上沿 X轴Y轴 平铺,我们是察觉不到它们在Z轴上的层叠关系。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。

如果一个元素含有层叠上下文,(也就是说它是层叠上下文元素),我们可以理解为这个元素在Z轴上就“高人一等”,最终表现就是它离屏幕观察者更近。

浅谈为什么我的 z-index 又不生效了

构建层叠上下文和盖楼比较类似:

首先, <html> 元素是地平线或地基 —— 所有楼都是从地基开始盖的

接下来,每产生一个层叠上下文,相当于盖一座楼, z-index 的值相当于楼的高度

以下几种元素可以产生层叠上下文:

  • 元素的 position 值为 absoluterelative, 且 z-index 值不为 auto (默认值).
  • 元素的 position 值为 fixedsticky
  • 元素是 flexbox 容器的子元素, 且 z-index 值不为 auto (默认值)
  • 元素是 grid 容器的子元素, 且 z-index 值不为 auto (默认值)
  • 元素有 opacity 值且值小于 1.
  • 元素有以下任意一项的值,且值不为 none :
    • transform
    • filter
    • perspective
    • clip-path
    • mask / mask-image / mask-border
  • 元素有 isolation 值且值为 isolate.
  • 元素有 mix-blend-mode 值且值不为 normal.
  • 元素有 -webkit-overflow-scrolling 值且值为 touch.
  • 其他几种冷门的情况

第三,层叠上下文是可以嵌套的 —— 这是最容易让人误解的一块。

嵌套,顾名思义就是在一个 层叠上下文 中能创建 另一个层叠上下文

假如在地基上盖一座50米高的楼(即 z-index: 50), 是否可以在楼里再盖一栋 100米高的楼中楼呢?

当然不可能!但是你可以在这座楼里建一座 100 级阶梯高的大堂。

换句话说,在嵌套的层叠上下文中,子层叠上下文被限制在了父层叠上下文中,它们的 z-index “单位”已经不一样了(z-index 没有单位,这边只是用于理解),无论子层叠上下文的 z-index 值有多大都无法突破父层叠上下文的高度。

层叠上下文小结:

  • 元素的第一级层叠上下文
  • 特定样式的元素可以产生新的层叠上下文,且z-index的值在这些元素中才有效
  • 子层叠上下文的“高度”被限制在了父层叠上下文中
  • 在同级层叠上下文中,没有(有效) z-index 的元素依然遵循上一小节的规律;z-index 值相同的元素遵循后来者居上原则。

需要注意:层叠上下文嵌套元素嵌套 不是一一对应的关系,一个元素所处的父层叠上下文是由内向外找到的第一个能产生层叠上下文的元素所产生的层叠上下文。

看个例子便于理解:

<div id="div1" style="position: relative; z-index: 1">
  <div id="div2" style="position: relative; z-index: 1">
      所处的父层叠上下文是 div1 产生的层叠上下文
  </div>

  <div id="div3">
      <div id="div4" style="position: relative; z-index: 2">
          所处的父层叠上下文也是 div1 产生的层叠上下文
      </div>
  </div>
</div>

虽然 div4 外面还有层 div3,但是由于 div3 不能产生层叠上下文,所以 div4 所处的父层叠上下文也是 div1 (产生的层叠上下文) —— 虽然在html元素层级中 div4div2 更深了一级,但是 div4div2 在层叠上下文层面上是同级的,因此它们可以相互比较 z-index 值来决定谁在上面。

三个问题的解答

学习完上面的 z-index 相关知识点,我们来回答开头提出的三个问题。

  • 第一个问题中 z-index 不生效的原因在于这三个元素都不能产生层叠上下文,因此z-index值对它们不生效 —— 根据出场顺序决定了 Content 处在 Box 2 之下。

  • 第二个问题的 Box 2不能产生层叠上下文,因此z-index同样是无效的;Content 因为使用了 transform 属性,产生了层叠上下文,相当于盖了一座 1 米高的楼( z-index: 1 )

  • Box 2Content 在同一级层叠上下文中,且Box 2z-index 比较小, 因此 Box 2Content 之下;且 Box 2-3Box 2的层叠上下文下新建了个子层叠上下文,因此Box 2-3的高度被限制在了 Box 2 之内,因此 Box 2-3z-index 再高也没用。

到此这篇关于浅谈为什么我的 z-index 又不生效了的文章就介绍到这了,更多相关z-index不生效内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
HTML / CSS 相关文章推荐
纯CSS绘制漂亮的圆形图案效果
May 07 HTML / CSS
CSS3 flex布局之快速实现BorderLayout布局
Dec 03 HTML / CSS
CSS3绘制有活力的链接下划线
Jul 14 HTML / CSS
CSS3实现复选框动画特效示例代码
Sep 27 HTML / CSS
CSS3打造磨砂玻璃背景效果
Sep 28 HTML / CSS
自定义html标记替换html5新增元素
Oct 17 HTML / CSS
仿酷狗html5手机音乐播放器主要部分代码
May 15 HTML / CSS
阻止移动设备(手机、pad)浏览器双击放大网页的方法
Jun 03 HTML / CSS
HTML5 在canvas中绘制文本附效果图
Jun 23 HTML / CSS
使用HTML5进行SVG矢量图形绘制的入门教程
Feb 19 HTML / CSS
移动端html5判断是否滚动到底部并且下拉加载
Nov 19 HTML / CSS
微信小程序纯CSS实现无限弹幕滚动效果
Sep 23 HTML / CSS
纯CSS实现一个简单步骤条的示例代码
Jul 15 #HTML / CSS
CSS中使用grid布局实现一套模板多种布局
Jul 15 #HTML / CSS
如何解决flex文本溢出问题小结
Jul 15 #HTML / CSS
使用HBuilder制作一个简单的HTML5网页
使用CSS定位HTML元素的实现方法
CSS实现背景图片全屏铺满自适应的3种方式
Jul 07 #HTML / CSS
HTML实现仿Windows桌面主题特效的实现
Jun 28 #HTML / CSS
You might like
PHP开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
11个PHPer必须要了解的编程规范
2014/09/22 PHP
PHP+MySQL之Insert Into数据插入用法分析
2015/09/27 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
利用PHP如何统计Nginx日志的User Agent数据
2019/03/06 PHP
laravel 实现设置时区的简单方法
2019/10/10 PHP
js 页面执行时间计算代码
2009/03/04 Javascript
JavaScript中的字符串操作详解
2013/11/12 Javascript
解决extjs grid 不随窗口大小自适应的改变问题
2014/01/26 Javascript
jQuery插件Tooltipster实现漂亮的工具提示
2015/04/12 Javascript
JS实现的3D拖拽翻页效果代码
2015/10/31 Javascript
浅谈jquery点击label触发2次的问题
2016/06/12 Javascript
JS实现根据文件字节数返回文件大小的方法
2016/08/02 Javascript
关于javascript的一些知识以及循环详解
2016/09/12 Javascript
Extjs表单输入框异步校验的插件实现方法
2017/03/20 Javascript
vue.js开发环境搭建教程
2017/05/04 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
vue 修改 data 数据问题并实时显示的方法
2018/08/27 Javascript
iview通过Dropdown(下拉菜单)实现的右键菜单
2018/10/26 Javascript
vue两组件间值传递 $router.push实现方法
2019/05/15 Javascript
Vue移动端项目实现使用手机预览调试操作
2020/07/18 Javascript
解决vue项目获取dom元素宽高总是不准确问题
2020/07/29 Javascript
如何区分vue中的v-show 与 v-if
2020/09/08 Javascript
解决antd的Form组件setFieldsValue的警告问题
2020/10/29 Javascript
Python将阿拉伯数字转换为罗马数字的方法
2015/07/10 Python
python机器学习之神经网络(二)
2017/12/20 Python
python3库numpy数组属性的查看方法
2018/04/17 Python
详解Python中的正则表达式
2018/07/08 Python
利用pyshp包给shapefile文件添加字段的实例
2019/12/06 Python
CSS3实现千变万化的文字阴影text-shadow效果设计
2016/04/26 HTML / CSS
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
澳大利亚美容产品及化妆品在线:Activeskin
2020/06/03 全球购物
JSP和EJB可以共享HttpSession么?EJB里面可以改变session里面的内容
2013/06/05 面试题
汽车技术服务与营销专业在籍生自荐信
2013/09/28 职场文书
中秋节礼品促销方案
2014/02/02 职场文书
市场营销专业自荐书
2014/06/10 职场文书