响应式布局实战
# 06.响应式布局实战
媒体查询 @media、rem/vw/vh 响应式单位、容器查询 @container、6 种水平垂直居中方案、圣杯/双飞翼/瀑布流/等高等经典布局。
# 1. 媒体查询 @media
/* 基础语法 */
@media (max-width: 768px) {
.sidebar { display: none; }
}
/* 组合条件 */
@media (min-width: 769px) and (max-width: 1024px) {
.container { max-width: 720px; }
}
/* 设备特性 */
@media (hover: hover) { } /* 支持悬停的设备(桌面) */
@media (pointer: coarse) { } /* 触摸设备(移动端) */
@media (prefers-color-scheme: dark) { } /* 暗色模式 */
@media (prefers-reduced-motion) { } /* 用户偏好减少动画 */
/* 屏幕方向 */
@media (orientation: portrait) { } /* 竖屏 */
@media (orientation: landscape) { } /* 横屏 */
# 1.1 移动优先 vs 桌面优先
/* 移动优先(推荐):先写最小屏,逐步扩展 */
.container { padding: 10px; } /* 手机 */
@media (min-width: 768px) { .container { padding: 20px; } } /* 平板 */
@media (min-width: 1024px) { .container { padding: 30px; } } /* 桌面 */
/* 桌面优先:先写最大屏,逐步收缩 */
.container { padding: 30px; } /* 桌面 */
@media (max-width: 1024px) { .container { padding: 20px; } } /* 平板 */
@media (max-width: 768px) { .container { padding: 10px; } } /* 手机 */
# 1.2 常见断点
/* 移动优先断点 */
@media (min-width: 640px) { } /* sm */
@media (min-width: 768px) { } /* md — 平板 */
@media (min-width: 1024px) { } /* lg — 小桌面 */
@media (min-width: 1280px) { } /* xl — 大桌面 */
# 2. 响应式单位
# 2.1 rem — 根字体相对单位
html { font-size: 16px; } /* 基准 */
.box {
width: 20rem; /* = 20 × 16px = 320px */
font-size: 0.875rem; /* = 14px */
}
/* 移动端适配:等比缩放 */
@media (max-width: 375px) {
html { font-size: 14px; } /* 小屏缩小基准,所有 rem 联动 */
}
# 2.2 vw / vh / vmin / vmax
| 单位 | 含义 |
|---|---|
1vw | 视口宽度的 1% |
1vh | 视口高度的 1% |
1vmin | vw 和 vh 中的较小值 |
1vmax | vw 和 vh 中的较大值 |
.hero { height: 100vh; } /* 全屏首屏 */
.text { font-size: clamp(16px, 4vw, 24px); } /* 文字随宽度缩放,但限制范围 */
.card { width: min(100%, 400px); } /* 最大宽度 400px,窄屏自适应 */
# 2.3 clamp() — 范围限制
/* clamp(min, preferred, max) — 取范围内的首选值 */
h1 { font-size: clamp(1.5rem, 5vw, 3rem); }
/* 最小 1.5rem,最大 3rem,屏幕宽时用 5vw */
# 3. 容器查询 @container
当需要根据父容器宽度(而非视口)调整样式时使用:
/* 定义容器 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 根据容器宽度调整子元素 */
@container card (min-width: 400px) {
.card { display: flex; flex-direction: row; }
}
@container card (max-width: 399px) {
.card { display: flex; flex-direction: column; }
}
⚠️
@container基线 2023 年获得所有现代浏览器支持,生产项目可使用。
# 4. 水平垂直居中(6 种方案)
/* ① Flexbox(推荐,最通用) */
.parent { display: flex; justify-content: center; align-items: center; }
/* ② Grid(最简洁) */
.parent { display: grid; place-items: center; }
/* ③ absolute + transform(不需知道子元素尺寸) */
.parent { position: relative; }
.child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
/* ④ absolute + margin:auto(需子元素有固定宽高) */
.parent { position: relative; }
.child { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; width: 200px; height: 100px; }
/* ⑤ 文本居中 */
.text-center { text-align: center; }
/* ⑥ table-cell(不推荐,遗留方案) */
.parent { display: table-cell; vertical-align: middle; text-align: center; }
# 5. 经典布局方案
# 5.1 圣杯布局(头/尾 + 三列,中间自适应)
<div class="container">
<header>头部</header>
<main>内容(flex: 1 撑开)</main>
<footer>尾部</footer>
</div>
.container { display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; } /* 撑开中间 */
# 5.2 瀑布流(CSS 多列 / Grid)
/* 方案 A:CSS columns(简单) */
.masonry {
columns: 4 250px; /* 4 列,最小 250px */
column-gap: 16px;
}
.masonry .item { break-inside: avoid; margin-bottom: 16px; }
/* 方案 B:Grid + masonry(实验性) */
.masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-rows: masonry; /* 仅 Firefox 实验支持 */
}
# 5.3 等高列
/* Flexbox 天然等高 */
.row { display: flex; }
.col { flex: 1; } /* 高度自动等于最高列 */
/* Grid 天然等行高 */
.row { display: grid; grid-template-columns: repeat(3, 1fr); }
# 6. 移动端适配清单
/* ① viewport 声明 */
<meta name="viewport" content="width=device-width, initial-scale=1">
/* ② 图片自适应 */
img { max-width: 100%; height: auto; }
/* ③ 最小触摸区域 */
button, a { min-width: 44px; min-height: 44px; } /* Apple HIG 推荐 */
/* ④ 安全区域(iPhone X+) */
body { padding: env(safe-area-inset-top) env(safe-area-inset-right)
env(safe-area-inset-bottom) env(safe-area-inset-left); }
# 7. 速查表
| 需求 | 方案 |
|---|---|
| 不同屏幕隐藏/显示元素 | @media (max-width: 768px) { .sidebar { display: none; } } |
| 文字随屏幕缩放 | font-size: clamp(1rem, 3vw, 1.5rem) |
| 全屏首屏 | height: 100vh 或 min-height: 100dvh |
| 组件根据父容器响应 | @container |
| 水平垂直居中 | display: flex; justify-content: center; align-items: center |
| 暗色模式 | @media (prefers-color-scheme: dark) |
| 减少动画 | @media (prefers-reduced-motion) { * { animation: none; } } |
下一篇:07.CSS渲染与优化 — 重排/重绘诊断、containment、字体加载、关键 CSS。
上次更新: 2026/06/24, 10:13:05