capture属性仅对<input type="file">生效,必须配合accept="image/*"等通配符及HTTPS、用户手势、静态DOM三条件;capture="user"/"environment"在iOS/Android兼容性差,精确控制应使用getUserMedia()。

capture 属性必须和 type="file" 一起用
单独给 <button> 或 <div> 加 capture 没有任何效果。它只对 <input type="file"> 生效,且必须配合 accept 才可能触发相机界面。
常见错误:<input type="file" capture> 漏了 accept,结果点击后只弹图库;或者写成 <input type="text" capture="user">,浏览器直接忽略。
-
accept必须是通配符形式:accept="image/*"✅,accept="image/jpeg"❌(iOS 和部分 Android 会降级为图库) - 视频录制用
accept="video/*",音频用accept="audio/*" -
capture值只能是"user"或"environment",其他如"camera"是非标写法,iOS 完全不认
HTTPS + 用户手势 + 静态 DOM 缺一不可
哪怕代码写对了,只要环境不满足这三条,浏览器就会静默 fallback 到文件选择器,控制台也不报错。
- 必须通过
https://(或localhost)访问:HTTP 下 iOS Safari 和新版 Chrome 直接禁用摄像头入口 - 触发
click()必须在用户真实点击/触摸回调里:不能放在setTimeout、Promise.then或页面加载完成后的自动调用中 -
<input>必须初始渲染在 DOM 中:不能用innerHTML动态插入,也不能在 Vue/React 的mounted或useEffect里创建后才挂载 - 不能包裹在
display: none或visibility: hidden的父元素里——Safari 会跳过该 input
capture="user" 在 iOS 和 Android 上表现差异极大
capture="user" 并不保证一定调前置,尤其在 Android 上行为更不可控。
立即学习“前端免费学习笔记(深入)”;
- iOS Safari 14.5+ 才稳定支持
capture="user";旧版本等价于没写,仍默认前置 - iOS Safari 至今(2026年8月)仍基本忽略
capture="environment",即使写了也大概率打开前置 - Android 厂商 ROM 差异大:部分机型无视
capture="environment",仍开前置;有些则直接退化为图库选择 - 不要加
multiple:带multiple的<input type="file" accept="image/*" capture="environment" multiple>会让几乎所有 Android 放弃调用摄像头
真正需要精确控制镜头时,别硬扛 capture
如果业务要求“必须后置”“实时预览”“镜像开关”或“自定义拍照按钮”,capture 就不是解决方案,而是障碍。
- 改用
MediaDevices.getUserMedia(),传{ facingMode: "environment" }明确请求后置 - 配合
<video>实时流 +<canvas>截帧,才能做到可控拍照、滤镜、裁剪 - 要处理权限拒绝、设备不可用、流停止等生命周期,不能只靠一个属性
- 微信内嵌 WebView、旧版 iOS、PWA 限制场景下,
capture失效概率极高,getUserMedia()虽也受限,但至少能给出明确错误提示
capture 是个提示,不是开关。它生效的条件链太长,任何一个环节断掉,就退回图库——而这个过程你完全看不见日志。



















