z-index属性

318 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

抛出问题

在MDN中,z-index是如下定义的:

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

从定义可以看出,z-index生效的条件是:元素设置了定位,即position非static;这个也不难理解,如果是正常流排版,就不可能也不需要设置z-index,都在同一层级上,没有堆叠一说。既然是多个层级间的堆叠,那说明就得存在多个层叠上下文,通过position设置生成。

概念理解了,但还是碰到了难题:

<el-dialog>
  <el-form>
    <el-select>
      <el-option></el-option>
    </el-select>
  </el-form>
</el-dialog>

弹框和el-select都设置的是不插入body中,这样el-select就是el-dialog的子元素,但当el-select的下拉框z-index值小于el-dialog的z-index的值,仍然没有被覆盖,为什么呢?

现在的问题是当弹框内容滚动时,select下拉框超出弹框时,会浮现在弹框之上。

测试

都插入body中

把dialog和select都插入body中,则两者受z-index的影响,z-index值大的在上,小的被覆盖。这种情况不能用,矛盾了,你想啊,select下拉本身在dialog,肯定要显示出来的,z-index必然要大于dialog,则问题还会出现。

overflow

既然select下拉框的z-index值必然会高于弹框的,其实element官网版本测试也存在这个问题;那我们能否通过overflow属性设置为hidden来隐藏超出边界的下拉框呢?

经过测试也是不行。因为select下拉框和设置的 overflow:hidden 两者不在同一个层叠上下文中,所以overflow设置为hidden无法约束覆盖下拉框。

没办法了,只能暴力解决了。

解决方案

el-select的下拉框position属性是fixed,根据浏览器窗口定位计算,修改成absolute,根据select中的input框定位。element为什么要用fixed来定位计算呢?感觉更消耗性能呢,不理解。

先这样解决吧,明天再继续研究下有没有更优雅的方式。