什么是替换元素?object-fit 和 object-position 如何控制图片视频?
简化版
替换元素的内容由外部资源或浏览器内部控件替换,典型如 img、video、iframe 和部分表单控件;它们通常有固有尺寸和固有比例。object-fit 决定资源如何放进元素内容盒,object-position 决定裁剪或留白时的对齐位置,它们不改变元素自身盒子的布局尺寸。
详细版
fill 会拉伸铺满,可能变形;contain 保持比例完整显示,可能留白;cover 保持比例覆盖盒子,可能裁剪;none 使用资源固有尺寸;scale-down 在 none 与 contain 中选择更小结果。
当图片是内容时应使用 <img> 与 object-fit,保留替代文本、加载和响应式图片能力;纯装饰图更适合 CSS background-image 与 background-size。两者视觉效果相近,但语义、可访问性和加载行为不同。
要避免布局偏移,应提供 width/height 或 aspect-ratio,再让 object-fit 处理盒内绘制,而不是等图片加载后才决定尺寸。
完整版教学
一、替换元素的“内容”不由 CSS 排版
普通 div 的内容由文本和子节点组成,浏览器能逐行排版;img 的内容则是外部图片解码后的画面,CSS 只控制它占据的盒子以及画面如何放进去。规范把这类内容表示被外部对象替代的元素称为替换元素。
元素盒子:由 CSS width/height/aspect-ratio 决定
内部对象:由图片、视频、嵌入文档或控件实现提供
常见替换元素包括 img、video、iframe、embed;表单控件的具体表现还与浏览器和平台有关。background-image 不是元素内容,所以它不属于替换元素。
二、固有宽高和比例参与自动尺寸计算
图片文件可能携带固有宽 1200px、高 800px,固有比例为 3:2。若 CSS 只设置 width: 300px; height: auto,浏览器可按比例算出高度 300 ÷ 1.5 = 200px。
img {
width: 300px;
height: auto;
}
若同时指定 width: 300px; height: 300px,元素盒子变成正方形,但图片对象仍是 3:2。此时是否变形、留白或裁剪由 object-fit 决定,而不是由固有比例自动替你选择。
三、五个 object-fit 值对应五种取舍
假设源图是 1200 × 800,目标盒是 300 × 300。保持比例时,按宽缩放得到 300 × 200,按高缩放得到 450 × 300;这两个结果正好对应 contain 与 cover 的核心选择。
| 值 | 绘制结果 | 是否变形 | 是否裁剪/留白 |
|---|---|---|---|
fill | 300 × 300 | 是 | 无 |
contain | 300 × 200 | 否 | 上下共留 100px |
cover | 450 × 300 | 否 | 左右共裁 150px |
none | 接近固有尺寸 | 否 | 可能溢出 |
scale-down | none 与 contain 中较小者 | 否 | 视尺寸而定 |
头像、卡片封面常用 cover,商品全貌或 Logo 常用 contain。选择标准是业务是否允许裁掉内容,不能只看哪一种“更铺满”。
四、object-position 控制裁剪焦点
cover 默认以中心对齐,主体在画面边缘时可能被裁掉。object-position 可以用关键字、百分比或长度移动对象的对齐点,例如人物在右侧时设置 70% center。
.portrait {
width: 300px;
aspect-ratio: 1;
object-fit: cover;
object-position: 70% 35%;
}
百分比不是简单把图片移动到盒子的百分比坐标,而是把对象自身的对应点与容器对应点对齐。若内容由编辑人员上传,最好允许保存焦点坐标,否则一条固定规则无法适配所有构图。
五、object-fit 与 background-size 语义不同
object-fit: cover 与 background-size: cover 都能产生铺满裁剪效果,但前者作用于内容元素,后者属于装饰背景。内容图片可拥有 alt、参与搜索语义、使用 srcset、懒加载和图片保存菜单;背景图通常不被辅助技术当作内容。
| 场景 | 推荐 | 原因 |
|---|---|---|
| 商品图、人物照片 | <img> | 是页面内容,需要替代文本 |
| 视频封面 | <video>/img | 有媒体语义和加载状态 |
| 纯纹理、渐变装饰 | CSS 背景 | 不应增加读屏噪声 |
| 带文字的关键信息图 | <img alt> 或正文 | 必须提供等价信息 |
把所有图片都写成背景图会失去响应式候选和可访问语义;把纯装饰图都写成有文字 alt 的 img 又会给读屏用户制造噪声。
六、稳定布局要先定义盒子再装入内容
图片下载前若没有尺寸信息,浏览器可能先分配零高度;资源到达后突然出现 300px 高度,下面内容整体跳动。应通过 HTML 宽高属性或 CSS aspect-ratio 预留空间。
.card-cover {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
容器宽 640px 时,16:9 高度是 640 × 9 ÷ 16 = 360px,下载前即可确定。object-fit 只负责这 640 × 360 盒子里的画面,不负责让盒子本身获得比例。
易错点:先定盒子尺寸,再谈对象如何 fit;把
object-fit当成布局尺寸属性,会让 CLS 和裁剪问题混在一起。
七、常见误区与追问
- 误区:
object-fit: cover会自动改变元素高度。 它只改变内部对象绘制方式,元素盒尺寸仍由 CSS 布局决定。 - 误区:所有带固有尺寸的元素都是图片。 视频、嵌入文档和部分表单控件也可能属于替换元素。
- 误区:背景图和 img 只是写法不同。 它们在语义、可访问性、响应式资源和加载 API 上差异很大。
- 追问:为什么
object-fit对普通 div 不生效? 普通 div 没有需要装入内容盒的替换对象,应改用背景或调整子元素布局。 - 追问:如何避免人物被 cover 裁掉? 使用
object-position保存焦点,或通过<picture>提供不同屏幕的美术裁剪。 - 追问:图片 alt 该如何处理? 内容图提供上下文等价描述,纯装饰图使用空
alt="",不要复述无意义文件名。
八、加强记忆
把替换元素想成“相框和照片”两层:CSS 布局先决定相框大小,资源固有尺寸描述照片比例,object-fit 决定完整放入、铺满裁剪还是拉伸,object-position 决定裁剪时保留哪里。内容图片用 img 保存语义和响应式能力,装饰图片用背景降低噪声;同时提前给相框宽高比,才能既控制构图又避免页面跳动。