
本文详解如何通过 radial-gradient 背景 + CSS 自定义属性 + 原生 JavaScript,实现一个精准作用于指定容器、不影响前后兄弟元素的可滚动/可交互圆形遮罩动画。
本文详解如何通过 radial-gradient 背景 + css 自定义属性 + 原生 javascript,实现一个精准作用于指定容器、不影响前后兄弟元素的可滚动/可交互圆形遮罩动画。
在网页设计中,类似 Kozowood 官网那种「滚动揭示内容」的圆形遮罩效果(即中心镂空、边缘遮盖)极具视觉冲击力。但若采用 position: fixed 的 DOM 元素作为遮罩层(如原始代码中的 #mask),会脱离文档流,导致无法精准限定作用范围——它将覆盖整个视口,从而干扰前后非目标区域的内容(如 .before 和 .after 区块)。真正的解法在于:用 CSS 伪元素 + 径向渐变背景替代 DOM 遮罩层,使遮罩仅作用于目标容器内部,完全隔离上下文。
✅ 核心原理:伪元素 + 动态径向渐变
我们利用 .content::before 创建覆盖层,并通过 radial-gradient 构建「中心透明、外围实色」的圆形孔洞:
.content::before {
content: "";
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
background: radial-gradient(
circle at center,
transparent var(--radius),
#e74c3c calc(var(--radius) + 1px)
);
z-index: 2;
}-
var(--radius)是动态 CSS 变量(如0%,50%,100%),控制透明圆的半径; -
calc(var(--radius) + 1px)确保边缘锐利无模糊过渡; -
circle at center保证圆心始终居中,不随内容滚动偏移。
?️ JavaScript 控制逻辑(滚动驱动版)
虽然示例中使用了滑块手动控制,但实际项目中需绑定 scroll 事件。以下为适配滚动的精简实现:
document.addEventListener('DOMContentLoaded', () => {
const content = document.querySelector('.content');
const maskContainer = document.querySelector('.container.fullscreen2');
// 监听滚动,计算当前滚动进度(0~1)
window.addEventListener('scroll', () => {
const scrollTop = window.scrollY;
const containerTop = maskContainer.offsetTop;
const containerHeight = maskContainer.offsetHeight;
const scrollProgress = Math.min(
Math.max((scrollTop - containerTop) / containerHeight, 0),
1
);
// 将进度映射为 0% ~ 100% 的半径值
const radiusPercent = Math.round(scrollProgress * 100);
content.style.setProperty('--radius', `${radiusPercent}%`);
// 当遮罩完全打开(radius ≥ 100%),移除遮罩层提升性能
if (radiusPercent >= 100) {
content.style.removeProperty('--radius');
content.classList.add('mask-complete');
}
});
});? 关键优化点:
Wjs Uploading Video下载将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
立即学习“前端免费学习笔记(深入)”;
- 使用
scrollProgress替代document.documentElement.scrollHeight,避免因页面高度变化导致计算偏差;Math.min/max确保值域严格锁定在[0, 1],防止负值或超限;- 达到 100% 后移除变量或添加类名,便于后续 CSS 清理(如
transition: none或display: none)。
? HTML 结构:天然支持前后兄弟元素
<div class="before">导航栏 / 头部内容</div>
<div class="container fullscreen2">
<div class="content">
<!-- 被遮罩的正文 -->
</div>
</div>
<div class="after">页脚 / 其他模块</div>由于遮罩仅通过 .content::before 应用,.before 和 .after 完全不受影响——它们保留自身定位、滚动行为和样式,真正实现「局部遮罩,全局兼容」。
⚠️ 注意事项与最佳实践
-
性能优先:避免在
scroll事件中直接修改style(易触发重排)。本方案仅更新 CSS 变量,由浏览器高效合成; -
响应式适配:
var(--radius)基于父容器宽度计算,若需基于视口或固定像素,改用vw/px单位(如--radius: 200px); - 无障碍友好:遮罩纯属视觉增强,确保核心内容仍可通过键盘导航访问,不依赖遮罩状态;
-
降级方案:旧版浏览器不支持
radial-gradient时,可回退为background: rgba(0,0,0,0.8)全遮盖 + JS 动态裁剪(Canvas/SVG),但现代项目中已极少需要。
此方案摒弃了易失控的 fixed 遮罩层,转而拥抱 CSS 原生能力,兼顾语义化、可维护性与性能——是打造专业级滚动揭示效果的推荐范式。


















