CSS 响应式设计与媒体查询——一套代码适配所有屏幕
前言
你的网页在电脑上看起来很棒,但用手机打开呢?文字可能小到看不清,三栏布局可能挤成一团。响应式设计(Responsive Design) 就是让同一套代码在手机、平板、桌面上都能良好展示的技术。
2026 年,全球超过 60% 的网页访问来自移动端。响应式不是可选项,而是必备能力。好消息是:上一篇学的 Flex 和 Grid 已经帮你解决了大部分响应式布局问题,本篇补上剩下的拼图:媒体查询和移动优先策略。
🎯 快捷调试:在 Chrome 中按
Ctrl + Shift + M(或打开 DevTools 后点左上角的设备图标),可以模拟不同设备的屏幕尺寸。本文所有示例都可以用这个功能测试。
正文
1. 视口(Viewport)
视口是浏览器中实际显示网页内容的区域。在手机上,如果不设置视口,浏览器会假装自己是一个 980px 宽的桌面浏览器,然后把页面缩小塞进屏幕——这就是为什么有些老网页在手机上字特别小。
<!-- 必须在 <head> 中添加这行 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
| 参数 | 含义 |
|---|---|
width=device-width | 视口宽度 = 设备实际宽度 |
initial-scale=1.0 | 初始缩放比例为 1(不缩放) |
这行代码是所有响应式页面的起点,没有它后面的媒体查询都不会正常工作。
2. 媒体查询(Media Queries)
媒体查询是 CSS 的条件语句——当屏幕满足某个条件时,应用对应的样式。
/* 基本语法 */
@media (条件) {
/* 当条件成立时应用的样式 */
}
/* 示例:屏幕宽度小于 768px 时(手机/平板) */
@media (max-width: 768px) {
.sidebar {
display: none; /* 隐藏侧边栏 */
}
.content {
width: 100%; /* 主内容占满宽度 */
}
}
/* 示例:屏幕宽度大于等于 1024px 时(桌面) */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}
C 语言类比:
@media (max-width: 768px) { ... }就像if (screen_width <= 768) { ... }。
常用断点(Breakpoints)
断点是触发布局变化的屏幕宽度阈值。业界常用断点:
| 名称 | 宽度范围 | 典型设备 |
|---|---|---|
| 手机竖屏 | < 640px | iPhone SE, 小屏手机 |
| 手机横屏/小平板 | 640px - 768px | 大屏手机, iPad Mini |
| 平板 | 768px - 1024px | iPad, 小笔记本 |
| 桌面 | 1024px - 1280px | 笔记本 |
| 大桌面 | ≥ 1280px | 台式机显示器 |
这些断点和 Tailwind CSS 的默认断点一致(
sm:640, md:768, lg:1024, xl:1280, 2xl:1536),提前熟悉有好处。
3. 移动优先(Mobile First)策略
有两种写媒体查询的思路:
桌面优先(Desktop First)——先写桌面样式,用 max-width 向下覆盖:
/* 默认桌面样式 */
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
/* 平板及以下 */
@media (max-width: 1024px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
/* 手机 */
@media (max-width: 640px) {
.grid { grid-template-columns: 1fr; }
}
移动优先(Mobile First)——先写手机样式,用 min-width 向上增强(推荐):
/* 默认手机样式(最简单的布局) */
.grid { display: grid; grid-template-columns: 1fr; }
/* 平板及以上 */
@media (min-width: 768px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
/* 桌面及以上 */
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
★ 为什么推荐移动优先?
这是本文的核心观点:
- 渐进增强:手机端加载最少的 CSS,性能更好。桌面端网络速度快、硬件强,多加载一些样式无所谓;但手机可能在 3G 网络下打开你的页面
- 思维更清晰:从最简单的单列布局出发,逐步添加复杂度。反过来从复杂往简单缩,往往会“缩不动”
- 与框架一致:Tailwind CSS、Bootstrap 等主流框架都采用移动优先,提前养成这个习惯会很顺畅
- 覆盖率高:大部分用户来自移动端,优先保证移动体验是商业常识
💡 工程师手记:我第一次用手机打开自己写的页面时,发现所有东西都挪在屏幕左上角——三栏布局还在,只是每一栏都窄得只剩几个字。那一刻我才理解为什么要移动优先——不是因为它“时髦”,而是因为从简单往复杂加真的比反过来容易太多了。
(建议替换为你自己第一次在手机上测试页面的真实经历)
4. 响应式布局常用技巧
4.1 弹性容器宽度
.container {
width: 100%; /* 小屏占满 */
max-width: 1200px; /* 大屏限制最大宽度 */
margin: 0 auto; /* 水平居中 */
padding: 0 16px; /* 左右留白,防止内容贴边 */
}
4.2 响应式字号
/* 方法一:媒体查询调整根字号 */
html { font-size: 14px; }
@media (min-width: 768px) {
html { font-size: 15px; }
}
@media (min-width: 1024px) {
html { font-size: 16px; }
}
/* 方法二:clamp() 函数(现代方案,自动在范围内平滑缩放) */
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
/* 最小 1.5rem,理想值 4vw(视口宽度的 4%),最大 3rem */
/* 不需要媒体查询,字号会随屏幕宽度自动、平滑地变化 */
}
/* clamp() 不只能用于字号,间距、宽度都可以 */
.container {
padding: clamp(16px, 3vw, 48px);
}
4.3 响应式图片
<!-- 基本:图片不超过容器宽度 -->
<img src="photo.jpg" alt="照片" style="max-width: 100%; height: auto;">
/* 全局设置所有图片为响应式 */
img {
max-width: 100%;
height: auto;
display: block;
}
<!-- 高级:根据屏幕加载不同尺寸的图片(节省流量) -->
<img
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
src="photo-800.jpg"
alt="响应式图片"
>
4.4 隐藏/显示元素
/* 手机上隐藏侧边栏 */
.sidebar { display: none; }
@media (min-width: 1024px) {
.sidebar { display: block; }
}
/* 手机上显示汉堡菜单按钮,桌面上隐藏 */
.menu-toggle { display: block; }
@media (min-width: 1024px) {
.menu-toggle { display: none; }
}
5. 完整实战:响应式页面布局
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>响应式布局示例</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: system-ui, sans-serif; line-height: 1.6; }
/* 导航栏 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: #1a1a2e;
color: white;
}
.nav-links { display: none; }
.menu-btn { background: none; border: none; color: white; font-size: 24px; cursor: pointer; }
/* 主内容区域 */
.main { padding: 16px; }
/* 卡片网格 */
.card-grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
.card {
padding: 24px;
background: #f8f9fa;
border-radius: 8px;
border: 1px solid #e9ecef;
}
/* 平板断点 */
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
.main { padding: 24px; }
}
/* 桌面断点 */
@media (min-width: 1024px) {
.nav-links { display: flex; gap: 24px; list-style: none; }
.nav-links a { color: white; text-decoration: none; }
.menu-btn { display: none; }
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
.main {
max-width: 1200px;
margin: 0 auto;
padding: 32px 24px;
}
}
</style>
</head>
<body>
<nav class="navbar">
<div class="logo">MyBlog</div>
<button class="menu-btn">☰</button>
<ul class="nav-links">
<li><a href="#">首页</a></li>
<li><a href="#">博客</a></li>
<li><a href="#">关于</a></li>
</ul>
</nav>
<div class="main">
<h1>最新文章</h1>
<div class="card-grid">
<div class="card">
<h3>Web 是怎么工作的</h3>
<p>从浏览器到服务器,理解 HTTP 的基本模型...</p>
</div>
<div class="card">
<h3>HTML 语义化</h3>
<p>用对标签,让页面结构清晰、可访问...</p>
</div>
<div class="card">
<h3>CSS 盒模型</h3>
<p>每个元素都是一个盒子:content + padding + border + margin...</p>
</div>
</div>
</div>
</body>
</html>
🎯 动手验证:把这段代码保存为
responsive.html,用浏览器打开,然后缩放窗口宽度(或按Ctrl+Shift+M切换设备模拟)。你会看到:手机端单列+汉堡菜单 → 平板两列 → 桌面三列+导航链接。这就是移动优先 + 媒体查询的完整效果。
6. 媒体查询进阶
/* 组合条件 */
@media (min-width: 768px) and (max-width: 1023px) {
/* 仅在平板尺寸生效 */
}
/* 横屏/竖屏 */
@media (orientation: landscape) { /* 横屏 */ }
@media (orientation: portrait) { /* 竖屏 */ }
/* 暗色模式偏好(用户系统级设置) */
@media (prefers-color-scheme: dark) {
body { background: #1a1a1a; color: #e0e0e0; }
}
/* 减少动画偏好(用户系统级设置,无障碍) */
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}
/* 打印样式 */
@media print {
.navbar, .sidebar { display: none; }
body { font-size: 12pt; }
}
总结
| 知识点 | 核心要点 |
|---|---|
| viewport meta | 必须添加 width=device-width, initial-scale=1.0 |
| 媒体查询 | @media (min-width: Xpx) { } 是移动优先的写法 |
| 移动优先 | 默认写手机样式,用 min-width 向上增强 |
| 常用断点 | 640 / 768 / 1024 / 1280 / 1536(与 Tailwind 一致) |
| 弹性宽度 | width: 100%; max-width: 1200px; margin: 0 auto; |
| 响应式图片 | max-width: 100%; height: auto; |
| clamp() | clamp(最小, 理想, 最大) 实现平滑缩放 |
常见问题
💬 你可能会问:断点怎么选?一定要用这些数值吗?
断点不是死规定,但 640/768/1024/1280 是业界广泛采用的标准(Tailwind CSS 默认值)。建议直接用这套,除非你的设计稿明确指定了其他断点。
💬 你可能会问:clamp() 和媒体查询什么时候用哪个?
简单规则:需要“平滑过渡”的属性(字号、间距)用
clamp(),需要“跳变”的布局(单列→双列、显示→隐藏)用媒体查询。两者配合使用效果最好。
💬 你可能会问:测试响应式效果一定要用真手机吗?
日常开发用 Chrome DevTools 的设备模拟就够了(
Ctrl+Shift+M)。但上线前建议用真实设备测一遍,因为触屏交互、软键盘弹出等行为无法完全模拟。
参考资料
📖 系列导航:本文是「FPGA 工程师的前端学习笔记」系列的第 5 篇 上一篇:CSS 布局体系:Flexbox 与 Grid 下一篇:[JavaScript 入门:从 C 到 JS 的思维转换](./0106-JavaScript入门:从 C到JS的思维转换.md)