给弹窗下增加一个半透明遮罩以及z-index的使用陷阱

1,031 阅读3分钟

当页面出现弹窗时,我们更可能会期望用户只会在弹窗上执行操作,而非点击弹窗外面的内容。 此时,最优雅的方式应该是在弹窗下面加一个半透明的黑色遮罩。

两个作用:

  1. 使用户的注意力聚焦于弹窗。
  2. 使用户不能点击弹窗外的内容,从而造成数据干扰。

jQuery遮罩(Mask)实现

HTML:

<div id="mask" class="mask"></div>
<a href="javascript:;" onClick="showMask()" >显示遮罩层</a><br>
<a href="javascript:;" onClick="hideMask()" >隐藏遮罩层</a>

CSS:

.mask {       
    position: absolute;
    top: 0px;
    left: 0px;
    background-color: #777;
    z-index: 9;
    filter: alpha(opacity=60); //IE透明度
    opacity:0.5; //Chrome
    -moz-opacity:0.5; //fireFox
}

jQuery:

//显示遮罩层
function showMask(){
    $("#mask").css("height",$(document).height());
    $("#mask").css("width",$(document).width());
    $("#mask").show();
}
//隐藏遮罩层
function hideMask(){
    $("#mask").hide();
}

上面的逻辑很简单,按照你本身的业务逻辑来编写就可以。比如,当你的弹窗出现的时候,直接调用showMask方法。当弹窗需要关闭的时候,调用hideMask方法。

但是要注意的是z-index的生效逻辑。
最简单的用法是,把mask和你的弹窗放到DOM同一等级,同时把弹窗的z-index设一个比mask大的值。

因为z-index有一些使用原则和使用陷阱。

z-index

使用时的注意项:

  1. z-index只能在position属性值为relative或absolute或fixed的元素上有效。
  2. 当你在一个positioned元素上应用z-index,会隐式创建一个全新的层叠上下文,这个元素同时成为了该层叠上下文的根元素。

层叠上下文和BFC(Block Formatting Context)有所区别:
层叠上下文解决元素次序问题(一个元素是否排在另一个元素之前),而BFC解决文档流和一个元素是否会被重叠。

  1. 父元素决定z轴的范围,子元素决定范围内的等级。

这个原因也导致了“为什么会出现大z-index值的元素会被覆盖

z-index不生效的原因

1. 父级元素溢出隐藏或者不显示

父元素设置了 overflow:hidden /display:none/ 等,此时子元素如果在父元素外部绝对定位,那么调节子元素 z-index 可能不会显示。

.father {
  display: none;
  opacity: 0;
  overflow: hidden; (auto)
  position: relative;
}
.son {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 100;
}

解决方案:取消父元素的上述属性。

2. 父级元素层级低

<div style="z-index: 1">
  <div style="z-index: 10">son</div>
</div>
<div style="z-index: 2"></div>

解决方案:查看父元素的 z-index 并修改

3. 没有设置定位

z-index使用的前提是,需要设置div的定位position(eg: position: absolute;)
如果元素是标准流,没有定位,那么设置z-index不会生效。

<div style="position:'absolute'; z-index: 10"></div>

解决方法:设置当前元素和父级元素的position

4. IE 浏览器不兼容

z-index 有一个属性 inherit,表示子元素继承父元素的 z-index。这个参数在 IE 浏览器上不兼容。

目前没有很好的直接解决方案,可以使用其他的 CSS 代替 z-index(float等)。

如果项目中层级很复杂(界面 1, modal 100, dialog 1000, mask 500),为了避免层级混乱,最好把 z-index 维护在一个公共的组件内部(一个单独的CSS文件或者单独的JS文件中,使用行内样式),这样修改和后期维护比较方便。