Page 186 - css揭秘
P. 186
如果把遮罩层交给这个元素自己的 ::before 伪元素来实现,就可以弥
补这些不足了。给伪元素设置 z-index: -1; 就可以让它出现在元素的背
后。尽管这解决了可移植性的问题,但无法对遮罩层的 Z 轴层次进行细粒度
的控制。它可能会出现在这个元素之后(这是我们期望的),但也可能会出
现在这个元素的父元素或祖先元素之后。
这个方法还有一个问题,伪元素无法绑定独立的 JavaScript 事件处理
函数。当遮罩层是由一个独立的元素来实现时,我们可以给它绑定事件处理
函数,比如当用户点击遮罩层时自动关闭弹出层。当使用弹出层自己的伪元
素来实现遮罩层时,就需要判断用户到底是点了弹出层还是遮罩层,这就变
得相当棘手了。
box-shadow 方案
上述伪元素方案相对灵活一些,通常可以满足绝大多数人对遮罩层的期
望。但对于简单的应用场景和产品原型来说,我们可以利用 box-shadow 来
达到调暗背景的效果:box-shadow 的扩张参数可以把元素的投影向各个方
向延伸放大。具体做法就是生成一个巨大的投影,不偏移也不模糊,简单而
拙劣地模拟出遮罩层的效果:
box-shadow: 0 0 0 999px rgba(0,0,0,.8);
这个初步的解决方案有一个明显的问题,就是它无法在较大的屏幕分
辨率(>2000px)下正常工作。我们要么加大数字来缓解这个问题,要么换
用视口单位来一劳永逸地解决它,只有这样才能确保“遮罩层”总是可以覆
盖(甚至超出)视口。因为我们无法分开指定水平和垂直方向上的扩张半
径,所以此处最合适的视口单位是 vmax。也许你对 vmax 单位还不熟悉,这
里简单介绍一下:1vmax 相当于 1vw 和 1vh 两者中的较大值。100vw 等于整
个视口的宽度,100vh 就是视口的高度。因此,满足我们需求的最小值就是
50vmax。由于投影是同时向四个方向扩展的,这个遮罩层的最终尺寸将是
100vmax 加上元素本身的尺寸。
box-shadow: 0 0 0 50vmax rgba(0,0,0,.8);
这个技巧非常简洁易用,但它存在两个非常严重的问题,从而制约了其
使用场景。你能指出这两个问题分别在哪里吗?
第一,由于遮罩层的尺寸是与视口相关,而不是与页面相关的,当我们
滚动页面时,遮罩层的边缘就露出来了,除非给它加上 position: fixed;
这个样式,或者页面并没有长到需要滚动的程度。此外,由于页面很可能真
的很长,为了规避这个缺陷而扩大投影的扩张半径就不太明智了。相反,我
推荐有限度地应用这个技巧,比如配合固定定位来使用,或者当页面没有滚
动条时再用。
32 通过阴影来弱化背景 155
ࠡ JOEC