如何在CSS中为可滚动absolute定位元素实现聚焦模糊效果?
实现滚动容器内的聚焦模糊效果(absolute定位场景)
可以实现你要的效果,核心思路是通过双层内容叠加+遮罩的方式,解决absolute定位滚动容器的模糊聚焦问题,具体实现如下:
实现原理
- 底层放置模糊处理后的完整内容
- 上层放置正常内容,再叠加一个径向渐变遮罩,遮罩透明区域露出清晰内容,其余区域透出底层的模糊内容
- 同步两层内容的滚动位置,并通过鼠标移动动态更新遮罩的圆心位置
完整代码
HTML结构
<div class="black-promo"> <!-- 模糊内容层 --> <div class="black-promo__blur-content"> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> </div> <!-- 正常内容+遮罩层 --> <div class="black-promo__content-wrapper"> <div class="black-promo__content"> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> <p>这里是需要显示的文本内容,很长很长,可以滚动...</p> </div> <div class="black-promo__mask"></div> </div> </div>
CSS样式
.black-promo { position: relative; height: 700px; overflow: hidden; background: #000; } /* 模糊内容层:铺满容器,内容模糊处理 */ .black-promo__blur-content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; padding: 20px; color: #fff; overflow-y: auto; filter: blur(8px); /* 可根据需求调整模糊程度 */ pointer-events: none; /* 禁止该层响应交互,确保上层内容可操作 */ } /* 内容包裹层:负责滚动,和模糊层同步滚动 */ .black-promo__content-wrapper { position: relative; width: 100%; height: 100%; overflow-y: auto; } /* 正常内容:与模糊层内容完全一致,显示清晰聚焦区域 */ .black-promo__content { padding: 20px; color: #fff; } /* 径向渐变遮罩:实现聚焦效果,跟随鼠标移动 */ .black-promo__mask { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient( circle at var(--mouse-x, 50%) var(--mouse-y, 50%), transparent 150px, rgba(0, 0, 0, 0.9) 250px ); pointer-events: none; /* 遮罩不干扰内容交互 */ }
JavaScript逻辑
const promo = document.querySelector('.black-promo'); const mask = promo.querySelector('.black-promo__mask'); const contentWrapper = promo.querySelector('.black-promo__content-wrapper'); const blurContent = promo.querySelector('.black-promo__blur-content'); // 同步滚动位置:确保模糊层和正常内容层滚动一致 contentWrapper.addEventListener('scroll', () => { blurContent.scrollTop = contentWrapper.scrollTop; }); // 实时更新遮罩圆心位置,跟随鼠标移动 promo.addEventListener('mousemove', (e) => { const rect = promo.getBoundingClientRect(); // 计算鼠标在容器内的相对百分比坐标 const xPercent = ((e.clientX - rect.left) / rect.width) * 100; const yPercent = ((e.clientY - rect.top) / rect.height) * 100; mask.style.setProperty('--mouse-x', `${xPercent}%`); mask.style.setProperty('--mouse-y', `${yPercent}%`); });
关键说明
- 双层内容分离:模糊层和正常内容层完全一致,通过定位叠加,上层遮罩控制显示区域
- 滚动同步:监听正常内容容器的滚动事件,同步更新模糊层的scrollTop,避免两层内容错位
- 动态遮罩:利用CSS变量实时更新径向渐变的圆心位置,实现鼠标跟随的聚焦效果
- 交互兼容:通过
pointer-events: none确保模糊层和遮罩层不影响正常内容的点击、选择等交互
内容的提问来源于stack exchange,提问作者uiHellen
相关产品推荐
相关产品推荐

