第30课:响应式设计与媒体查询——移动优先、断点、@media 与容器查询简介
响应式设计(Responsive Design)是让同一个网站或应用在不同屏幕尺寸、不同设备上都能提供良好体验的设计哲学。其核心支柱是媒体查询(Media Queries)——允许 CSS 根据视口宽度、设备特性等条件应用不同的样式。本节课将系统讲解移动优先策略、断点的选择与命名、@media 的完整语法与逻辑组合,以及现代响应式布局的新星——容器查询(Container Queries) 的基本原理。
1. 移动优先(Mobile First)策略
1.1 两种设计策略对比
| 策略 | 基础样式面向 | 媒体查询方向 | 优点 | 缺点 |
|---|---|---|---|---|
| 桌面优先 | 大屏幕(桌面) | max-width 逐步降级小屏 |
历史习惯,大屏设计更“完整” | 小屏加载大屏资源,代码臃肿,维护难 |
| 移动优先 | 小屏幕(手机) | min-width 逐步增强大屏 |
性能更优,代码更简洁,移动优先策略 | 需转变思维,初期设计需克制 |
移动优先是当前业界推荐的主流策略。其核心原则:
- 基础样式:针对最小屏幕(通常是 320px~375px 的手机竖屏)编写,不使用任何媒体查询。
- 增强样式:使用
min-width媒体查询,在屏幕宽度达到特定断点时叠加或覆盖样式。
1 | /* 基础样式:手机竖屏 */ |
1.2 为什么移动优先?
- 移动端用户占比高:全球超过一半的 Web 流量来自移动设备。
- 性能优先:移动设备网络和 CPU 受限,基础样式仅包含最核心的样式,不加载不必要的增强。
- 渐进增强:从核心体验开始,逐步叠加,符合 Web 的基本哲学。
- 代码更简洁:
min-width的叠加逻辑比max-width的覆盖逻辑更清晰,减少不必要的重置。
2. 断点(Breakpoints):选择与命名
2.1 常见断点参考
断点不应根据某个特定设备的宽度设定(因为设备不断更新),而应基于内容需要——当布局开始变得不协调时,设置断点。以下是业界常用的一组参考值:
| 断点名称 | 宽度条件 | 典型设备 |
|---|---|---|
xs |
< 576px | 手机竖屏 |
sm |
>= 576px | 手机横屏 / 小型平板 |
md |
>= 768px | 平板竖屏 |
lg |
>= 992px | 平板横屏 / 小型桌面 |
xl |
>= 1200px | 桌面 |
xxl |
>= 1400px | 大屏桌面 |
这些与 Bootstrap 5 的断点完全一致,可在团队中作为默认约定。
2.2 用 CSS 自定义属性管理断点(可选)
虽然 CSS 媒体查询不能直接使用变量,但预处理器或未来的 CSS 环境变量可以辅助管理。在纯 CSS 中,通常将断点值直接写在 @media 中,并通过注释标注:
1 | /* 断点参考: |
也可以使用 @custom-media 规范(尚未被所有浏览器原生支持,需 PostCSS 插件),语法如 @custom-media --sm (min-width: 576px);,但目前不建议在生产中直接使用。
3. @media 语法与逻辑组合
3.1 基本语法
1 | @media <media-type> and (<media-feature>) { |
- **
media-type**:all(默认,所有设备)、screen(屏幕)、print(打印)、speech(屏幕阅读器)。 - **
media-feature**:最常见的是min-width、max-width、orientation、prefers-color-scheme等。
1 | /* 仅屏幕设备,宽度 >= 768px */ |
3.2 逻辑运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
and |
逻辑与,所有条件必须满足。 | @media (min-width: 768px) and (orientation: landscape) |
, |
逻辑或,任一条件满足即应用。 | @media (max-width: 575px), (min-width: 1200px) |
not |
对整个媒体查询取反。 | @media not screen and (min-width: 768px) |
only |
阻止老浏览器解析(已极少用)。 | @media only screen and (min-width: 768px) |
注意:not 必须放在媒体查询的开头,它对整个媒体查询语句取反,而不是单个条件。
1 | /* 宽度 < 768px 时应用(因为 not 翻转了整个条件) */ |
更清晰的写法是直接用 max-width:
1 | @media (max-width: 767px) { |
3.3 区间范围的现代写法
CSS Media Queries Level 4 引入了区间语法,使用 <、<=、>、>= 直接比较,更加直观。
1 | /* 传统写法 */ |
优点:
- 更接近自然语言的表达方式。
- 避免使用
min-和max-时的混淆。 - 清晰表达闭合区间。
兼容性:Chrome 104+、Firefox 102+、Safari 16.4+ 均已支持。企业项目中需根据 browserslist 决定是否使用。
3.4 常见的媒体特性
除了宽度和高度,媒体查询还支持众多特性。
| 媒体特性 | 说明 | 示例 |
|---|---|---|
width / min-width / max-width |
视口宽度。 | (min-width: 768px) |
height / min-height / max-height |
视口高度。 | (min-height: 600px) |
orientation |
设备方向:portrait(竖屏)或 landscape(横屏)。 |
(orientation: landscape) |
prefers-color-scheme |
系统主题:light、dark。 |
(prefers-color-scheme: dark) |
prefers-reduced-motion |
用户是否减少动画。 | (prefers-reduced-motion: reduce) |
resolution |
设备像素密度(dpi / dpcm)。 | (min-resolution: 2dppx) |
hover |
主输入设备是否支持悬停(hover / none)。 |
(hover: hover) |
应用示例:暗色模式与减少动画偏好
1 | :root { |
4. 视口 <meta> 与响应式的基石
第 2 课已简要介绍过视口元标签。这里再次强调:没有它,任何媒体查询都不会在移动端生效。
1 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
- **
width=device-width**:将布局视口宽度设置为设备的理想视口宽度(如 iPhone 14 为 390px)。 - **
initial-scale=1.0**:初始缩放比为 1:1。
若缺失此标签,移动端浏览器会使用默认的 980px 视口宽度,导致所有基于小屏的媒体查询失效,页面被缩小,文字如针尖。
5. 容器查询(Container Queries)简介
媒体查询基于视口改变样式,而容器查询基于父容器的尺寸改变样式。这对于构建可复用的响应式组件至关重要——同一个组件放在不同的容器中,样式自适应容器,而非整个页面。
5.1 定义容器
使用 container-type 声明一个元素为查询容器。
1 | .card-wrapper { |
inline-size:仅基于宽度查询(最常用)。size:同时支持宽度和高度查询(使用较少)。normal:默认值,不是查询容器。
5.2 容器查询语法
1 | @container card (min-width: 400px) { |
当 .card-wrapper 的宽度 >= 400px 时,.card 变为水平布局;小于 400px 时,变为垂直堆叠。
5.3 容器查询 vs 媒体查询
| 对比维度 | 媒体查询 (@media) |
容器查询 (@container) |
|---|---|---|
| 参照系 | 视口(整个浏览器窗口) | 父容器(元素的直接容器) |
| 组件复用性 | 低——组件样式依赖全局视口宽度,难以独立复用。 | 高——组件样式仅依赖自身容器,任意放置均可自适应。 |
| 典型场景 | 页面整体布局、导航栏切换。 | 卡片布局、侧边栏中的列表、不同宽度的模块。 |
| 浏览器支持 | 所有浏览器。 | 现代浏览器(Chrome 105+、Safari 16+、Firefox 110+)。 |
5.4 容器查询综合示例
1 | <style> |
课后练习
一、概念自测(选择题 / 填空题)
(单选) 移动优先策略的核心是?
A. 使用max-width降级桌面样式。
B. 先编写大屏样式,再覆盖小屏。
C. 基础样式面向小屏幕,用min-width逐步增强大屏。
D. 所有样式都写在@media (max-width: 640px)中。(单选) 以下哪个媒体查询写法可以匹配宽度在 768px 到 1199px 之间的屏幕?
A.@media (min-width: 768px) and (max-width: 1199px)
B.@media (width >= 768px) and (width <= 1199px)
C.@media (768px <= width <= 1199px)
D. 以上均可。(填空) 要声明一个元素为容器查询的参照容器,应设置 CSS 属性
______: inline-size;。(多选) 以下哪些是 CSS 媒体查询支持的逻辑运算符?
A.and
B.or
C.not
D.,
二、AI 编程任务:编写面向 AI 的提示词
场景:实现一个响应式导航栏。要求如下:
- 移动端(< 768px)显示汉堡菜单图标(☰),菜单项垂直堆叠隐藏,点击汉堡图标展开。
- 平板及以上(>= 768px)菜单水平排列,隐藏汉堡图标。
- 使用移动优先策略,基础样式为移动端,通过
min-width: 768px增强。 - 菜单展开/收起的交互使用纯 CSS 实现(通过隐藏的
<input type="checkbox">的:checked状态控制),无需 JavaScript。 - 汉堡图标使用 Unicode 字符 ☰ 和 ✕ 切换。
任务要求:请写出一段完整的中文提示词,发送给 AI,使其生成符合上述要求的 HTML + CSS 代码。提示词中需明确指定移动优先的基础样式、min-width 媒体查询、以及纯 CSS 交互的实现方式。
三、Agent 模式下的提示词示例
你是一个资深前端开发 Agent。请构建一个纯 CSS 响应式导航栏组件,遵循移动优先策略。需要创建以下文件:
index.html:包含导航栏的完整 HTML 结构。使用<nav class="navbar">,内部包含一个 Logo 链接、一个隐藏的<input type="checkbox" id="menu-toggle">作为汉堡菜单开关、一个<label for="menu-toggle">显示 ☰/✕、以及一个<ul class="nav-links">包含 4 个菜单项。styles/navbar.css:基础样式面向移动端(< 768px):.nav-links默认display: none;,当#menu-toggle:checked ~ .nav-links时display: flex; flex-direction: column;。使用@media (min-width: 768px)将.nav-links设为display: flex; flex-direction: row;,并隐藏汉堡图标和复选框。添加平滑过渡动画。styles/global.css:引入盒模型重置、基础字体。- 确保所有交互完全由 CSS 实现,注释解释关键选择器的作用。在
index.html中正确引入 CSS 文件。
四、面试真题与参考答案
题目(字节跳动前端面试题):
请解释响应式设计中“移动优先”策略的含义和优势。它与“桌面优先”策略有什么区别?在使用媒体查询时,
min-width和max-width的选用分别适用于哪种策略?
参考答案:
1. 含义与优势:
移动优先是指先针对移动设备的小屏幕编写基础样式,再通过 min-width 媒体查询为更大屏幕添加增强样式。优势包括:性能更优(移动设备仅加载最少的样式)、代码逻辑更清晰(叠加而非覆盖)、符合移动互联网发展趋势。
2. 与桌面优先的区别:
桌面优先先编写大屏的完整样式,再通过 max-width 为小屏降级或隐藏内容。这种方式容易导致移动端加载大量不必要的样式,且覆盖逻辑复杂,容易产生优先级冲突。
3. 媒体查询的选用:
- 移动优先使用
min-width:例如@media (min-width: 768px),表示“当屏幕至少 768px 时,应用这些增强样式”。基础样式在小屏生效,大屏叠加。 - 桌面优先使用
max-width:例如@media (max-width: 767px),表示“当屏幕不超过 767px 时,应用这些降级样式”。基础样式在大屏生效,小屏覆盖。 - 区间范围可使用两者组合或现代语法
(768px <= width <= 1199px)进行精确限定。
课后练习答案
一、概念自测答案
C
- 解析:移动优先的基础样式面向小屏,通过
min-width增强。A 和 B 描述的是桌面优先。D 错误,基础样式不应写在媒体查询内。
- 解析:移动优先的基础样式面向小屏,通过
D
- 解析:A 是传统写法,B 和 C 是 Media Queries Level 4 的新语法(注意 B 语法略有差异,实际标准为
width >= 768px等,但现代浏览器均支持区间语法)。题目中 B 的写法虽不完全标准,但核心是 D 表示以上均可(因为 Level 4 语法在现代浏览器中可用)。
- 解析:A 是传统写法,B 和 C 是 Media Queries Level 4 的新语法(注意 B 语法略有差异,实际标准为
container-type- 解析:
container-type是声明容器查询容器的属性,常用值inline-size。
- 解析:
A、C、D
- 解析:
and表示与,,表示或,not表示非。不存在or关键字,应使用逗号。
- 解析:
二、AI 编程任务参考答案(提示词示例)
示例提示词:
“请实现一个响应式导航栏,纯 HTML + CSS,移动优先。要求:
- HTML 使用隐藏的
<input type="checkbox" id="menu-toggle">和<label for="menu-toggle">作为汉堡图标(显示 ‘☰’,选中后变为 ‘✕’)。- 基础样式(移动端,< 768px):
.nav-links默认display: none;,当 checkbox 选中时(#menu-toggle:checked ~ .nav-links)显示为flex; flex-direction: column;。- 使用
@media (min-width: 768px)将.nav-links设为display: flex; flex-direction: row;,并隐藏 checkbox 和 label。- 菜单项背景、颜色、间距自行设计,确保美观。直接输出完整 HTML 文件。”