CSS 教程 / CSS 背景颜色与图片:cover 和 contain

CSS 背景可以用颜色或图像填充元素,同时保持 HTML 内容不变。background-size: cover 会填充区域,可能裁剪图像;contain 会显示整个图像,可能留出未使用的空间。

了解背景颜色和图像

当没有图像或在透明区域后面时,背景颜色是可见的。即使图像未加载,背景颜色也可以保留。背景图像本身不是元素的内容,也不会自动创建元素高度。如果你只是将图像 URL 放在一个空的 div 中而不指定高度,可能不会有任何显示区域。在将有意义的照片作为 HTML 内容显示时,可以参考使用 响应式图片与视频:aspect-ratio 与 object-fit 的示例。

.sample {
  height: 300px;
  background-color: #e8e8e8;
  background-image: url("images/landscape.webp");
}

如果图像本身传达信息,例如文本中的照片或说明性图表,则使用 HTML 的 img 标签和替代文本是合适的。你不能直接将 alt 属性附加到 CSS 背景上。在本课的空白练习框中,你需要填写一个描述比较结果的可访问性名称,但在实际服务中每次使用装饰性背景时,你无需添加 role。不要将重要描述仅放在背景图像中。

准备示例图像和文件夹

打开下面的 600×400 练习背景图像,并将其保存为 landscape.webp。使用左右的树木和中心圆圈作为比较对象。将 3:2 比例的图片放入正方形框中,这样可以更容易地看到各部分是如何裁剪的。

background-practice/
  backgrounds.html
  images/
    landscape.webp

因为示例将其 CSS 嵌入到 backgrounds.html 中,所以 images/landscape.webp 是从该 HTML 文档解析的。如果你将样式移动到 css/style.css,请使用 ../images/landscape.webp 对同一图片进行处理。外部 CSS 中的相对 URL 是从样式表解析的。还要检查文件名的大小写和扩展名。有关更多细节,请参见 MDN:background-image。参见 使用内联、内部和外部样式应用 CSS 。

比较 cover 和 contain

数值 图像比例 将一个 600×400 的图片放入 300×300 的盒子后的结果
cover 保持 缩放到 450×300 并裁剪左右各 75px。
contain 保持 缩小到 300×200,上下各留空 50px。
100% 100% 原始比例可能有所不同 可以通过设置为 300×300 将圆形变为椭圆形。

这些尺寸假设背景区域为300 × 300,居中定位,无重复,无边框或内边距。cover通过裁剪部分图像来填充区域;contain保留整个图像,并在未使用的空间中显示背景色。当图像和区域的比例相同时,这两种结果看起来可能相同。参见 MDN:background-size。

示意对比使用3:2横向图像来说明两种尺寸计算方式。使用 cover 时,图像两侧会被裁剪。使用 contain 时,整个图像保持可见,灰色背景出现在图像的上下。完整示例让您可以使用提供的练习图像比较这些效果。

300×300 背景区域示意图:cover 将图片左右各裁掉 75px;contain 显示完整图片,上下各留空 50px。

如果你将 cover·contain 与没有特定大小和比例的普通 CSS 渐变进行比较,差别几乎不可见,因为它们填充的是相同的区域。为了练习裁剪,请使用具有固定大小和比例的图片文件,就像现在这样。

控制重复和位置

.repeat {
  background-size: 100px auto;
  background-repeat: repeat;
  background-position: left top;
}

.no-repeat {
  background-size: 100px auto;
  background-repeat: no-repeat;
  background-position: left top;
}

background-size: 100px auto 将宽度设置为 100px,高度与原始比例相匹配。repeat 会在背景区域中重复填充一张小图片,no-repeat 则只显示一次。如果没有关闭默认的 repeat,contain 留出的空白区域也可能继续平铺图片,因此在比较整个图片时请指定 no-repeat。

background-position 设置放置图像的标准。center 将剩余空间或裁剪部分在两侧均分,而 left top 则根据左上角进行对齐。如果你更改 cover 的定位,大小不会改变,但裁剪的那一侧会改变。示例使用了单独的属性,所以在之后添加 background 简写属性时,应检查是否把未写出的背景子属性重置为初始值。

运行完整的背景示例

将下面的代码以 UTF-8 保存到之前准备的文件夹中的 backgrounds.html,并打开它。在四个框中使用同一张图片来比较大小和重复情况。如果窗口较窄,框的宽度会缩小,而高度保持为 300px,因此裁剪和空白部分的大小也会重新计算。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Comparing background image sizes</title>
  <style>
    * { box-sizing: border-box; }
    body { margin: 24px; color: #333; font: 1rem/1.7 sans-serif; }
    .sample { width: 100%; max-width: 300px; height: 300px; margin-block-end: 24px;
      background-color: #e8e8e8; background-image: url("images/landscape.webp");
      background-position: center; background-repeat: no-repeat; }
    .cover { background-size: cover; }
    .contain { background-size: contain; }
    .repeat { background-size: 100px auto; background-repeat: repeat; background-position: left top; }
    .no-repeat { background-size: 100px auto; background-position: left top; }
  </style>
</head>
<body>
  <h1>Comparing background images</h1>
  <h2>cover:Fill the box</h2><div class="sample cover" role="img" aria-label="Background with left and right sides cut out"></div>
  <h2>contain:Contains the entire picture</h2><div class="sample contain" role="img" aria-label="Background with empty space above and below"></div>
  <h2>repeat: small repetition</h2><div class="sample repeat" role="img" aria-label="Background with repeated small pictures"></div>
  <h2>no-repeat:Show small once</h2><div class="sample no-repeat" role="img" aria-label="Background with one small image in the upper left corner"></div>
</body>
</html>

一次只更改一个属性

  1. 把窗口加宽,再在开发者工具中确认前两个框的尺寸为 300×300。比较cover的左侧和右侧裁剪,以及contain的上下空间。
  2. 只更改cover的background-position为left top。确认左侧更多的树木可见而右侧裁剪更多后,再将其恢复为center。
  3. 将contain的background-repeat更改为repeat。检查空白区域是否有部分图片重复,然后恢复为no-repeat。
  4. 将 .no-repeat 的 background-size 从 100px auto 改为 100% 100%。检查中心圆的比例是否变化,并将其恢复为原始值。

诊断缺失的图像和意外裁剪

  • 直接打开练习图像链接以确保原始文件可见。检查保存的文件名和实际扩展名,并根据 HTML/CSS 位置计算路径。
  • 在开发者工具的网络面板中检查图像请求。404 响应需要检查路径。如果响应成功但图像不可见,请检查盒子尺寸和应用的 background-image 声明。
  • 如果你希望它填满而没有空白空间,请检查是否使用 cover。要显示整张图片,请同时指定 contain 和 no-repeat。如果原图与背景区域的宽高比相同,两者的差异将很小。
  • 如果你在文字后面添加背景,确保文字在明亮和暗的区域都清晰可读。因为本课的目的是比较图片,所以说明文字放置在框外。

在强行拉伸背景图之前,先决定它是需要完整展示的图片,还是可以裁剪的装饰。需要完整展示的图片,例如产品照片或说明性图示,以及装饰性背景,不应采用相同的处理标准。