第07篇:图片与多媒体
网页有了文字和链接,还需要图片来丰富视觉表达。从基础的
img标签到响应式图片、语义化图片容器,本篇带你全面掌握。
学习目标
- 深入理解
img标签的所有重要属性及其作用 - 掌握
srcset和sizes实现响应式图片 - 学会使用
picture元素按条件加载不同图片 - 理解
figure+figcaption的语义化图片包裹 - 了解图片懒加载和加载失败的降级处理
核心知识点
一、img标签全面解析
img是网页中最常用的媒体标签,用于嵌入图片资源。
<imgsrc="photo.jpg"alt="一只橘猫在阳光下睡觉"width="600"height="400"loading="lazy">核心属性详解
| 属性 | 作用 | 是否必须 | 示例值 |
|---|---|---|---|
src | 图片路径(Source) | ✅ | "images/cat.jpg"、"https://..." |
alt | 替代文本描述 | ✅ | "一只橘猫在阳光下睡觉" |
width | 图片显示宽度(像素) | 推荐 | "600" |
height | 图片显示高度(像素) | 推荐 | "400" |
loading | 加载策略 | 推荐 | "lazy"(懒加载)、"eager"(立即加载) |
decoding | 解码策略 | 可选 | "async"、"sync"、"auto" |
srcset | 多分辨率图片列表 | 进阶 | 见下文 |
sizes | 图片在不同视口下的显示尺寸 | 配合 srcset | 见下文 |
alt属性的正确用法(再强调!)
alt不是可有可无的装饰,它承载三个核心功能:
- 图片加载失败时显示替代文字
- 屏幕阅读器朗读给视障用户
- 搜索引擎通过
alt理解图片内容
<!-- ✅ 好的 alt:准确描述图片内容 --><imgsrc="team-photo.jpg"alt="公司2024年度团建合影,15名员工在天安门广场前微笑">"<!-- ❌ 差的 alt:没有信息价值 --><imgsrc="team-photo.jpg"alt="图片">"<imgsrc="team-photo.jpg"alt="照片">"<!-- ✅ 装饰性图片:alt 设为空字符串 --><imgsrc="divider-line.png"alt=""role="presentation">width和height的重要性
<!-- ✅ 同时设置宽高:浏览器能预留空间,避免布局抖动(CLS) --><imgsrc="hero.jpg"width="1200"height="600"alt="首屏大图"><!-- ❌ 只设置 width:浏览器不知道高度,图片加载时内容会跳动 --><imgsrc="hero.jpg"width="1200"alt="首屏大图">💡CLS(Cumulative Layout Shift):图片没有预设尺寸时,加载完成后会撑开空间,导致页面内容突然下移,用户体验很差。同时设置
width+height可以让浏览器提前预留空间。
二、响应式图片:srcset与sizes
不同设备需要不同尺寸的图片:手机上加载 400px 宽就够了,桌面显示器可能需要 1200px。srcset让浏览器根据设备条件自动选择最合适的图片。
基于像素密度的srcset(DPR)
<imgsrc="photo-1x.jpg"srcset="photo-1x.jpg 1x, photo-2x.jpg 2x, photo-3x.jpg 3x"alt="产品照片">| 语法 | 含义 |
|---|---|
photo-1x.jpg 1x | 标准屏(DPR=1)使用 |
photo-2x.jpg 2x | 视网膜屏(DPR=2,如 iPhone)使用 |
photo-3x.jpg 3x | 高密度屏(DPR=3)使用 |
基于宽度的srcset+sizes
<imgsrc="flower-400.jpg"srcset="flower-400.jpg 400w, flower-800.jpg 800w, flower-1200.jpg 1200w"sizes="(max-width: 600px) 100vw, (max-width: 900px) 50vw, 33vw"alt="一束鲜花">逐行解析:
| 代码 | 含义 |
|---|---|
srcset中的400w | 告诉浏览器这张图片的实际宽度是 400 像素 |
sizes="(max-width: 600px) 100vw" | 当视口 ≤ 600px 时,图片显示宽度是视口宽度的 100% |
sizes="(max-width: 900px) 50vw" | 当 600px < 视口 ≤ 900px 时,图片显示宽度是视口的 50% |
sizes="33vw" | 默认情况(视口 > 900px),图片显示宽度是视口的 33% |
浏览器的选择逻辑:
1. 浏览器知道当前视口宽度(如 375px,iPhone) 2. 查 sizes:375px ≤ 600px → 图片显示宽度 = 100vw = 375px 3. 查 srcset:哪张图片最接近 375px?flower-400.jpg(400w) 4. 加载 flower-400.jpg💡简单记忆:
srcset提供"有哪些可选图片",sizes告诉浏览器"图片会显示多大"。浏览器根据这两个信息做最优选择。
三、picture元素:艺术指导(Art Direction)
srcset解决的是"同一图片的不同尺寸",而picture解决的是"不同场景下显示完全不同的图片"。
<picture><!-- 当视口宽度 ≥ 800px 时,使用这张大图 --><sourcesrcset="hero-desktop.jpg"media="(min-width: 800px)"><!-- 当视口宽度 ≥ 400px 时,使用这张中图 --><sourcesrcset="hero-tablet.jpg"media="(min-width: 400px)"><!-- 兜底:移动端小图(img 必须存在,作为后备) --><imgsrc="hero-mobile.jpg"alt="响应式英雄图"></picture>picture的使用场景
| 场景 | 说明 |
|---|---|
| 裁切不同构图 | 桌面显示完整风景,手机只显示核心主体 |
| 格式回退 | 优先使用 WebP,不支持则回退到 JPEG |
| 方向适配 | 横屏设备显示横图,竖屏设备显示竖图 |
格式回退示例(WebP → JPEG)
<picture><!-- 浏览器支持 WebP 就用 WebP(体积更小) --><sourcesrcset="image.webp"type="image/webp"><!-- 不支持就回退到 JPEG --><sourcesrcset="image.jpg"type="image/jpeg"><!-- 最后的 img 是必须的 --><imgsrc="image.jpg"alt="描述图片"></picture>⚠️注意:
picture本身不产生任何视觉效果,它只是图片的"包装器"。真正的显示由内部的img完成。
四、语义化图片容器:figure+figcaption
当图片需要附带说明文字时,使用figure包裹,语义更清晰。
<figure><imgsrc="mars-rover.jpg"alt="火星车在红色沙丘上行驶"width="800"height="500"><figcaption>图 1:毅力号火星车在 Jezero 陨石坑采集岩石样本。 图片来源:NASA/JPL-Caltech</figcaption></figure>figure的语义
figure表示独立的内容单元,通常包含:
- 一张图片 + 说明
- 一段代码 + 说明
- 一个图表/表格 + 说明
- 一段引用 + 说明
<!-- figure 不只用于图片 --><figure><pre><code>const greeting = "Hello, World!";</code></pre><figcaption>示例 2.1:JavaScript 的常量声明</figcaption></figure>figcaption的位置
figcaption可以放在figure的第一个子元素位置(说明在图片上方)或最后一个子元素位置(说明在图片下方):
<figure><figcaption>图 1:产品外观(上方说明)</figcaption><imgsrc="product.jpg"alt="产品照片"></figure><figure><imgsrc="product.jpg"alt="产品照片"><figcaption>图 1:产品外观(下方说明)</figcaption></figure>五、图片懒加载
懒加载(Lazy Loading)让图片在即将进入视口时才加载,减少初始页面加载时间。
<!-- 页面首屏的图片:立即加载 --><imgsrc="hero.jpg"alt="首屏大图"loading="eager"><!-- 页面底部的图片:懒加载 --><imgsrc="gallery-1.jpg"alt="画廊照片1"loading="lazy"><imgsrc="gallery-2.jpg"alt="画廊照片2"loading="lazy">| 值 | 行为 | 使用场景 |
|---|---|---|
eager | 立即加载(默认值) | 首屏图片、关键内容 |
lazy | 滚动到视口附近才加载 | 首屏下方的图片、长列表图片 |
六、图片加载失败的处理
图片可能因网络问题、路径错误、服务器故障而加载失败。
使用onerror事件(JavaScript)
<imgsrc="photo.jpg"alt="描述"onerror="this.src='fallback.jpg'">使用 CSS 降级样式
<style>img{/* 图片加载前显示占位背景 */background-color:#f0f0f0;/* 图片加载失败时显示破碎图片图标 */}</style>⚠️最佳实践:始终提供有意义的
alt文本,这是图片加载失败时唯一的降级内容。
七、图片格式速查
| 格式 | 特点 | 适用场景 |
|---|---|---|
| JPEG | 有损压缩,体积小,不支持透明 | 照片、复杂图像 |
| PNG | 无损压缩,支持透明 | 图标、需要透明的图片、截图 |
| GIF | 支持动画,最多 256 色 | 简单动画(逐渐被 WebP/Video 替代) |
| WebP | 体积小、支持透明和动画 | 现代浏览器的首选格式 |
| SVG | 矢量,无限缩放不失真 | 图标、Logo、简单图形 |
| AVIF | 体积比 WebP 更小 | 前沿格式,兼容性还在提升 |
动手练习
练习 1:完善图片标签
找出以下代码的问题并修正:
<imgsrc="banner.png"><imgsrc="photo.jpg"alt="图片"width="100%"><imgsrc="icon.svg"alt=""width="24"height="24">练习 2:响应式图片实战
使用srcset+sizes为一篇文章配图创建响应式方案:
- 准备三张不同尺寸的图片(400w、800w、1200w)
- 当视口 ≤ 600px 时,图片占满宽度
- 当 600px < 视口 ≤ 1000px 时,图片占 80% 宽度
- 当视口 > 1000px 时,图片固定 800px 宽
- 在浏览器 DevTools 的设备模拟中测试不同尺寸
练习 3:图片画廊页面
创建一个包含 6 张图片的画廊页面:
- 每张图片使用
figure+figcaption包裹 - 首屏图片立即加载,其余图片懒加载
- 为每张图片写好
alt文本 - 使用
picture实现移动端和桌面端显示不同裁切比例的图片(至少一张)
常见误区 ⚠️
| 误区 | 真相 |
|---|---|
“alt可以不写” | 必须写!不写会导致可访问性问题和 SEO 损失 |
“width="100%"是正确的写法” | width属性只接受像素值(无单位)。百分比用 CSSwidth: 100% |
“srcset会自动调整图片大小” | srcset只决定加载哪张图片,显示大小还是由 CSS 或width属性控制 |
“picture可以省略img” | 不可以!img是必需的,不支持source的浏览器会回退到img |
| “懒加载对所有图片都好” | 首屏图片应该loading="eager",否则用户会看到一个空白 |
“figure只能放图片” | figure可以包裹任何独立内容单元:代码、引用、图表等 |
| “WebP 所有浏览器都支持” | IE 不支持,Safari 14 以下不支持。生产环境需提供格式回退 |
| “图片越大越清晰越好” | 过大的图片浪费带宽。用srcset提供合适尺寸,或用压缩工具优化 |
速查卡片 📋
img标签完整属性
<imgsrc="图片路径"alt="替代文本描述"width="显示宽度"<!--像素值,无单位-->height="显示高度"<!-- 像素值,无单位 -->loading="lazy"<!-- lazy | eager -->decoding="async"<!-- async | sync | auto -->srcset="..."<!-- 响应式图片源 -->sizes="..."<!-- 配合 srcset 使用 -->>srcset+sizes模板
<!-- 基于宽度(w 描述符)--><imgsrcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"sizes="(max-width: 600px) 100vw, 50vw"src="medium.jpg"alt="描述"><!-- 基于像素密度(x 描述符)--><imgsrcset="photo.jpg 1x, photo@2x.jpg 2x"src="photo.jpg"alt="描述">picture元素模板
<picture><sourcesrcset="image.webp"type="image/webp"><sourcesrcset="image.jpg"type="image/jpeg"media="(min-width: 800px)"><imgsrc="image-fallback.jpg"alt="描述"></picture>figure+figcaption模板
<figure><imgsrc="photo.jpg"alt="描述"width="800"height="600"><figcaption>图片说明文字</figcaption></figure>图片格式选择决策
是照片/复杂图像? ├── 是 → 需要透明? │ ├── 是 → PNG(或 WebP) │ └── 否 → JPEG(或 WebP) └── 否 → 是图标/Logo/图形? ├── 是 → SVG(无限缩放) └── 否 → 是简单动画? ├── 是 → WebP 动画 / 视频 └── 否 → PNG图片 checklist
alt属性已填写,描述准确width+height已同时设置,避免布局抖动- 首屏图片用
loading="eager",其余用loading="lazy" - 大尺寸图片考虑
srcset响应式加载 - 需要说明文字时用
figure+figcaption
扩展阅读
- MDN: 元素
- MDN: 响应式图片
- MDN: 元素
- MDN:
和 - Google Web.dev: 优化图片加载(英文)
📌下一步:图片让页面有了视觉表达,接下来进入 第08篇:音频与视频,让页面"有声有色"。