欢迎关注我的公众号:前端侦探
分享一个 CSS
小技巧
在平时开发中,经常会遇到这样一种问题:当打开一个弹窗时,后面的页面是可以滚动的,演示如下
那么,该如何锁定页面的滚动呢?
一、传统的实现方式
传统的方式其实也不复杂,就是在打开弹窗时阻止滚动就行了,通常是改变overflow
属性
js
const openModal = () => {
document.body.style.overflow = 'hidden'
}
const closeModal = () => {
document.body.style.overflow = 'auto'
}
如果是在现代框架里,比如vue
,可以用监听弹窗状态来实现
js
watch(
() => show.value,
(val) => {
if (val) {
document.body.style.overflow = 'hidden'
} else {
document.body.style.overflow = 'auto'
}
},
)
这样就能锁定滚动了
二、传统方式的局限
虽然上面的实现看似完美,其实还有潜在问题的。比如有多个弹窗,弹窗覆盖的情况下,这个时候锁定就会出问题了。
因为在关闭第二个弹窗的时候,页面已经解除锁定了,所以在第一个弹窗还在的时候,页面已经可以滚动了
如果想要优化这个问题,还需要做进一步的判断
三、借助 CSS has 实现
现在有了CSS :has
伪类,一切就好办了,无需过多的判断,直接一个选择器搞定
css
body:has(dialog[open]){
overflow: hidden
}
这行选择器表示,只要有属性为open
的弹窗,body
就自动锁定,无论有多少层弹窗
天然就实现了打开弹窗时自动锁定,是不是非常简单?
完整代码可以查看:CSS has lock scroll (juejin.cn)
四、has已经全兼容了
提一下兼容性,目前现代浏览器都支持了(虽然还比较新,但各大浏览器都跟进了),如下
其实关于has
能做的事情有很多很多,远不止父级选择器 那么简单,可以说has
可以选择网页中任意元素。
关于
has
选择器的用途,之前在这篇文章中还有其他介绍,可以参考一下:CSS 有了:has伪类可以做些什么? - 掘金 (juejin.cn)
最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发 ❤❤❤