📚 现代前端开发 目录
阶段1:Web基础
第 4 / 35 课

响应式设计

一套代码,多端适配

📖 核心概念

💻 代码实现

响应式布局系统 ✅ 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 */
}

容器查询最佳实践

容器查询让组件真正实现了自适应,不再依赖视口宽度:

🎯 练习任务

🏆 成就解锁
适配达人 — 掌握响应式设计核心技巧,让你的页面在任何设备上都很完美