CSS Handbook · 现代布局特性

第九章 / 9.1 aspect-ratio 与 object-fit

第九章 · 9.1 节

aspect-ratio 与 object-fit


在这两个属性出现之前,"固定宽高比的占位盒子"要靠 padding-top 百分比 hack 实现,"图片裁剪填充"则完全无法用纯 CSS 控制。这两个现代属性把这两类高频需求都变成了一行声明。

aspect-ratio 固定宽高比

aspect-ratio 让元素按指定比例自动计算高度(或宽度),无需再依赖百分比 padding 的 hack 手法。

.video-wrap {
  aspect-ratio: 16 / 9;
  width: 100%;
}
aspect-ratio: 16 / 9
16 : 9
旧写法对照过去实现同样效果需要:外层 position: relative,内层用 ::before { padding-top: 56.25%; } 撑开高度,再让真正的内容用 position: absolute 铺满——三行变一行,且语义清晰得多。

配合响应式宽度使用

常见的图片/视频占位场景:宽度跟随容器自适应,高度按比例自动计算,避免图片加载完成前后页面出现"跳动"(累积布局偏移,CLS)。

img {
  width: 100%;
  aspect-ratio: 4 / 3; /* 图片尚未加载时也预留正确高度 */
  object-fit: cover;
}

object-fit 媒体填充方式

object-fit 决定 <img>/<video> 这类"可替换元素"在其自身宽高与真实媒体宽高不一致时如何填充,语义与 background-size 十分相似。

取值效果
fill(默认)拉伸填满容器,可能导致图片变形
cover保持比例缩放至完全覆盖容器,超出部分裁剪,最常用
contain保持比例缩放至完整显示,容器内可能留白
none保持原始尺寸,不缩放
object-fit 对比(用色块模拟原始比例更宽的媒体)
cover(等比裁剪)
contain(等比留白)

object-position

配合 object-fit: cover 使用,控制裁剪时保留媒体的哪个部位可见——例如人像图裁剪时希望始终保留头部而非居中裁剪。

.avatar {
  object-fit: cover;
  object-position: top center; /* 优先保留图片顶部区域 */
}

两者组合:响应式媒体卡片

.card-cover {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
  border-radius: 8px 8px 0 0;
}

这是当前卡片列表、文章封面图最常见的写法:无论原图比例如何,卡片封面始终保持统一的 16:9 外观。

常见误区

  • aspect-ratio 在同时设置了明确 width 与 height 时不生效——它只在"至少一个维度是自动计算"时才起作用。
  • object-fit 只对图片、视频等可替换元素生效,对普通 div 背景图无效,背景图应使用 background-size。
  • 用 object-fit: cover 裁剪人像图却未设置 object-position,默认居中裁剪可能切掉头部。

Chapter 9 · Section 9.1

aspect-ratio and object-fit


Before these two properties existed, a placeholder box with a fixed aspect ratio required a padding-top percentage hack, and cropping images to fill a box could not be controlled with pure CSS at all. These two modern properties turn both high-frequency needs into a single declaration.

aspect-ratio: Fixing the Aspect Ratio

aspect-ratio lets an element compute its height (or width) automatically from a specified ratio, with no need for the percentage-padding hack.

.video-wrap {
  aspect-ratio: 16 / 9;
  width: 100%;
}
aspect-ratio: 16 / 9
16 : 9
Old approach, for comparisonIn the past the same effect required position: relative on the outer element, ::before { padding-top: 56.25%; } on an inner element to prop up the height, and then absolutely positioning the real content with position: absolute to fill it — three lines reduced to one, with far clearer semantics.

Using It with Responsive Widths

A common image/video placeholder scenario: the width follows the container responsively, while the height is computed from the ratio, avoiding the page "jump" (cumulative layout shift, CLS) before and after the image finishes loading.

img {
  width: 100%;
  aspect-ratio: 4 / 3; /* reserves the correct height even before the image loads */
  object-fit: cover;
}

object-fit: How Media Fills Its Box

object-fit decides how replaced elements such as <img>/<video> fill their box when the element's own size does not match the media's native size; its semantics are very similar to background-size.

ValueEffect
fill (default)Stretched to fill the box; may distort the image
coverScaled proportionally to cover the box completely, cropping the overflow; most commonly used
containScaled proportionally to fit entirely; may leave blank space in the box
noneKeeps the native size, no scaling
object-fit comparison (color blocks simulate media with a wider native ratio)
cover (scaled and cropped)
contain (scaled with letterboxing)

object-position

Used together with object-fit: cover, it controls which part of the media stays visible when cropped — for example, cropping a portrait while always keeping the head instead of a centered crop.

.avatar {
  object-fit: cover;
  object-position: top center; /* keeps the top region of the image */
}

Combining Both: Responsive Media Cards

.card-cover {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
  border-radius: 8px 8px 0 0;
}

This is the most common pattern for card lists and article cover images: whatever the native ratio of the source image, the card cover always keeps a uniform 16:9 appearance.

Common Pitfalls

  • aspect-ratio has no effect when both an explicit width and height are set — it only applies when at least one dimension is auto-computed.
  • object-fit only affects replaced elements such as images and video, not background images on ordinary divs; use background-size for background images.
  • Cropping a portrait with object-fit: cover without setting object-position defaults to a centered crop that may cut off the head.