• 黑色遮罩引导蒙版 CSS实现方式


    一、微云的实现

    网站有一些改动的时候,为了让用户熟知新的操作位置,往往会增加一个引导,常见的方式就是使用一个黑色的半透明蒙版,然后需要关注的区域是镂空的。

    然后上周五我去微云转悠的时候,也看到了引导层,于是职业病又犯了,去学习下别人是怎么实现的。下面是观测的结果:

    为了实现镂空蒙层效果,作者发挥了小时候拼积木的才能,使用两层HTML结构,内层使用5块独立区域拼接形成,至于中间镂空的区域的阴影则是使用的图片实现的。

    微云的实现

    微云的实现

    虽然最终的效果满足了产品的需求,对于用户而言,目的已经达到。但是,从代码质量层面、潜在的体验提升可能性、使用场景广度上来讲,还是弱了很多的。

    举例来说,如果我们某个提示区域面积很大,那中间的那个镂空区域尺寸是不是要变,那后面的背景图片怎么办?搞新图,有人看到了使用了background-size:cover, 那IE7,IE8怎么办?哦,可能微云不需要管IE7, IE8.

    如果不需要管IE7, IE8,那这里的实现就显得更加小白了。我们实际上只需要一层标签,一层空标签就可以实现我们的效果,且不需要图片。

    二、我的实现

    主要在于思维方式的变化。拼积木这种想法大家都比较容易想到,符合日常认知,但是,但代码层面,我们可以进行思维转换,发散思考,偌大的半透明遮罩层,我们不要老想着背景色块背景色块,可以突破常规思维,把它认为是边框,一个很大很大的边框(我们平时使用border都是1像素巨多),这样,我们自然就有了镂空效果。

    如下图示意:
    border实现蒙版

    但是,目前我们中间的镂空区域方的,有没有什么办法变成圆的呢?
    自然有,方法1是元素设置超大圆角,但是,此时为了边框依然填满整个屏幕,border边框尺寸要大大增大,但是,为了不影响页面的滚动条,我们必须再嵌套一层标签,就显得啰嗦了;
    方法2则是方法1某些方面的逆向思维处理,就是把当前元素作为外层限制标签,里面重新生成一个大尺寸伪元素,实现自适应尺寸的圆角效果,这个好,HTML干净不啰嗦,CSS一步到位(代码如下示意);

    .cover::before {     content: '';      100%; height:100%;     border-radius: 50%;     border: 400px solid #000;     position: absolute;     left: -400px; top: -400px;     /* 自己瞎填的参数,示意 */     box-shadow: inset 0 0 5px 2px rgba(0,0,0,.75); }

    大家可以看到,上面的伪元素的各个参数都是固定参数值,与外部元素的尺寸什么的没有任何关系,只要外部元素尺寸不超过400,里面永远会有一个正椭圆的内阴影的镂空图形(因为超出部分会被.cover隐藏),要理解圆角和正椭圆的关系,可以参考我之前的文章:“秋月何时了,CSS3 border-radius知多少?”。

    眼见为实,耳听为虚,您可以狠狠地点击这里:一层标签实现网站引导镂空蒙版功能demo (点击黑色蒙层会有引导切换效果)

    demo这个镂空蒙层所使用的HTML代码如下:

    <div class="cover"></div>

    没错,就这么简单,没什么嵌套,没有什么五个元素变形金刚合体,没有使用图片。

    微云这张图片3K多,以微云的用户访问量,估计流量费要不少钱的。

    而且,大家如果点击蒙版,会发现,镂空的区域大小每次都是不一样的,有大有小,有高有瘦,而微云的那个实现方法要满足此需求就棘手;而且,大家发现没,这些尺寸位置的变化都是动画来动画去的,不是嗙嗙嗙这种生硬的效果,更soft, 对用户视觉引导效果更好,你看,我从这里到这里了,为什么可以实现动画效果呢,因为我们的镂空和内阴影都是CSS实现的,而微云的图片方法,显然是无法有动画的。

    引导过渡动画效果

    JS代码辅助
    当然,我的实现也离不开JS的辅助,JS的工作很简单,让蒙层的width/height以及border大小和需要引导的元素相关联。

    我特意整了个可以公用的方法coverGuide(命名不喜欢自己随便改):

    var coverGuide = function(cover, target) {     var body = document.body, doc = document.documentElement;     if (cover && target) {         // target size(width/height)         var targetWidth = target.clientWidth,             targetHeight = target.clientHeight;          // page size         var pageHeight = doc.scrollHeight,             pageWidth = doc.scrollWidth;                  // offset of target             var offsetTop = target.getBoundingClientRect().top + (body.scrollTop || doc.scrollTop),             offsetLeft = target.getBoundingClientRect().left + (body.scrollLeft || doc.scrollLeft);                  // set size and border-width         cover.style.width = targetWidth + 'px';         cover.style.height = targetHeight + 'px';             cover.style.borderWidth =              offsetTop + 'px ' +              (pageWidth - targetWidth - offsetLeft) + 'px ' +             (pageHeight - targetHeight - offsetTop) + 'px ' +              offsetLeft + 'px';                  cover.style.display = 'block';                      // resize         if (!cover.isResizeBind) {             if (window.addEventListener) {                 window.addEventListener('resize', function() {                     coverGuide(cover, target);                 });                     cover.isResizeBind = true;             } else if (window.attachEvent) {                 window.attachEvent('onresize', function() {                     coverGuide(cover, target);                 });                 cover.isResizeBind = true;                                  // IE7, IE8 box-shadow hack                 cover.innerHTML = '<img src="guide-shadow.png">';             }         }     } };

    这里的coverGuide方法使用原生JS实现,IE6+浏览器都是兼容的,不依赖JS库,大家可以随意使用。当然,写得匆忙,没有严格验证,可能有bug,大家可以稍微留点心。

    使用非常简单,语法如下:

    coverGuide(cover, target);

    其中cover就是.cover这个单独的蒙版元素,target则是我们需要指引的元素,按钮啊,导航什么的。然后,我们的镂空区域自动定位到target的位置,大小也是target元素的大小。超省心。

    具体使用,可参考上面的demo,源代码就在页面上。

    IE7,IE8怎么办
    如果你需要兼容IE7,IE8,我们不妨就方框效果;如果设计和产品接受不了,则可以使用图片打个补丁,例如上面JS代码部分的:

    cover.innerHTML = '<img src="guide-shadow.png">';

    我demo使用的这个图片长下面这样:
    镂空图片for IE7,IE8

    大小还有阴影都是我自己随手一搞的,旨在示意,真实项目大家可以向设计师索要图片。

    然后,CSS超easy, 图片撑满我们的cover就可以。

    /* IE7, IE8 img */ .cover > img {      100%; height: 100%;     }

    三、结束语

    这种蒙版覆盖思想呢,不仅仅适用于这种大面积的引导。我们上传图片,尤其上传头像之后,要对头像进行剪裁,常见的交互之一就是四周黑色,中间镂空,也可以使用巨大border来实现我们的效果,一层标签足矣,根本不需要上下左右额外4层标签拼接合体实现。

    内部自适应的圆角效果单看文字,很多小伙伴估计不知道我在说些什么,建议去demo页面看下伪元素的代码,真实区域大小和最终效果,估计就会明白了。

    感谢阅读,欢迎交流,欢迎提供更好的实现方法,一定有的,只是我功力不够。

    以上~

    树懒开心的笑

  • 相关阅读:
    闭包详解
    年少不知富婆好,错把少女当成宝
    var a = ? if(a==1 && a==2 && a==3){ console.log(1); }
    vue中watch监听的handler,deep,immediate用法详解
    前端VSCode常用插件-快捷键-以及常用技巧
    如何看待 Web 开发构建工具 Vite?-------------转载自知乎
    如何关联多个远程仓库
    图解 | 原来这就是网络
    QMdiArea、QMdiSubWindow
    QDockWidget
  • 原文地址:https://www.cnblogs.com/jill1231/p/5452314.html
Copyright © 2020-2023  润新知