CSS 响应式设计
CoreCSS Layout响应式设计(Responsive Web Design, RWD)使网页能够 自适应 不同屏幕尺寸——从手机到桌面显示器,提供一致且良好的用户体验。
一、📱 为什么需要响应式设计
1.1 设备碎片化
现代用户通过各种尺寸的设备访问网页:
| 设备类型 | 典型宽度范围 |
|---|---|
| 折叠屏/小手机 | 280px – 375px |
| 手机 | 375px – 576px |
| 平板(竖屏) | 576px – 768px |
| 平板(横屏)/ 小笔记本 | 768px – 992px |
| 笔记本 / 桌面 | 992px – 1400px |
| 大屏 / 4K | 1400px + |
1.2 核心原则
| 原则 | 说明 |
|---|---|
| 流体布局 | 使用百分比 / fr / auto 代替固定像素 |
| 弹性媒体 | 图片/视频随容器缩放 |
| 媒体查询 | 在不同断点应用不同样式 |
| 移动优先 | 先为最小屏幕设计,逐步增强 |
二、📐 视口(Viewport)
2.1 Viewport Meta 标签
每个响应式页面 必须 在 <head> 中包含:
html
<meta name="viewport" content="width=device-width, initial-scale=1.0" />| 属性 | 说明 |
|---|---|
width=device-width | 页面宽度等于设备屏幕宽度 |
initial-scale=1.0 | 初始缩放比例为 1:1 |
缺少此标签
如果不加 viewport meta 标签,移动设备会按桌面宽度(通常 980px)渲染页面,然后缩小显示,导致字体极小、无法正常浏览。
2.2 视口单位(Viewport Units)
| 单位 | 全称 | 含义 |
|---|---|---|
vw | viewport width | 视口宽度的 1% |
vh | viewport height | 视口高度的 1% |
vmin | viewport minimum | vw 和 vh 中 较小 的那个 |
vmax | viewport maximum | vw 和 vh 中 较大 的那个 |
css
/* 占满整个视口 */
.hero {
width: 100vw;
height: 100vh;
}
/* 响应式字体大小 */
h1 {
font-size: 5vw; /* 随视口宽度变化 */
}使用场景
| 场景 | 推荐单位 | 示例 |
|---|---|---|
| 全屏英雄区域 | 100vh | 首屏占满整个窗口 |
| 响应式字号 | vw + rem 混合 | font-size: clamp(1rem, 2.5vw, 3rem) |
| 等比正方形 | vmin | width: 50vmin; height: 50vmin; |
vh 的陷阱
在移动端,100vh 可能比可见区域 更高(因为浏览器地址栏)。CSS 新增了 svh(小视口高度)和 dvh(动态视口高度)来解决此问题。
三、📱 媒体查询(Media Queries)
3.1 基本语法
css
/* 当屏幕宽度 ≤ 768px 时应用 */
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}
/* 当屏幕宽度 ≥ 992px 时应用 */
@media (min-width: 992px) {
.sidebar {
display: block;
}
}3.2 常用断点
| 断点名 | 宽度 | 典型设备 |
|---|---|---|
| X-Small | < 576px | 竖屏手机 |
| Small | ≥ 576px | 横屏手机 |
| Medium | ≥ 768px | 平板 |
| Large | ≥ 992px | 笔记本 |
| X-Large | ≥ 1200px | 桌面显示器 |
| XX-Large | ≥ 1400px | 大屏 |
这些是 Bootstrap 的断点
虽然断点值可以自定义,但这组数值已被 Bootstrap 等框架广泛采用,成为行业事实标准。
3.3 移动优先 vs 桌面优先
移动优先(推荐)⭐
先写移动端样式(基础样式),再用 min-width 逐步增强:
css
/* 基础样式 = 移动端 */
.card { width: 100%; }
/* 平板及以上 */
@media (min-width: 768px) {
.card { width: 50%; }
}
/* 桌面及以上 */
@media (min-width: 992px) {
.card { width: 33.3%; }
}桌面优先
先写桌面样式,用 max-width 逐步降级:
css
.card { width: 33.3%; }
@media (max-width: 991px) {
.card { width: 50%; }
}
@media (max-width: 767px) {
.card { width: 100%; }
}| 策略 | 使用 | 优点 |
|---|---|---|
| 移动优先 | min-width | 渐进增强,性能更好 |
| 桌面优先 | max-width | 直觉更自然(但不推荐) |
3.4 组合条件
css
/* 宽度在 576px 到 992px 之间 */
@media (min-width: 576px) and (max-width: 991px) {
.sidebar { display: none; }
}
/* 横屏模式 */
@media (orientation: landscape) {
.hero { height: 50vh; }
}
/* 暗色模式偏好 */
@media (prefers-color-scheme: dark) {
body { background-color: #1a1a1a; color: #e0e0e0; }
}
/* 减少动画偏好 */
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}3.5 媒体查询与 Flexbox/Grid 配合
css
/* Flexbox 响应式:宽屏横排 → 窄屏纵排 */
.container { display: flex; gap: 1rem; }
@media (max-width: 768px) {
.container { flex-direction: column; }
}
/* Grid 响应式:宽屏三列 → 窄屏单列 */
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
@media (max-width: 768px) {
.grid { grid-template-columns: 1fr; }
}四、🖼️ 响应式图片
4.1 基础:max-width
css
img {
max-width: 100%; /* 不超过容器宽度 */
height: auto; /* 保持宽高比 */
}4.2 HTML picture 元素
html
<picture>
<source media="(min-width: 992px)" srcset="large.jpg" />
<source media="(min-width: 576px)" srcset="medium.jpg" />
<img src="small.jpg" alt="响应式图片" />
</picture>根据屏幕宽度加载 不同尺寸 的图片,节省移动端带宽。
4.3 srcset 属性
html
<img src="small.jpg"
srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1000px) 50vw, 33vw"
alt="响应式图片" />浏览器自动选择最合适的图片尺寸。
五、🔤 流体排版(Fluid Typography)
5.1 clamp() 函数
css
h1 {
/* clamp(最小值, 首选值, 最大值) */
font-size: clamp(1.5rem, 4vw, 3rem);
}
p {
font-size: clamp(1rem, 1.5vw, 1.25rem);
}| 参数 | 说明 |
|---|---|
| 最小值 | 字号下限,不会更小 |
| 首选值 | 通常用 vw 单位,随视口变化 |
| 最大值 | 字号上限,不会更大 |
clamp() 的优势
无需媒体查询,字体大小在最小值和最大值之间 平滑过渡,是现代响应式排版的首选方式。
5.2 响应式间距
css
.section {
padding: clamp(1rem, 5vw, 4rem);
margin-bottom: clamp(2rem, 4vh, 6rem);
}六、📱 实用响应式模式
6.1 汉堡菜单
窄屏时将导航栏折叠为汉堡按钮:
css
.nav-links { display: flex; gap: 1rem; }
.hamburger { display: none; }
@media (max-width: 768px) {
.nav-links { display: none; }
.hamburger { display: block; }
}6.2 卡片从横排到竖排
css
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}auto-fit + minmax() 实现 无需媒体查询 的自适应网格。
6.3 侧边栏隐藏
css
.layout {
display: grid;
grid-template-columns: 250px 1fr;
}
@media (max-width: 768px) {
.layout { grid-template-columns: 1fr; }
.sidebar { display: none; }
}七、🔍 Chrome DevTools 响应式调试
7.1 设备模拟器
| 操作 | 快捷键 |
|---|---|
| 切换设备工具栏 | ⌘ + ⇧ + M(Mac)/ Ctrl + Shift + M |
| 选择预设设备 | 顶部下拉菜单(iPhone、iPad 等) |
| 自定义尺寸 | 选择 "Responsive" 模式,拖动边框 |
7.2 查看断点
拖动调试器宽度时,顶部会显示当前像素宽度。可以观察:
- 哪个宽度触发了布局变化
- 媒体查询的断点是否正确
- 不同设备上的实际显示效果
八、💡 实践要点
| # | 要点 | 说明 |
|---|---|---|
| 1 | 始终添加 viewport meta | 缺少它响应式完全失效 |
| 2 | 移动优先 | 基础样式 = 手机,min-width 逐步增强 |
| 3 | 使用相对单位 | %、fr、rem、vw 优于 px |
| 4 | clamp() 替代多个断点 | 字号和间距用 clamp() 平滑过渡 |
| 5 | auto-fit + minmax | 无需媒体查询的响应式网格 |
| 6 | 测试真实设备 | 模拟器不能完全代替真机测试 |