controls属性必须完全移除而非设为false;controlslist仅作提示且兼容性差;彻底隐藏控件需结合内核专属css伪元素;移除controls后必须用js补全播放、拖拽、音量等交互逻辑。

controls 属性不能设为 false,必须移除或用 JS 删除
写 controls="false" 或 controls="0" 完全没用——浏览器只看“是否存在”,不解析值。只要属性在标签里,控件就显示。
正确做法只有两个:
- HTML 中完全不写
controls属性(最干净) - 用 JavaScript 动态移除:
video.removeAttribute('controls')
错误示例:<video controls="false" src="a.mp4"></video> → 控件照常弹出,别被名字骗了。
controlsList 只能“尽力隐藏”,别指望它精准控制单个按钮
controlsList 是个辅助手段,不是开关。它只在 Chromium 系列(Chrome/Edge)中稳定生效,Firefox 基本忽略,Safari 支持极弱。
常见值有:noprogress、nofullscreen、nodownload、noremoteplayback,但注意:
- 即使写了
controlsList="noprogress nofullscreen",只要controls属性还在,播放/暂停/音量按钮仍会显示 - 它不保证隐藏成功,只是向浏览器“提个请求”
- 无法隐藏 WebKit 下的 overflow button 或画中画按钮,这些得靠 CSS 补刀
CSS 伪元素必须分内核写,WebKit 和 Firefox 不通用
想彻底干掉残余按钮,得靠浏览器专属伪元素。不同内核的选择器完全不同,漏写一个就露馅:
- Chrome/Edge(Blink/WebKit):
video::-webkit-media-controls-fullscreen-button、video::-webkit-media-controls-overflow-button、video::-internal-media-controls-overflow-button - Firefox:
video::-moz-media-controls-fullscreen-button、video::-moz-media-controls-play-button - 统一兜底(现代支持):
video::part(media-controls)(但 Safari 目前不认)
别乱加 pointer-events: none——它会让 video.play() 在点击封面图时直接失效,除非你已接管全部交互逻辑。
移除 controls 后,视频变“哑巴容器”,JS 控制逻辑必须补全
这是最容易翻车的环节:删完 controls,用户点不了、拖不动、切不了静音,页面就卡死。
至少要手动实现以下基础能力:
- 播放/暂停:
video.play()/video.pause()(注意移动端需用户手势触发) - 进度拖拽:监听
timeupdate事件 + 自己画进度条 + 设置video.currentTime = x(注意该赋值是异步的,iOS 上尤其明显) - 音量控制:
video.muted = true、video.volume = 0.7(iOS 音量只读,volume设了也无效) - 防意外 UI:
video.disablePictureInPicture = true、video.playsInline = true(iOS 必加)
真正难的不是“怎么藏”,而是“藏完之后,用户还能不能用”。很多项目卡在这一步,不是 CSS 没写对,是 JS 控制链断了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











