核心是用带透明中心的暗色径向渐变遮罩实现动态“照亮”,而非叠加光斑;通过::before伪元素承载background: radial-gradient(circle at var(--x) var(--y), transparent 0%, rgba(0,0,0,0.85) 70%),配合JS更新容器内相对坐标与requestAnimationFrame节流,确保高性能与真实追光效果。

网页卡片用 CSS 径向渐变做聚光灯效果,核心不是“加个光斑”,而是用带透明中心的暗色渐变遮罩,只让鼠标附近的区域透出来——就像舞台追光灯扫过黑幕,内容是原本就存在的,只是被动态“照亮”了。
结构与容器基础设置
卡片本身保持语义清晰、内容可读,不要包裹多余遮罩层。关键一步是给卡片容器设 position: relative,并确保背景为深色(如 #121212 或纯黑),否则聚光灯对比度不足。
- 避免用 这类额外 DOM 元素模拟光斑,推荐用 ::before 伪元素承载渐变
- 卡片内容(文字、图片、按钮)保持默认层级,不加
z-index干扰- 伪元素需设 pointer-events: none,否则会拦截点击和悬停
径向渐变遮罩的关键写法
真正起作用的是这个渐变声明:
background: radial-gradient(circle at var(--x) var(--y), transparent 0%, rgba(0,0,0,0.85) 70%);-
圆心不能直接写变量:
radial-gradient(circle at var(--x) var(--y), ...)在部分浏览器中无效;可靠做法是 JS 动态更新整个background声明,或用calc()拼接(如circle at calc(var(--x) * 1px) calc(var(--y) * 1px)) -
颜色过渡要留“呼吸感”:中心用
transparent,边缘用半透黑(如rgba(0,0,0,0.85)),太深会吞掉文字细节,太浅则失去聚光感 -
尺寸比例决定质感:光圈半径建议设为卡片宽高的 30%–45%,例如
--size: 40%,再在渐变中用circle at var(--x) var(--y) calc(var(--size) * 1px)控制范围
JS 动态定位与性能控制
鼠标坐标必须转成容器内百分比,且每帧最多更新一次,否则卡顿明显。
- 监听
mousemove时,用getBoundingClientRect()计算鼠标在卡片内的相对位置(0–100%) - 用 requestAnimationFrame 节流,避免频繁触发样式重排
- 设置 CSS 变量统一用 px 单位(如
--x: 32px),避免单位混用导致渐变解析失败 - 移动端慎用:iOS Safari 在后台标签中可能暂停
requestAnimationFrame,触摸事件坐标也不稳定
混合模式与降级兼容
单纯叠加渐变容易盖住内容,要用混合模式让光区“透亮”而非“覆盖”。
- 伪元素加 mix-blend-mode: screen 或 exclusion,让黑色背景与透明中心自然融合
- 用
@supports检测支持性:@supports (background: radial-gradient(circle at 0 0, #000, #fff)) { /* 启用聚光灯 */ } - 不支持时降级为静态暗角:
background: url("vignette.png"),或直接移除遮罩 - Firefox 96 前、Safari 某些嵌套场景下
mix-blend-mode渲染异常,可临时改用opacity: 0.95缓解
- 卡片内容(文字、图片、按钮)保持默认层级,不加
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











