📖 核心概念
- Viewport与设备像素比
- 媒体查询策略:移动优先 vs 桌面优先
- 流式布局与弹性单位
- 容器查询(CSS Container Queries)
- 响应式图片与媒体
- 触摸与交互适配
💻 代码实现
响应式布局系统
✅ css
/* 移动优先的响应式框架 */
:root {
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
--font-sm: 0.875rem;
--font-base: 1rem;
--font-lg: 1.25rem;
}
/* 基础移动端样式 */
.container {
width: 100%;
padding: var(--spacing-md);
margin: 0 auto;
}
.grid {
display: grid;
gap: var(--spacing-md);
grid-template-columns: 1fr;
}
/* 平板 (768px+) */
@media (min-width: 768px) {
:root {
--spacing-md: 1.5rem;
--spacing-lg: 3rem;
}
.container { max-width: 720px; }
.grid { grid-template-columns: repeat(2, 1fr); }
}
/* 桌面 (1024px+) */
@media (min-width: 1024px) {
.container { max-width: 1200px; }
.grid { grid-template-columns: repeat(3, 1fr); }
}
/* 大屏 (1440px+) */
@media (min-width: 1440px) {
.grid { grid-template-columns: repeat(4, 1fr); }
}
/* 容器查询 - 组件级响应式 */
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card { flex-direction: row; }
.card-image { width: 200px; }
}
响应式图片与导航
✅ html
<!-- 响应式图片 -->
<picture>
<source media="(min-width: 1024px)" srcset="hero-desktop.webp">
<source media="(min-width: 768px)" srcset="hero-tablet.webp">
<img src="hero-mobile.webp" alt="Hero image"
loading="lazy" decoding="async"
width="800" height="600">
</picture>
<!-- 响应式图片尺寸 -->
<img src="photo.jpg"
srcset="photo-320.jpg 320w,
photo-640.jpg 640w,
photo-1280.jpg 1280w"
sizes="(max-width: 640px) 100vw,
(max-width: 1024px) 50vw,
33vw"
alt="Responsive photo">
<!-- 移动端汉堡导航 -->
<nav class="nav-responsive">
<a href="/" class="nav-logo">Logo</a>
<button class="nav-toggle" aria-label="打开菜单" aria-expanded="false">
<span></span><span></span><span></span>
</button>
<ul class="nav-menu">
<li><a href="/about">关于</a></li>
<li><a href="/services">服务</a></li>
<li><a href="/contact">联系</a></li>
</ul>
</nav>
<style>
.nav-menu {
display: none;
position: absolute;
top: 100%; left: 0; right: 0;
background: #1e293b;
flex-direction: column;
padding: 1rem;
}
.nav-toggle.active + .nav-menu { display: flex; }
@media (min-width: 768px) {
.nav-toggle { display: none; }
.nav-menu { display: flex; position: static; flex-direction: row; }
}
</style>
🔍 响应式设计进阶
流式排版与clamp()
使用CSS clamp()函数可以实现无需媒体查询的流式排版,字体大小根据视口宽度平滑变化:
流式排版
✅ css
/* 流式字体:最小16px,最大32px,随视口缩放 */
h1 {
font-size: clamp(1.5rem, 1rem + 3vw, 2.5rem);
}
/* 流式间距 */
.section {
padding: clamp(1rem, 3vw, 3rem);
}
/* 流式网格列数 */
.grid {
grid-template-columns: repeat(
auto-fill,
minmax(clamp(200px, 30vw, 350px), 1fr)
);
}
逻辑属性(Logical Properties)
使用逻辑属性替代物理方向,为RTL语言和不同书写模式做好准备:
逻辑属性
✅ css
/* 物理属性 → 逻辑属性 */
margin-left → margin-inline-start
margin-right → margin-inline-end
margin-top → margin-block-start
padding-left → padding-inline-start
border-left → border-inline-start
width → inline-size
height → block-size
/* 实际使用 */
.card {
padding-inline-start: 1rem; /* LTR: 左, RTL: 右 */
margin-block-end: 1.5rem; /* 始终是底部 */
inline-size: 100%; /* 替代width */
}
容器查询最佳实践
容器查询让组件真正实现了自适应,不再依赖视口宽度:
- 为容器设置
container-type: inline-size而非container-type: size,避免不必要的布局计算 - 使用
container-name命名容器,避免冲突 - 组件应该从最小尺寸开始设计,通过容器查询向上扩展
🎯 练习任务
- 1 实现一个移动优先的响应式导航,包含汉堡菜单
- 2 创建一个响应式图片画廊,使用picture和srcset
- 3 使用容器查询实现一个组件在不同容器宽度下的自适应布局
- 4 测试你的响应式页面在多种设备上的表现
🏆 成就解锁
适配达人 — 掌握响应式设计核心技巧,让你的页面在任何设备上都很完美