CSS 响应式设计

响应式设计让同一个网页在不同屏幕尺寸(手机、平板、桌面)上都能良好显示。它的核心工具是 媒体查询(@media)

视口设置(Viewport)

响应式的第一步是在 HTML 中声明 viewport:

html
<meta name="viewport" content="width=device-width, initial-scale=1.0">

不写这行,移动端浏览器会以桌面版宽度渲染后缩小,导致文字小到无法阅读。

@media — 媒体查询

@media 让你根据设备特征(屏幕宽度、方向、分辨率等)选择性应用样式:

css
/* 基础样式(移动端) */
.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;
  }
}

媒体查询的两种写法

css
/* 1. 写在样式表中 */
@media (max-width: 767px) {
  .sidebar { display: none; }
}

/* 2. 在 link 标签中分离样式文件 */
html
<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 鼠标)
css
/* 深色模式 */
@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 媒体查询逐步增强:

css
/* 默认 = 移动端(窄屏) */
.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
/* 项目中可以定义 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)来管理断点变量(编译时替换为值)。

响应式实践技巧

响应式字体

css
/* clamp():一个字搞定响应式字号 */
h1 { font-size: clamp(1.5rem, 4vw, 3rem); }
p { font-size: clamp(1rem, 2.5vw, 1.125rem); }

响应式图片

html
<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>

隐藏/显示内容

css
/* 移动端隐藏侧栏 */
@media (max-width: 767px) {
  .sidebar { display: none; }
}

/* 仅移动端显示汉堡菜单 */
@media (min-width: 768px) {
  .mobile-menu { display: none; }
}

不需要媒体查询的响应式

一些现代 CSS 特性天生具有响应性:

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-fitflex-wrapmin()max() 等)。它们能基于容器尺寸自动适应,而不需要人工定义断点。