纯 CSS 实现缕空遮罩层

4,574 阅读2分钟

需求

有很多网页在做引导时,遮罩层做成了缕空效果,最近我也遇到一个这样的需求,如图:

image

实现

常见方法

最容易想到的方法是切图,这个不用解释了。

在网上找到的大部分做法都是用边框,那么我们来看一下边框怎么实现这个效果。

<div class="mask"></div>

.mask {
    position: absolute;
    top: -1647px; // 由于边框宽度太大
    right: -1756px;
    filter: blur(15px);
    border-radius: 60px;
    border: 2000px solid rgba(0,0,0,.6); // 为了盖住整个页面,把边框设得比较大
    width: 155px;
    height: 80px;
}

实现效果如下:

image

仔细一看,咦,我的圆角呢?

原来是因为 border-width 设置越大,圆角会越不明显,超过一定数值就会变成直角(可以把 filter: blur(15px) 去掉看看),而且设置 border-radius 百分比为 50% 以上才有效,但是缕空部分就会整个变圆了。

圆角大作战

思考一下,想到了一个迂回的办法,我可以给遮罩加一个 ::before,然后用它来设置一个宽度小的边框,就可以实现圆角啦~ 那么在上面的基础上,再加几个样式:

/* 省略上面 */
.mask {
    overflow: hidden; // 用来隐藏 ::before 溢出
}
.mask::before {
    content: ' ';
    position: absolute;
    top: -10px;
    left: -10px;
    width: 100%;
    height: 100%;
    border-radius: 60px;
    border: 10px solid;
}

虽然稍微麻烦了点,不过这样就做出了我们想要的圆角了~!

缺点

  • 比较麻烦,圆角要用伪元素做。
  • 定位设置有点难计算,border-width 改变的话,相应地也要改 topleft 等。

有更好的方法吗

用上面的方法做完之后,我突然意识到用 box-shadow 做这个效果更简单Orz,代码如下:

<div class="mask"></div>

.mask {
    position: absolute;
    top: 350px;
    right: 244px;
    width: 155px;
    height: 80px;
    filter: blur(15px);
    border-radius: 60px;
    box-shadow: 0 0 0 2000px rgba(0,0,0,.6);
}

效果很完美(如果不考虑旧版浏览器的话 =w=),用这个方法更好,因为

  • 圆角轻松实现;
  • box-shadow 不会影响元素位置,定位只需要根据 content 的位置写。