source 标签的 media 属性在 <video> 中基本无效,因主流浏览器均忽略该属性的媒体查询判断,仅 <picture> 中稳定生效;视频响应式加载必须用 JavaScript 配合 matchMedia 和 video.load() 实现。

source 标签的 media 属性在 <video> 中基本无效,不能靠它实现不同屏幕尺寸加载不同视频文件。
为什么写 media="(min-width: 768px)" 却没用?
主流浏览器(Chrome、Firefox、Safari、Edge)当前均不执行 <video><source> 中的 media 条件判断——它被解析但被忽略。常见现象包括:
- 小屏设备仍下载了
media="(min-width: 1200px)"的高清 MP4 - Network 面板里所有
<source>的资源都发出了请求,完全无视媒体查询 - 控制台无报错,但行为与预期完全不符
这不是你写错了语法,而是规范未强制实现、厂商也未优先支持的结果。W3C 允许该属性存在,但不保证它起作用。
<picture> + media 是唯一可靠场景
media 属性只在 <picture> 中稳定生效,且仅用于图片。它的行为明确:
立即学习“前端免费学习笔记(深入)”;
- 按 DOM 顺序遍历每个
<source> - 对
media值执行 CSS 媒体查询匹配 - 命中第一个就停止,加载其
srcset或src - 必须配
<img src="fallback.jpg">,否则无图显示
示例结构(可靠):
<picture> <source media="(min-width: 1200px)" srcset="hero-1920.jpg"> <source media="(min-width: 768px)" srcset="hero-1024.jpg"> <img src="hero-480.jpg" alt="Hero"> </picture>
注意:media 值必须是合法 CSS 媒体查询,比如 (max-height: 600px)、screen and (orientation: landscape),不能写 "mobile" 或漏括号。
视频响应式加载只能靠 JavaScript
想让不同屏幕尺寸加载不同分辨率的视频,必须手动控制 <video>.src 并触发重载:
- 用
window.matchMedia("(min-width: 768px)").matches判断当前断点 - 设置
video.src = "hd.mp4"或替换<source>的src属性 - **必须调用
video.load()**,否则不会发起新请求 - 建议在
DOMContentLoaded后执行,避免 race condition - 如需响应 resize,可监听
matchMedia的change事件(注意防抖)
简单示例:
const video = document.querySelector('video');
const mql = window.matchMedia('(min-width: 768px)');
function setVideoSrc() {
video.src = mql.matches ? 'hd.mp4' : 'sd.mp4';
video.load(); // 关键:不加这行不会重新加载
}
setVideoSrc();
mql.addEventListener('change', setVideoSrc);
type 属性比 media 更关键,别搞混
media 不是选格式,type 才是。常见翻车点:
- 没写
type="video/mp4",Safari 可能跳过 MP4 直接 fallback - 写了
type="video/mpeg"而不是video/mp4,导致识别失败 - AV1 视频要写
type="video/mp4"; codecs="av1",且仅 Safari 16+ 支持 - 多个
<source>按 DOM 顺序“第一个可用即用”,不是最优选
真正影响是否加载的,是 type 是否被识别 + HTTP 状态码 + 解码能力;media 在 <video> 里只是摆设。
最容易被忽略的一点:即使你用 JS 动态设置了 src,如果没调 .load(),浏览器不会发请求——它只会等你点播放或自动播放触发,而那时可能已经晚了。



















