:fullscreen伪类在Chrome中不生效是因为必须用双冒号::fullscreen(非单冒号),且仅作用于通过requestFullscreen()触发全屏的元素本身,需用户手势调用、配合document.fullscreenElement校验及浏览器前缀兼容。

为什么:fullscreen伪类在Chrome里不生效
因为现代浏览器对全屏API的实现分两套:一套是旧的:fullscreen(带冒号),另一套是更严格的::backdrop配合document.fullscreenElement。Chrome 65+、Edge 79+、Firefox 64+ 都已弃用:fullscreen单冒号写法,只认::fullscreen双冒号——但注意,这仅用于样式,不是选择器匹配逻辑。
常见错误是直接写:fullscreen { background: red; },结果视频全屏后样式完全没反应。
- 必须用
::fullscreen(双冒号)作用于被全屏的元素本身,比如video::fullscreen -
::backdrop才是控制全屏时背景层的样式,它独立于视频元素,且默认透明 - 不能对
body或父容器用::fullscreen——它只匹配当前处于全屏状态的那个元素
如何给全屏视频加自定义控件和背景
单纯改video::fullscreen只能影响视频画布本身(比如缩放、边框),真正想覆盖控件或遮罩,得靠video::backdrop + 绝对定位子元素。前提是视频必须通过requestFullscreen()触发,用controls自带的全屏按钮不会触发你写的::backdrop样式(部分浏览器限制)。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 把自定义控件(如返回按钮、音量条)放在
<video></video>同级的<div class="video-overlay">中,并用<code>video::fullscreen + .video-overlay或video:fullscreen ~ .video-overlay来显隐 -
video::backdrop可设background: rgba(0,0,0,.8),但无法加子元素——它只是个伪元素层 - 如果需要动态控制,监听
fullscreenchange事件比纯CSS更可靠:document.addEventListener('fullscreenchange', () => { if (document.fullscreenElement === myVideo) { ... } }) - 移动端(iOS Safari、Android Chrome)基本不响应
::fullscreen,因为它们没有“真全屏”概念,而是调用原生播放器 - 使用
object-fit: contain或cover时,video::fullscreen内修改width/height可能被忽略——浏览器会强制保持原始宽高比 - 若视频是
<iframe></iframe>嵌入(如YouTube),需确保allow="fullscreen"属性存在,否则requestFullscreen()会被拒绝,伪类自然不触发 - 在控制台执行
document.fullscreenElement,确认是否为你的<video></video>元素 - 检查元素面板里,全屏时
<video></video>上是否有:-webkit-full-screen这类私有类名(Safari/旧Chrome) - 用
@supports selector(::fullscreen)做特性检测,避免在不支持的环境里浪费样式 - 不要依赖
video:fullscreen(单冒号)——它在所有新浏览器里都不起作用,连警告都不会报
video::fullscreen和video::backdrop的兼容性差异
Firefox 支持video::fullscreen但不支持video::backdrop(直到115才部分支持);Safari 16.4+ 才开始支持::backdrop,且仅限<video></video>和<iframe></iframe>;Chrome 最早支持但要求display: block等基础样式不被重置。
关键细节:
为什么加了::fullscreen还是看不到效果
最常被忽略的是:全屏状态必须由用户手势触发(click/tap),且不能在异步回调(如setTimeout、fetch.then)里调用requestFullscreen(),否则会被浏览器静默拒绝,document.fullscreenElement为null,伪类自然不激活。
调试方法:
全屏样式真正的复杂点不在写法,而在于它和浏览器原生行为、移动端策略、权限模型深度耦合;哪怕CSS规则完全正确,只要触发路径不对,就永远进不了那个伪类作用域。


















