最稳的明暗控制方式是直接在 video 元素上用 CSS 变量绑定 brightness(),如 filter: brightness(var(--video-brightness)),避免遮罩层或 backdrop-filter;全屏时需监听 fullscreenchange 并确保 z-index 足够高。

直接给 video 元素加 filter 就能调明暗,但全屏时容易失效;真正可控、可响应主题、不卡顿的方案是:用 CSS 变量绑定 brightness(),配合 filter 作用于 video 本身,而非遮罩层。
video 元素直接加 filter 是最稳的明暗控制方式
别绕路写 ::backdrop 或叠 div 遮罩——那些是为“调色+模糊”设计的,纯调亮度反而多一层渲染开销、多一个 z-index 坑。现代浏览器(Chrome 110+、Safari 16.4+、Firefox 启用 layout.css.backdrop-filter.enabled 后)都支持对 video 直接应用 filter,且性能远优于 canvas 中转。
-
filter: brightness(0.85)会整体压暗画面,值 1 是提亮,0.7–1.3 是安全区间 - 必须写在
video标签上,不能只写在父容器——否则子元素(如字幕、控件)也会被滤镜影响 - 移动端 Android WebView 旧版本可能不支持,可用
@supports (filter: blur(1px))检测并降级为透明遮罩 - 避免和
backdrop-filter混用在同一元素上,两者叠加会导致 Safari 渲染闪烁
用 CSS 变量实现暗黑模式自动适配亮度
硬编码 brightness(0.8) 在亮色模式下会发灰,切到暗黑模式又可能过暗。关键不是“设多少”,而是让数值能随 [data-theme="dark"] 切换动态重算。
- 在
:root定义默认值:--video-brightness: 1; - 在
[data-theme="dark"]覆盖:--video-brightness: 0.92;(实测比 0.85 更耐看,细节不塌) -
video上统一写:filter: brightness(var(--video-brightness)); - 不要在
[data-theme="dark"] video里直接写filter,否则 JS 动态改变量时不会触发重绘 - 若视频本身偏暗(如夜景素材),暗黑模式可设为
1,甚至微调contrast(1.05)提层次,而非盲目压亮度
全屏后滤镜消失?优先检查 document.fullscreenElement 和层级
进入全屏后,浏览器(尤其 Safari)会把 video 提升到顶层渲染层,导致你写的 filter 被忽略——这不是 bug,是全屏 API 的默认行为。此时滤镜没丢,只是没生效。
- 监听
fullscreenchange事件,确认document.fullscreenElement === yourVideoEl - 确保全屏时
video的z-index显式设为足够高(如z-index: 2147483647),防止被系统 UI 压住 - 不要依赖父容器的
filter,全屏时父容器常被脱离文档流,filter不再继承 - 若仍无效,临时 fallback:全屏时用 JS 强制设置
video.style.filter = "brightness(" + getComputedStyle(video).getPropertyValue("--video-brightness") + ")"
最易被忽略的是:brightness 值不是越小越好。设成 0.5 在暗黑背景下会让阴影细节完全糊掉,人眼反而觉得“闷亮”。实际项目中,0.85–0.95 才是兼顾可读性与氛围的常用区间;而那个看似“更高级”的 backdrop-filter 遮罩方案,其实只在你需要同时做模糊+调色时才值得引入。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











