巧用阴影、mask以及css变量来实现元素聚焦效果

安全部
• 阅读 749

巧用阴影、mask以及css变量来实现元素聚焦效果

前言

嘿,之前我好像有段时间没写博客了。其实最大的原因就是我变得有点懒了。不过,现在毕业快到了,我也不能一直偷懒下去啊。对我来说,选择写代码作为职业方向是一件好玩的事情,而在此方向上,持续学习是最重要的事情之一。写博客就是一种非常好的方式来帮助自己持续学习,并且可以当作自己的成长记录,回味无穷。

最近遇到了一个这样的需求,有一个消息列表,希望可以在某条消息中实现聚焦,即除了应该聚焦的消息外的消息都会被一个黑蒙蒙的遮罩所遮住。

巧用阴影、mask以及css变量来实现元素聚焦效果

那么遇到这种不常见的需求,我们首先就需要思考技术方案。

技术方案

1.Mask遮罩

我最开始想到的是通过使用CSS渐变以及遮罩的方式来实现。

具体思路如下,首先利用IntersectionObserver监听指定元素,如果它进入视图中,就可以将其topheight属性以「CSS变量」的方式赋值给Mask元素,Mask即可通过CSS变量的方式进行渐变计算,从而最终显示出聚焦效果。

整个HTML文档结构如下:

<div class="box"> // 滚动列表盒子
    <ul class="list"> // 列表盒子,利用after伪元素来实现遮罩
      <li class="item">1</li>
      <li class="item">2</li>
      <li class="item">3</li>
      <li class="item">4</li>
      <li class="item">5</li>
      <li class="item">6</li>
      <li class="item">7</li>
      <li class="item">8</li>
      <li class="item">9</li>
      <li class="item" id="target">10 (target)</li> // 需要聚焦的元素
      <li class="item">11</li>
      <li class="item">12</li>
      <li class="item">13</li>
    </ul>
  </div>

JS代码的主要作用其实就是去监听目标元素的显示,从而切换遮罩显示:

 const intersectionObserver = new IntersectionObserver((entries) => {
    const entry = entries[0]
    if (!entry) return
    const Mask = document.querySelector('.list')
    if (entry.isIntersecting) {
      // 可视领域
      const rect = entry.boundingClientRect
      const { height } = rect
      Mask.style.setProperty('--height', height + 'px')
      Mask.style.setProperty('--top', entry.target.offsetTop + 'px')
    } else {
    // 不显示,则设置渐变令其透明
      Mask.style.setProperty('--height', entry.rootBounds.height + 'px')
      Mask.style.setProperty('--top', 0 + 'px')
    }

  });
  // 开始监听
  intersectionObserver.observe(document.querySelector('#target'));

我们利用mask,即mask中不透明的部分会使得背景图被遮住的特性来控制遮罩的位置。

最关键的CSS变量计算核心代码如下:

.list::after {
      content: '';
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.46);
      mask: linear-gradient(180deg, #000 calc(var(--top) -  var(--height)), transparent var(--top), #000 calc(var(--top) + 2 * var(--height)));
    }

于是,一个简单的聚焦效果就完成啦~

最终效果可以点击利用mask和css变量实现元素聚焦功能所示

2.BoxShadow阴影遮罩

对于box-shadow属性,我们可能都不太陌生,我们经常用它来实现各种类3D的样式,例如按钮、卡片等组件中。但是,当我们将box-shadow的扩散半径调成无限大的时候,它不就成为了一个最好用的遮罩了嘛?而且也并不会遮挡住目标元素。

「注意」:这里需要注意的是,box-shadow阴影会被后续相邻的元素所遮挡,这时可以配合相对定位来解决。

这种方式与前者相比,代码量少得可不是一丁半点,具体的模糊效果可以根据具体需要来自行调节。

核心代码如下:

 .focus {
      position: relative;
      box-shadow: 0px 0px 28px 1000px rgba(0, 0, 0, 0.59);
}
 const intersectionObserver = new IntersectionObserver((entries) => {
    const entry = entries[0]
    const target = entry.target
    if (!entry) return
    if (entry.isIntersecting) {
      // 可视领域
      target.classList.add('focus')
    } else {
      target.classList.remove('focus')
    }

  });
  // 开始监听
  intersectionObserver.observe(document.querySelector('#target'));

最终效果可以点击利用阴影实现元素聚焦功能所示

总结

以上是两种利用CSS技术实现元素聚焦效果的方案。虽然这两种方案都是利用CSS的特性来达到遮罩的效果,但是它们的实现方式有所不同,对应的CSS属性和代码也有所区别。

对于使用mask遮罩的方式,需要利用CSS变量以及渐变来控制遮罩的位置和效果,比较适用于需要实现复杂渐变效果的场景;而对于使用box-shadow遮罩的方式,则相对更加简单,代码量更小,比较适用于一些简单的遮罩效果。

不过无论是哪种方案,它们都提供了一种新的思路和思考方式,让我们在开发中更加灵活和高效地运用CSS技术。

巧用阴影、mask以及css变量来实现元素聚焦效果

我是<span style="color:#87481f;font-weight:bold">「盐焗乳鸽还要香锅」</span>,喜欢我的文章欢迎关注噢

  • github 链接https://github.com/1360151219
  • 博客链接是 strk2.cn
  • 掘金账号、知乎账号、简书《盐焗乳鸽还要香锅》
  • 思否账号《天天摸鱼真的爽》
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
徐小夕 徐小夕
3年前
前端: 如何更高效的学习Css? 有哪些库值得推荐?
之前有很多朋友问我如何快速学习css以及有哪些好用的css库,最近也抽出时间思考整理了一下,今天就和大家分享一下我的经验.如何高效学习Css之前在工作中也使用css做过很多有意思的事情,比如用css画图标,写轮播图,写动效,做布局等等,但是这些应用的实现都依赖于html和css基础知识.根据我自己的学习经验,我们需要掌
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Sass
嵌套规则(NestedRules)Sass允许将一套CSS样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器mainp{color:00ff00;width:97%;.redbox{
Stella981 Stella981
3年前
CSS 分类 (Classification)
★★CSS分类属性(Classification)★★⑴CSS分类属性允许你控制如何显示元素,设置图像显示于另一元素中的何处,相对于其正常位置来定位元素,使用绝对值来定位元素,以及元素的可见度。⑵下面是常用的属性以及描述:!(https://oscimg.oschina.net/oscnet/00cb565
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这