CSS 响应式设计
响应式设计让同一个网页在不同屏幕尺寸(手机、平板、桌面)上都能良好显示。它的核心工具是 媒体查询(@media)。
视口设置(Viewport)
响应式的第一步是在 HTML 中声明 viewport:
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 不写这行,移动端浏览器会以桌面版宽度渲染后缩小,导致文字小到无法阅读。
@media — 媒体查询
@media 让你根据设备特征(屏幕宽度、方向、分辨率等)选择性应用样式:
/* 基础样式(移动端) */
.container {
padding: 1rem;
}
/* 屏幕宽度 >= 768px 时 */
@media (min-width: 768px) {
.container {
padding: 2rem;
display: flex;
gap: 2rem;
}
}
/* 屏幕宽度 >= 1024px 时 */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
} 媒体查询的两种写法
/* 1. 写在样式表中 */
@media (max-width: 767px) {
.sidebar { display: none; }
}
/* 2. 在 link 标签中分离样式文件 */ <link rel="stylesheet" href="mobile.css" media="(max-width: 767px)"> 第一种是最常用的方式——所有样式写在一起,用 @media 分组。
常用媒体特性
| 特性 | 示例 | 说明 |
|---|---|---|
width / min-width / max-width | (min-width: 768px) | 视口宽度(最常用) |
height | (max-height: 600px) | 视口高度 |
orientation | (orientation: landscape) | 横屏/竖屏 |
prefers-color-scheme | (prefers-color-scheme: dark) | 系统深色/浅色模式 |
prefers-reduced-motion | (prefers-reduced-motion: reduce) | 减弱动画偏好 |
hover | (hover: hover) | 设备是否支持悬停 |
pointer | (pointer: coarse) | 输入设备精度(触摸 vs 鼠标) |
/* 深色模式 */
@media (prefers-color-scheme: dark) {
body {
background: #0f172a;
color: #e2e8f0;
}
}
/* 减弱动画 */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
} prefers-reduced-motion 是对无障碍设计的重要支持。部分用户因前庭功能障碍对动画敏感,在系统设置中开启了”减弱动态效果”。响应这个媒体特性的网站会赢得这部分用户的信任。
移动优先(Mobile First)
移动优先策略是先写移动端的样式(作为默认),再用 min-width 媒体查询逐步增强:
/* 默认 = 移动端(窄屏) */
.card {
width: 100%;
padding: 1rem;
}
/* 平板(>=768px) */
@media (min-width: 768px) {
.card {
width: calc(50% - 0.75rem);
}
}
/* 桌面(>=1024px) */
@media (min-width: 1024px) {
.card {
width: calc(33.333% - 1rem);
}
} 移动优先是社区推荐的做法——移动端样式更简单(通常单列),作为基准,桌面增强只添加额外的列和间距。反过来(桌面优先 + max-width)会让你的代码以复杂布局为起点,不断”减去”样式,更容易出错。
常见断点
没有”标准”断点——断点应该根据你的内容来设置,而不是根据特定设备。以下是一个常用的参考范围:
| 断点 | 范围 | 典型设备 |
|---|---|---|
0-639px | 小屏幕 | 手机竖屏 |
640-767px | 中屏幕 | 手机横屏 |
768-1023px | 平板 | 平板竖屏 |
1024-1279px | 小桌面 | 平板横屏、笔记本 |
1280px+ | 大桌面 | 外接显示器 |
/* 项目中可以定义 CSS 变量集中管理断点值,方便在源码中统一引用和修改 */
:root {
--bp-sm: 640px;
--bp-md: 768px;
--bp-lg: 1024px;
--bp-xl: 1280px;
} CSS 变量不能用在 @media 的条件中——@media (min-width: var(--bp-md)) 是无效的,这些变量仅用于在 CSS 源码中统一记录和引用断点值。断点值在 @media 中只能直接写数字。可以用预处理器(Sass/Less)来管理断点变量(编译时替换为值)。
响应式实践技巧
响应式字体
/* clamp():一个字搞定响应式字号 */
h1 { font-size: clamp(1.5rem, 4vw, 3rem); }
p { font-size: clamp(1rem, 2.5vw, 1.125rem); } 响应式图片
<picture>
<source srcset="photo-mobile.webp" media="(max-width: 767px)">
<source srcset="photo-desktop.webp" media="(min-width: 768px)">
<img src="photo.jpg" alt="描述文字">
</picture> 隐藏/显示内容
/* 移动端隐藏侧栏 */
@media (max-width: 767px) {
.sidebar { display: none; }
}
/* 仅移动端显示汉堡菜单 */
@media (min-width: 768px) {
.mobile-menu { display: none; }
} 不需要媒体查询的响应式
一些现代 CSS 特性天生具有响应性:
/* Grid auto-fit(见 Grid 章节) */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
/* Flexbox wrap */
.tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
/* min() 函数 */
.container {
width: min(100% - 2rem, 1200px);
margin-left: auto;
margin-right: auto; /* 水平居中,等价于逻辑属性 margin-inline: auto */
} 响应式设计的未来趋势是减少对 @media 的依赖,更多使用内在响应式的 CSS 特性(clamp()、auto-fit、flex-wrap、min()、max() 等)。它们能基于容器尺寸自动适应,而不需要人工定义断点。