Skip to content

CSS object-fit: contain 应用说明

这篇文章解决什么问题

前端页面里,图片和视频经常不是“放进去就完事”:

  • 商品图比例不统一,但列表卡片要整齐。
  • Logo 有横版、竖版、图标版,不能被裁掉。
  • 证件照、凭证、截图、设计稿预览必须完整显示。
  • 视频播放器要保留完整画面,不希望上下左右被切掉。
  • 后台上传图不可控,横图、竖图、透明 PNG、长截图都会出现。

这些场景的共同点是:内容完整性比铺满容器更重要。

object-fit: contain 解决的就是这个问题。

先说结论

object-fit: contain 的作用是:

让图片或视频在指定盒子里完整显示,保持原始比例,不裁剪,不拉伸。

典型写法:

css
.product-image {
  width: 240px;
  height: 180px;
  object-fit: contain;
}

配合 HTML:

html
<img class="product-image" src="/images/product.png" alt="商品图" />

它最适合:

  • 商品图
  • Logo
  • 证件照预览
  • 上传图片预览
  • 视频课程播放器
  • 需要完整展示的截图、海报、凭证图

它不适合:

  • 首屏 Banner
  • 沉浸式封面
  • 背景视频
  • 需要铺满视觉区域的图片

这类场景通常更适合 object-fit: cover

object-fit 是什么

object-fit 用来控制替换元素的内容如何适配自己的盒子。

常见替换元素包括:

元素是否常用说明
img常用图片、商品图、Logo、头像、预览图
video常用播放器、视频封面、背景视频
picture不直接作用应写在内部 img
iframe不推荐依赖内容源复杂,表现不如图片和视频稳定

object-fit 写在 imgvideo 上,不写在普通 div 上。

错误写法:

css
.image-wrapper {
  object-fit: contain;
}

正确写法:

css
.image-wrapper img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

如果图片是 background-image,对应能力不是 object-fit,而是:

css
.banner {
  background-size: contain;
}

contain 到底怎么缩放

可以把 contain 理解成这条规则:

在不超过盒子宽高的前提下,把内容尽量放大,并保持原始比例。

假设盒子是 300px * 300px

如果图片是横图 600px * 300px

  • 图片会缩成 300px * 150px
  • 宽度贴满盒子。
  • 上下出现留白。

如果图片是竖图 300px * 600px

  • 图片会缩成 150px * 300px
  • 高度贴满盒子。
  • 左右出现留白。

如果图片比例刚好和盒子一致:

  • 图片会完整铺满盒子。
  • 不裁剪。
  • 不留白。

所以 contain 的留白不是 bug,而是它为了完整显示内容付出的代价。

必须先有明确的盒子

object-fit: contain 依赖一个明确的展示区域。没有宽高约束时,它很难表现出预期效果。

不稳定写法:

css
.image {
  width: 100%;
  object-fit: contain;
}

这里没有高度,图片仍然按自身比例撑开。列表里如果图片比例不同,卡片高度就可能不同。

更稳定的写法:

html
<div class="media-box">
  <img src="/images/product.png" alt="商品图" />
</div>
css
.media-box {
  aspect-ratio: 4 / 3;
  background: #f6f7f9;
}

.media-box img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

这段代码里,真正起作用的是三件事:

  • aspect-ratio 固定展示区域。
  • width: 100%; height: 100% 让图片元素占满这个区域。
  • object-fit: contain 决定图片内容如何缩放进去。

实际项目里,contain 通常不会单独出现,而是和固定宽高、aspect-ratio、背景色、内边距一起用。

cover 的区别

containcover 都会保持图片原始比例,但目标完全不同。

目标是否裁剪是否留白适合场景
contain内容完整放进盒子不裁剪可能留白商品图、Logo、证件照、上传预览
cover内容铺满整个盒子可能裁剪不留白Banner、封面、头像、背景视频

示例:

css
.product-image {
  width: 240px;
  height: 180px;
  object-fit: contain;
}

.hero-image {
  width: 100%;
  height: 420px;
  object-fit: cover;
}

判断方法很简单:

  • 图片不能被裁:用 contain
  • 容器不能留白:用 cover

商品图被裁掉,用户可能看不到完整商品。Banner 留白太多,页面视觉会变弱。所以两者没有谁更高级,只有场景不同。

和其他值的横向对比

object-fit 常见值有五个:

含义是否保持比例是否裁剪常见程度
fill拉伸内容填满盒子默认值,但图片场景不推荐
contain完整显示内容商品图、Logo 常用
cover铺满盒子封面、头像常用
none使用原始尺寸可能溢出少用
scale-downnonecontain 中选更小结果偶尔用于不想放大小图

fill

css
.image {
  object-fit: fill;
}

fill 会把内容硬塞进盒子,可能拉伸变形。它是默认值,但不是大多数图片布局的理想值。

none

css
.image {
  object-fit: none;
}

none 不缩放内容。图片原始尺寸比盒子大时,会被盒子裁掉或溢出。真实业务里用得少。

scale-down

css
.image {
  object-fit: scale-down;
}

scale-down 可以理解成:

如果原图放得下,就按原图显示;如果放不下,就按 contain 缩小。

它适合不希望小图被放大的场景,比如图标预览、素材库缩略图。

配合 object-position 控制位置

object-fit: contain 决定缩放方式,object-position 决定内容在盒子里的位置。

默认值接近:

css
.image {
  object-fit: contain;
  object-position: center;
}

如果希望内容靠上:

css
.preview {
  width: 180px;
  height: 240px;
  object-fit: contain;
  object-position: top center;
}

如果希望内容靠左:

css
.logo {
  width: 180px;
  height: 72px;
  object-fit: contain;
  object-position: left center;
}

注意:object-position 不改变图片比例,也不改变是否留白。它只改变内容在盒子里的对齐位置。

商品图场景

商品图通常不能裁剪。鞋子、衣服、数码产品、包装盒,如果被 cover 裁掉边缘,会影响用户判断。

推荐结构:

html
<article class="product-card">
  <div class="product-media">
    <img src="/images/shoe.png" alt="轻量跑鞋" />
  </div>
  <h3>轻量跑鞋</h3>
</article>
css
.product-card {
  width: 240px;
}

.product-media {
  aspect-ratio: 1 / 1;
  padding: 16px;
  background: #f6f7f9;
  border-radius: 8px;
  overflow: hidden;
}

.product-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

这个写法解决三个问题:

  • 商品图区域比例统一。
  • 商品完整显示。
  • 不同比例图片不会撑乱卡片列表。

padding 是常见小技巧。它让商品不要贴边,尤其适合白底商品图、透明 PNG、Logo 型商品图。

Logo 场景

Logo 比例差异很大。横版 Logo、竖版 Logo、只有图标的 Logo 混在一起,如果使用 cover,很容易裁掉品牌信息。

推荐:

html
<div class="brand-logo">
  <img src="/images/logo.svg" alt="品牌 Logo" />
</div>
css
.brand-logo {
  width: 160px;
  height: 72px;
  display: grid;
  place-items: center;
}

.brand-logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

Logo 场景也可以用:

css
.brand-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

区别是:

  • width: 100%; height: 100%:图片元素盒子占满父容器。
  • max-width: 100%; max-height: 100%:图片元素按自身比例缩进父容器。

Logo 列表里,max-width + max-height 往往更自然。

上传预览场景

后台管理系统里,上传图片预览更看重“看全”,不是“好看铺满”。

html
<div class="upload-preview">
  <img src="/uploads/license.jpg" alt="营业执照预览" />
</div>
css
.upload-preview {
  width: 320px;
  height: 180px;
  border: 1px solid #dcdfe6;
  background: #fafafa;
}

.upload-preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

如果上传的是证件照、凭证、合同扫描件,containcover 更安全。因为裁掉任何一部分,都可能影响审核。

视频场景

object-fit: contain 也可以用于 video

html
<video class="lesson-video" src="/videos/demo.mp4" controls></video>
css
.lesson-video {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  object-fit: contain;
}

课程视频、会议录屏、教学演示通常适合 contain,因为画面边缘可能有重要信息。

如果是背景视频,通常更适合:

css
.background-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

背景视频目标是铺满视觉区域,允许裁掉一部分边缘画面。

头像场景不要盲目用 contain

头像多数时候更适合 cover

css
.avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
}

原因是头像容器通常很小,如果使用 contain,可能出现明显留白,看起来像头像没有填满。

只有当头像或照片不能被裁剪时,才考虑 contain

css
.id-photo {
  width: 180px;
  height: 240px;
  background: #f7f8fa;
  object-fit: contain;
}

例如证件照审核、人像素材预览、原图对比。

background-size: contain 的区别

object-fit: containbackground-size: contain 很像,但它们不是一回事。

能力作用对象图片是否是内容常见场景
object-fit: containimg / video商品图、内容图、视频
background-size: containCSS 背景图装饰图、纹理、视觉背景

内容图推荐:

html
<img class="product-image" src="/images/product.png" alt="商品图" />

装饰图可以用:

css
.decoration {
  background-image: url("/images/decoration.png");
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}

不要把有语义的内容图随手做成背景图。这样会丢掉 alt、懒加载、响应式图片、右键保存、可访问性等能力。

Tailwind CSS 中的写法

Tailwind CSS 里,object-fit: contain 对应工具类是:

html
<img class="object-contain" src="/images/product.png" alt="商品图" />

常见完整组合:

html
<div class="aspect-square rounded-lg bg-gray-100 p-4">
  <img class="h-full w-full object-contain" src="/images/product.png" alt="商品图" />
</div>

这里每个类的作用是:

类名作用
aspect-square固定展示区域为正方形
bg-gray-100给留白区域一个背景色
p-4给图片留安全边距
h-full w-fullimg 元素占满父容器
object-contain对应 object-fit: contain

如果只写:

html
<img class="object-contain" src="/images/product.png" alt="商品图" />

通常看不到明显效果。因为没有明确宽高或父容器边界,object-fit 没有可适配的盒子。

Tailwind 里常见相关类还有:

Tailwind 类CSS
object-containobject-fit: contain;
object-coverobject-fit: cover;
object-fillobject-fit: fill;
object-noneobject-fit: none;
object-scale-downobject-fit: scale-down;
object-centerobject-position: center;
object-topobject-position: top;
object-leftobject-position: left;

Tailwind 只是换了写法,底层规则仍然是原生 CSS 的 object-fitobject-position

常见错误

只写 object-fit,不写宽高

css
.image {
  object-fit: contain;
}

这通常不够。应该给图片或父容器明确尺寸:

css
.image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

object-fit 写在父元素上

css
.media-box {
  object-fit: contain;
}

这不会影响内部图片。应该写在图片本身:

css
.media-box img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

误以为 contain 能消灭留白

contain 的目标是完整显示,不是铺满容器。只要图片比例和盒子比例不同,就可能留白。

如果不能接受留白,要改需求或使用 cover

图片还是变形

检查是否只写了:

css
.image {
  width: 100%;
  height: 100%;
}

没有 object-fit 时,图片会按元素盒子强行拉伸。需要补上:

css
.image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

SVG 看起来还有空白

SVG 自身可能带 viewBox 空白、固定画布或透明边距。即使外层用了 object-fit: contain,视觉上仍会像“没放满”。

这种情况要检查 SVG 文件本身,不是只改 CSS。

透明 PNG 看不出边界

透明 PNG 用 contain 时,留白区域和图片透明区域可能混在一起。建议给容器加背景色:

css
.media-box {
  background: #f6f7f9;
}

这样更容易看出图片真实占位和视觉边界。

实战选择表

需求推荐写法原因
商品图完整展示object-fit: contain商品不能被裁
商品列表卡片高度统一aspect-ratio + object-fit: contain固定区域,图片完整缩放
Logo 列表object-fit: containmax-width + max-height保留品牌形状
上传预览object-fit: contain看全比铺满重要
证件照审核object-fit: contain不能裁关键区域
头像展示object-fit: cover小图留白通常不好看
Banner 封面object-fit: cover铺满比完整更重要
视频课程object-fit: contain保留完整画面
背景视频object-fit: cover视觉铺满优先
装饰背景图background-size: contain图片不属于正文内容

最小可用模板

普通 CSS:

html
<div class="media-box">
  <img src="/images/demo.png" alt="示例图" />
</div>
css
.media-box {
  aspect-ratio: 4 / 3;
  background: #f6f7f9;
  overflow: hidden;
}

.media-box img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}

Tailwind CSS:

html
<div class="aspect-[4/3] overflow-hidden bg-gray-100">
  <img class="h-full w-full object-contain object-center" src="/images/demo.png" alt="示例图" />
</div>

总结

object-fit: contain 是图片和视频布局里很常用的完整显示方案。

记住几个点:

  • 它保持比例。
  • 它不裁剪。
  • 它可能留白。
  • 它需要明确的盒子尺寸。
  • 它应该写在 img / video 上。
  • 它常和 aspect-ratio、背景色、内边距、object-position 一起用。
  • Tailwind 的 object-contain 只是它的工具类写法。

真实项目里,先问一个问题:这张图能不能被裁?不能裁,用 contain;不能留白,用 cover

基于 VitePress 的个人知识库骨架