响应式布局
本教程共 44 篇 · 第 41 篇 · 更新于 2026-07-29 · 约 14 分钟阅读
41. 响应式布局
本节目标:掌握响应式网格系统的搭建方法,理解移动优先的设计思路,能够设置合理的断点实现多设备适配。
上一章学了媒体查询的基础语法。这一章把理论落地,看看实际布局中怎么用好它们。
响应式网格系统
很多网站都基于网格来设计。把页面分成 12 列是最常见的做法,因为 12 能被 2、3、4、6 整除,组合灵活。
先设置全局盒模型,让 padding 和 border 算在宽度内:
* {
box-sizing: border-box;
}
然后定义每一列的宽度。100% 除以 12 列,每列约 8.33%:
.col-1 { width: 8.33%; }
.col-2 { width: 16.66%; }
.col-3 { width: 25%; }
.col-4 { width: 33.33%; }
.col-5 { width: 41.66%; }
.col-6 { width: 50%; }
.col-7 { width: 58.33%; }
.col-8 { width: 66.66%; }
.col-9 { width: 75%; }
.col-10 { width: 83.33%; }
.col-11 { width: 91.66%; }
.col-12 { width: 100%; }
所有列向左浮动,加上内边距:
[class*="col-"] {
float: left;
padding: 15px;
}
12 列网格是经典方案,Bootstrap 等框架也采用类似思路。实际列数可根据需求调整,16 列、24 列也很常见。
行与列的组合
每行用 <div class="row"> 包裹。一行内的列宽加起来要等于 12:
<div class="row">
<div class="col-3">侧边栏</div>
<div class="col-9">主内容</div>
</div>
行用 ::after 伪元素清除浮动,防止高度塌陷:
.row::after {
content: "";
clear: both;
display: table;
}
<!DOCTYPE html>
<html lang="zh">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* { box-sizing: border-box; }
[class*="col-"] {
float: left;
padding: 15px;
border: 1px solid #ddd;
}
.row::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="row">
<div class="col-3">25% 宽度</div>
<div class="col-9">75% 宽度</div>
</div>
<div class="row">
<div class="col-4">33.33%</div>
<div class="col-4">33.33%</div>
<div class="col-4">33.33%</div>
</div>
</body>
</html>
移动优先设计
移动优先(Mobile First)的意思是:先写手机上的样式,再用 min-width 逐步增强到大屏。
这样做有两个好处:移动端代码更简洁,搜索引擎也更看重移动端的体验。
/* 默认:手机样式,单列全宽 */
[class*="col-"] {
width: 100%;
}
/* 平板及以上:768px */
@media only screen and (min-width: 768px) {
.col-1 { width: 8.33%; }
.col-2 { width: 16.66%; }
.col-3 { width: 25%; }
.col-4 { width: 33.33%; }
.col-5 { width: 41.66%; }
.col-6 { width: 50%; }
.col-7 { width: 58.33%; }
.col-8 { width: 66.66%; }
.col-9 { width: 75%; }
.col-10 { width: 83.33%; }
.col-11 { width: 91.66%; }
.col-12 { width: 100%; }
}
移动优先用
,桌面优先用
max-width。现代开发推荐移动优先,代码更少、逻辑更清晰。
多断点适配
实际项目中,通常需要适配手机、平板、桌面三种设备。可以添加多个断点:
/* 手机:默认全宽 */
[class*="col-"] {
width: 100%;
}
/* 平板:600px 及以上 */
@media only screen and (min-width: 600px) {
.col-m-1 { width: 8.33%; }
.col-m-2 { width: 16.66%; }
.col-m-3 { width: 25%; }
.col-m-4 { width: 33.33%; }
.col-m-5 { width: 41.66%; }
.col-m-6 { width: 50%; }
.col-m-7 { width: 58.33%; }
.col-m-8 { width: 66.66%; }
.col-m-9 { width: 75%; }
.col-m-10 { width: 83.33%; }
.col-m-11 { width: 91.66%; }
.col-m-12 { width: 100%; }
}
/* 桌面:992px 及以上 */
@media only screen and (min-width: 992px) {
.col-1 { width: 8.33%; }
.col-2 { width: 16.66%; }
.col-3 { width: 25%; }
.col-4 { width: 33.33%; }
.col-5 { width: 41.66%; }
.col-6 { width: 50%; }
.col-7 { width: 58.33%; }
.col-8 { width: 66.66%; }
.col-9 { width: 75%; }
.col-10 { width: 83.33%; }
.col-11 { width: 91.66%; }
.col-12 { width: 100%; }
}
HTML 中同时引用两个类,让不同断点有不同的列宽:
<div class="row">
<div class="col-3 col-m-3">侧边栏</div>
<div class="col-6 col-m-9">主内容</div>
<div class="col-3 col-m-12">底部栏</div>
</div>
效果:桌面上三列并排,平板上侧边栏和主内容在一行、底部栏全宽,手机上全部堆叠。
常用断点参考
设备千差万别,没必要为每个尺寸写断点。常用的五组断点:
/* 超小设备(手机竖屏) */
@media only screen and (max-width: 575px) { ... }
/* 小设备(手机横屏) */
@media only screen and (min-width: 576px) { ... }
/* 中等设备(平板) */
@media only screen and (min-width: 768px) { ... }
/* 大设备(笔记本) */
@media only screen and (min-width: 992px) { ... }
/* 超大设备(台式机) */
@media only screen and (min-width: 1200px) { ... }
断点不是固定的,根据实际内容调整。原则是:让内容在每种屏幕上都舒适阅读,而不是死记硬背某个数值。
响应式图片
图片是响应式布局中最容易出问题的地方。一张固定宽度的大图,在小屏幕上会溢出容器。
最简单的处理方式:
img {
max-width: 100%;
height: auto;
}
max-width: 100% 让图片最大不超过容器宽度,height: auto 保持宽高比。图片可以缩小,但不会放大超过原始尺寸。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
img {
max-width: 100%;
height: auto;
}
.banner {
width: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div class="banner">
<img src="https://via.placeholder.com/1200x400" alt="Banner">
</div>
<p>调整窗口大小,图片会自动缩放</p>
</body>
</html>
背景图片的响应式处理
背景图片用 background-size 控制缩放行为:
/* 保持比例,完整显示 */
.bg-contain {
background-size: contain;
background-repeat: no-repeat;
}
/* 保持比例,覆盖整个区域(可能裁剪) */
.bg-cover {
background-size: cover;
}
/* 拉伸填满(可能变形) */
.bg-stretch {
background-size: 100% 100%;
}
| 值 | 效果 |
|---|---|
contain | 图片完整显示,可能留白 |
cover | 覆盖整个区域,可能裁剪 |
100% 100% | 拉伸填满,可能变形 |
<!DOCTYPE html>
<html lang="zh">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.box {
width: 100%;
height: 300px;
border: 2px solid #333;
margin-bottom: 20px;
background-image: url('https://via.placeholder.com/800x400');
background-repeat: no-repeat;
}
.contain { background-size: contain; }
.cover { background-size: cover; }
.stretch { background-size: 100% 100%; }
</style>
</head>
<body>
<div class="box contain">contain</div>
<div class="box cover">cover</div>
<div class="box stretch">100% 100%</div>
</body>
</html>
不同设备加载不同图片
大图在小屏幕上既浪费流量又加载慢。用媒体查询可以针对不同屏幕加载不同尺寸的图片:
/* 小屏幕:加载小图 */
.hero {
background-image: url('small.jpg');
}
/* 大屏幕:加载大图 */
@media only screen and (min-width: 768px) {
.hero {
background-image: url('large.jpg');
}
}
HTML5 的 <picture> 元素更灵活,浏览器会自动选择最合适的图片:
<picture>
<source srcset="small.jpg" media="(max-width: 600px)">
<source srcset="medium.jpg" media="(max-width: 900px)">
<img src="large.jpg" alt="响应式图片">
</picture>
Tip元素中,
<img>标签不能省略。它是兜底方案:不支持<picture>的浏览器会直接显示<img>的图片。
响应式实用技巧
隐藏元素
小屏幕上隐藏次要内容,让页面更聚焦:
/* 手机上隐藏侧边栏 */
@media (max-width: 768px) {
.sidebar {
display: none;
}
}
调整字体大小
不同屏幕使用不同的基础字号:
/* 手机 */
body { font-size: 14px; }
/* 平板 */
@media (min-width: 768px) {
body { font-size: 16px; }
}
/* 桌面 */
@media (min-width: 1024px) {
body { font-size: 18px; }
}
横屏/竖屏适配
/* 横屏时 */
@media (orientation: landscape) {
.hero { flex-direction: row; }
}
/* 竖屏时 */
@media (orientation: portrait) {
.hero { flex-direction: column; }
}
响应式布局速查
| 技术 | 作用 |
|---|---|
| 12 列网格 | 灵活的列布局系统 |
| 移动优先 | 先写手机样式,再增强到大屏 |
min-width 断点 | 从小到大逐步增强 |
max-width: 100% | 图片自适应容器 |
background-size: cover | 背景图覆盖区域 |
<picture> | 不同屏幕加载不同图片 |
display: none | 小屏隐藏元素 |
现代 CSS 的 Flexbox 和 Grid 本身就具有响应式能力。配合
、
minmax()等特性,很多时候不需要写媒体查询就能实现自适应。