巧用阴影、mask以及css变量来实现元素聚焦效果
前言
嘿,之前我好像有段时间没写博客了。其实最大的原因就是我变得有点懒了。不过,现在毕业快到了,我也不能一直偷懒下去啊。对我来说,选择写代码作为职业方向是一件好玩的事情,而在此方向上,持续学习是最重要的事情之一。写博客就是一种非常好的方式来帮助自己持续学习,并且可以当作自己的成长记录,回味无穷。
最近遇到了一个这样的需求,有一个消息列表,希望可以在某条消息中实现聚焦,即除了应该聚焦的消息外的消息都会被一个黑蒙蒙的遮罩所遮住。
那么遇到这种不常见的需求,我们首先就需要思考技术方案。
技术方案
1.Mask遮罩
我最开始想到的是通过使用CSS渐变以及遮罩的方式来实现。
具体思路如下,首先利用IntersectionObserver
监听指定元素,如果它进入视图中,就可以将其top
、height
属性以「CSS变量」的方式赋值给Mask元素,Mask即可通过CSS变量的方式进行渐变计算,从而最终显示出聚焦效果。
整个HTML文档结构如下:
// 滚动列表盒子
// 列表盒子,利用after伪元素来实现遮罩
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10 (target)
// 需要聚焦的元素
- 11
- 12
- 13
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技术。
我是「盐焗乳鸽还要香锅」,喜欢我的文章欢迎关注噢
- github 链接https://github.com/1360151219
- 博客链接是 strk2.cn
- 掘金账号、知乎账号、简书《盐焗乳鸽还要香锅》
- 思否账号《天天摸鱼真的爽》
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net