Skip to content

图片尺寸与响应式图片

在网页中使用图片时,控制尺寸和适应不同屏幕是两个核心问题。本节将介绍如何通过 HTML 属性和 CSS 控制图片尺寸,以及如何实现响应式图片策略来适配各种设备和屏幕分辨率。

前置知识

阅读本节前,建议先了解:src 与 alt 属性

基础概念

图片尺寸控制涉及两个层面:HTML 属性width/height)和 CSS 样式。HTML 属性用于告诉浏览器图片的原始尺寸,帮助浏览器在图片下载前预留空间,防止累积布局偏移(CLS)。CSS 则控制图片在页面中的实际显示尺寸。

响应式图片是指根据用户设备的屏幕宽度、分辨率等因素,自动加载最合适的图片版本。这不仅提升了用户体验,还减少了不必要的带宽消耗。

语法

width 和 height 属性

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>图片尺寸属性</title>
</head>
<body>
  <h1>width 与 height 属性</h1>

  <!-- 只设置 width,高度按比例缩放 -->
  <img src="photo.jpg" alt="风景照片" width="300">

  <br>

  <!-- 同时设置 width 和 height -->
  <img src="photo.jpg" alt="风景照片" width="300" height="200">

  <br>

  <!-- 错误:width 和 height 比例与原图不一致,图片变形 -->
  <!-- <img src="photo.jpg" alt="风景照片" width="300" height="100"> -->

  <!-- 原始尺寸(不推荐:可能导致布局偏移) -->
  <img src="photo.jpg" alt="风景照片">
</body>
</html>

CSS 控制图片尺寸

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>CSS 控制图片尺寸</title>
  <style>
    /* 固定宽高 */
    .fixed-size {
      width: 400px;
      height: 300px;
      object-fit: cover; /* 裁剪填满 */
    }

    /* 自适应宽度 */
    .responsive {
      width: 100%;
      height: auto; /* 保持比例 */
      max-width: 600px;
    }

    /* 限制最大尺寸 */
    .max-size {
      max-width: 100%;
      max-height: 400px;
    }

    /* CSS 宽高与 HTML 属性宽高的区别 */
    .css-sized {
      width: 200px;
      /* CSS width 覆盖 HTML width 属性 */
    }
  </style>
</head>
<body>
  <h1>CSS 控制图片尺寸</h1>

  <!-- CSS 固定尺寸 + object-fit -->
  <img class="fixed-size" src="photo.jpg" alt="风景" width="800" height="600">

  <!-- CSS 响应式宽度 -->
  <img class="responsive" src="photo.jpg" alt="风景" width="800" height="600">

  <!-- CSS 限制最大尺寸 -->
  <img class="max-size" src="photo.jpg" alt="风景" width="1920" height="1080">
</body>
</html>

详细说明

HTML 属性 vs CSS 控制

HTML 的 width/height 属性和 CSS 的 width/height 有不同的用途:

对比项HTML width/heightCSS width/height
单位像素(无单位数值)像素、百分比、em 等
作用预留布局空间控制实际显示尺寸
优先级被 CSS 覆盖优先级更高
目的防止 CLS视觉呈现
是否必须建议设置按需设置

为什么设置 width/height 属性很重要

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>CLS 演示</title>
</head>
<body>
  <h1>设置 width/height 防止布局偏移</h1>

  <!-- 推荐:设置了 width 和 height -->
  <!-- 浏览器在图片下载前就能预留正确空间 -->
  <p>文章标题</p>
  <img src="hero.jpg" alt="文章配图" width="800" height="450">
  <p>文章正文内容...</p>

  <hr>

  <!-- 不推荐:未设置 width 和 height -->
  <!-- 图片下载前不占空间,下载后页面布局突然跳动 -->
  <!-- <p>文章标题</p> -->
  <!-- <img src="hero.jpg" alt="文章配图"> -->
  <!-- <p>文章正文内容...</p> -->
</body>
</html>

CLS 累积布局偏移

当页面元素在加载过程中发生位置变化,会导致 CLS(Cumulative Layout Shift)。不设置图片尺寸是 CLS 的常见原因之一。Google 将 CLS 作为 Core Web Vitals 指标,影响搜索排名。

CSS object-fit 属性

object-fit 控制图片在指定容器中的填充方式:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>object-fit 属性</title>
  <style>
    .box {
      width: 300px;
      height: 200px;
      border: 2px solid #333;
      margin-bottom: 10px;
      overflow: hidden;
    }

    .box img {
      width: 100%;
      height: 100%;
    }

    .fill img    { object-fit: fill; }
    .contain img { object-fit: contain; }
    .cover img   { object-fit: cover; }
    .none img    { object-fit: none; }
    .scale-down img { object-fit: scale-down; }
  </style>
</head>
<body>
  <h1>object-fit 对比</h1>

  <!-- fill(默认):拉伸填满,可能变形 -->
  <div class="box fill">
    <img src="photo.jpg" alt="fill 模式" width="800" height="600">
  </div>
  <p>fill:拉伸图片填满容器,可能导致变形</p>

  <!-- contain:保持比例,完整显示 -->
  <div class="box contain">
    <img src="photo.jpg" alt="contain 模式" width="800" height="600">
  </div>
  <p>contain:保持比例,完整显示图片,可能留白</p>

  <!-- cover:保持比例,填满容器(可能裁剪) -->
  <div class="box cover">
    <img src="photo.jpg" alt="cover 模式" width="800" height="600">
  </div>
  <p>cover:保持比例,填满容器,超出部分被裁剪</p>

  <!-- none:原始尺寸,可能溢出 -->
  <div class="box none">
    <img src="photo.jpg" alt="none 模式" width="800" height="600">
  </div>
  <p>none:保持原始尺寸,不缩放</p>

  <!-- scale-down:取 none 和 contain 中较小的 -->
  <div class="box scale-down">
    <img src="photo.jpg" alt="scale-down 模式" width="800" height="600">
  </div>
  <p>scale-down:选择 contain 或 none 中较小的结果</p>
</body>
</html>

object-fit 值对比

行为变形裁剪留白
fill拉伸填满可能
contain保持比例,完整显示可能
cover保持比例,填满容器可能
none原始尺寸可能可能
scale-down取 none/contain 较小值可能

object-position 属性

object-position 控制图片在容器中的对齐位置(配合 object-fit: covercontain 使用):

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>object-position</title>
  <style>
    .crop-box {
      width: 300px;
      height: 200px;
      border: 2px solid #333;
      overflow: hidden;
      margin: 10px 0;
    }

    .crop-box img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .center  { object-position: center; }    /* 默认 */
    .top     { object-position: top; }
    .bottom  { object-position: bottom; }
    .left    { object-position: left; }
    .right   { object-position: right; }
    .custom  { object-position: 30% 70%; }   /* 自定义位置 */
  </style>
</head>
<body>
  <h1>object-position 对比</h1>

  <div class="crop-box"><img class="center" src="portrait.jpg" alt="居中" width="400" height="600"></div>
  <p>center(默认):居中显示</p>

  <div class="crop-box"><img class="top" src="portrait.jpg" alt="顶部" width="400" height="600"></div>
  <p>top:对齐顶部,适合人像照片</p>

  <div class="crop-box"><img class="custom" src="portrait.jpg" alt="自定义" width="400" height="600"></div>
  <p>custom 30% 70%:自定义焦点位置</p>
</body>
</html>

响应式图片策略

在不同设备上提供合适的图片尺寸,可以大幅优化性能:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>响应式图片策略</title>
  <style>
    /* 策略 1:CSS max-width 100% */
    .fluid-img {
      width: 100%;
      height: auto;
      max-width: 800px;
      display: block;
    }

    /* 策略 2:CSS 媒体查询切换背景图 */
    .hero {
      width: 100%;
      height: 400px;
      background-size: cover;
      background-position: center;
    }

    @media (max-width: 768px) {
      .hero {
        height: 250px;
        /* 小屏幕使用小图 */
        background-image: url('images/hero-small.jpg');
      }
    }

    @media (min-width: 769px) {
      .hero {
        /* 大屏幕使用大图 */
        background-image: url('images/hero-large.jpg');
      }
    }

    /* 策略 3:使用 srcset 和 sizes(推荐) */
    /* 在 img 标签中直接配置,见下方 HTML */
  </style>
</head>
<body>
  <h1>响应式图片策略</h1>

  <!-- 策略 1:CSS 流式图片 -->
  <figure>
    <img class="fluid-img"
         src="photo-800.jpg"
         alt="流式布局的风景照片"
         width="800" height="533">
    <figcaption>CSS max-width: 100% 让图片自适应容器宽度</figcaption>
  </figure>

  <!-- 策略 3:HTML 响应式属性 -->
  <figure>
    <img src="photo-default.jpg"
         srcset="photo-320.jpg 320w,
                 photo-640.jpg 640w,
                 photo-1024.jpg 1024w,
                 photo-1600.jpg 1600w"
         sizes="(max-width: 480px) 100vw,
                (max-width: 768px) 80vw,
                600px"
         alt="使用 srcset 和 sizes 的响应式图片"
         width="1600" height="1067"
         class="fluid-img">
    <figcaption>HTML srcset + sizes 根据屏幕宽度选择最佳图片</figcaption>
  </figure>

  <!-- 策略 2:CSS 媒体查询背景图 -->
  <div class="hero" role="img" aria-label="城市天际线背景图"></div>
</body>
</html>

响应式图片策略对比

策略方法优点缺点
CSS max-widthwidth: 100%简单直接只缩放不换图,带宽浪费
CSS 媒体查询background-image精确控制无法用 img 标签,SEO 差
HTML srcset/sizessrcset + sizes语义化、SEO 友好语法稍复杂
HTML picture<picture> 元素最灵活代码量较大

实战示例

响应式图片画廊

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>响应式画廊</title>
  <style>
    * {
      box-sizing: border-box;
    }

    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
    }

    .gallery-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
      gap: 20px;
    }

    .card {
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }

    .card img {
      width: 100%;
      height: 220px;
      object-fit: cover;
      display: block;
    }

    .card-body {
      padding: 16px;
    }

    .card-body h3 {
      margin: 0 0 8px;
    }

    .card-body p {
      margin: 0;
      color: #666;
      font-size: 14px;
    }
  </style>
</head>
<body>
  <h1>摄影作品集</h1>
  <p>点击图片查看大图,画廊自动适配不同屏幕尺寸。</p>

  <div class="gallery-grid">
    <div class="card">
      <img src="photo1-600.jpg"
           srcset="photo1-400.jpg 400w, photo1-600.jpg 600w, photo1-900.jpg 900w"
           sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw"
           alt="黄昏时分湖泊的倒影,远处群山轮廓"
           width="900" height="600"
           loading="lazy">
      <div class="card-body">
        <h3>湖畔黄昏</h3>
        <p>宁静的湖面映着夕阳的余晖</p>
      </div>
    </div>

    <div class="card">
      <img src="photo2-600.jpg"
           srcset="photo2-400.jpg 400w, photo2-600.jpg 600w, photo2-900.jpg 900w"
           sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw"
           alt="白雪覆盖的松树林,阳光从树缝中洒下"
           width="900" height="600"
           loading="lazy">
      <div class="card-body">
        <h3>雪中松林</h3>
        <p>冬日暖阳穿过林间的光影</p>
      </div>
    </div>

    <div class="card">
      <img src="photo3-600.jpg"
           srcset="photo3-400.jpg 400w, photo3-600.jpg 600w, photo3-900.jpg 900w"
           sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw"
           alt="夜晚城市的天际线,万家灯火通明"
           width="900" height="600"
           loading="lazy">
      <div class="card-body">
        <h3>城市夜景</h3>
        <p>繁华都市的璀璨灯火</p>
      </div>
    </div>
  </div>
</body>
</html>

注意事项

  • HTML width/height 属性的单位是像素(无需写 px),CSS 中必须写单位
  • CSS 的 width/height 会覆盖 HTML 属性中的同名属性
  • object-fit: cover 可能会裁剪图片,需要配合 object-position 控制焦点
  • 不设置 width/height 属性会导致 CLS,影响 Core Web Vitals 评分
  • width: 100% + height: auto 是最简单的响应式方案,但不适用于需要精确控制的场景
  • CSS background-image 不支持 alt 文本,不利于无障碍和 SEO

最佳实践

  • 始终设置 HTML 的 widthheight 属性(使用图片原始尺寸)
  • 使用 CSS max-width: 100% + height: auto 实现基本的响应式
  • 裁剪区域使用 object-fit: cover + object-position 控制焦点
  • 对于多尺寸适配,优先使用 HTML 的 srcset/sizes<picture> 元素
  • 头图/大图使用 loading="lazy" 实现懒加载
  • 生成多版本图片时,使用 1.5x 和 2x 密度版本覆盖高 DPI 屏幕
  • 使用 CDN + WebP/AVIF 格式进一步优化加载性能

下一节

继续学习:srcset 与 sizes

参考链接