响应式之智——一页适配万物

目录

第 1 节 概述

同一个页面在手机上竖着看,在桌面上横着看——布局必须跟着变。

Tailwind 采用 mobile-first(移动优先) 的策略:先写手机上的样式,再用断点覆盖更大屏幕的布局。

这意味着不加前缀的样式默认在所有屏幕上都生效。加上 md:lg: 前缀后,只在达到相应宽度的屏幕上生效。

第 2 节 断点系统

2.1 默认断点

前缀最小宽度适用
sm640px大屏手机横屏、小平板
md768px平板
lg1024px小桌面、笔记本
xl1280px桌面显示器
2xl1536px大屏幕

images/08-breakpoints.svg

2.2 使用方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<!-- 手机:上下排列;桌面:左右排列 -->
<div class="flex flex-col md:flex-row">
  <div class="w-full md:w-1/3">侧边栏</div>
  <div class="w-full md:w-2/3">主内容</div>
</div>

<!-- 手机:1 列;平板:2 列;桌面:3 列 -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
  <div>卡片 1</div>
  <div>卡片 2</div>
  <div>卡片 3</div>
</div>

<!-- 手机:小字号居中;桌面:大字号 -->
<h1 class="text-2xl text-center md:text-4xl md:text-left">
  适配不同屏幕的标题
</h1>

2.3 工作原理

sm: 等价于 @media (width >= 40rem)md: 等价于 @media (width >= 48rem),以此类推。

不加前缀的样式,对所有屏幕生效。加了前缀的样式,只在该宽度及以上生效。

1
2
<!-- 默认是 flex-col,md 以上才是 flex-row -->
<div class="flex flex-col md:flex-row"></div>

2.4 最大宽度变体

v4 自动生成了对应的 max-* 变体,表示"小于某个断点":

1
2
3
4
5
6
7
<!-- 只在小于 md(768px)的屏幕上隐藏 -->
<div class="max-md:hidden">手机上隐藏</div>

<!-- 只在 md 到 lg 之间的屏幕上显示 -->
<div class="max-lg:max-md:block">
  平板专属内容
</div>

第 3 节 常见响应式模式

3.1 1. 响应式网格

最常用的模式——卡片数量随屏幕变化:

1
2
3
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
  <!-- 手机 1 列 → 平板 2 列 → 小桌面 3 列 → 大桌面 4 列 -->
</div>

3.2 2. 导航栏折叠

手机上导航链接折叠成汉堡菜单,桌面上展开:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<nav class="flex items-center justify-between px-6 h-16">
  <span class="text-xl font-bold">Logo</span>

  <!-- 桌面端显示的导航链接 -->
  <div class="hidden md:flex gap-8">
    <a href="#">首页</a>
    <a href="#">产品</a>
    <a href="#">关于</a>
  </div>

  <!-- 手机端汉堡按钮 -->
  <button class="md:hidden p-2">
    <svg><!-- 汉堡图标 --></svg>
  </button>
</nav>

hidden md:flex 的意思是:默认隐藏(手机不显示),md 以上用 flex 显示。

3.3 3. 侧边栏布局

手机上侧边栏隐藏或堆叠在上面,桌面端在左侧:

1
2
3
4
5
6
7
8
<div class="flex flex-col md:flex-row">
  <aside class="w-full md:w-64 md:min-h-screen bg-gray-50 p-4">
    侧边栏
  </aside>
  <main class="flex-1 p-6">
    主内容
  </main>
</div>

3.4 4. 响应式字号

手机上用小一点的标题,桌面上用大的:

1
2
3
4
5
6
7
<h1 class="text-2xl md:text-4xl lg:text-5xl font-bold">
  自适应标题
</h1>

<p class="text-sm md:text-base lg:text-lg">
  正文大小也根据屏幕变化
</p>

第 4 节 Container 布局

Tailwind 的 .container 类会根据屏幕宽度自动设置 max-width

1
2
3
<div class="container mx-auto px-6">
  内容最大宽度不超过 2xl 断点(1536px),并居中
</div>
技巧

使用 container mx-auto px-6 作为页面内容包装器。mx-auto 居中,px-6 在手机上提供边距。

第 5 节 容器查询(Container Queries)

v4 新特性。容器查询响应式断点不同:断点基于视口宽度,容器查询基于父容器的宽度。

这个功能非常实用——同一个组件放在侧边栏和主内容区时,可以自适应。

标记容器:

1
2
3
<div class="@container">
  <!-- 这个容器内的子元素可以用 @ 前缀查询容器宽度 -->
</div>

容器内的子元素:

1
2
3
4
5
<div class="@container p-4">
  <div class="flex flex-col @md:flex-row">
    <!-- 容器宽度 >= 48rem 时横向排列,否则纵向 -->
  </div>
</div>

容器查询的断点以 @ 开头:@sm@md@lg@xl@2xl

常用场景:卡片组件。不管卡片放在哪里(侧边栏还是主区域),只要容器够宽就自动切换横排/竖排布局。

第 6 节 实战:让产品页全面响应

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>星光科技 · 智能灯</title>
  <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
</head>
<body>
  <nav class="fixed top-0 inset-x-0 bg-white/70 backdrop-blur-md border-b border-gray-100/50 z-50">
    <div class="max-w-5xl mx-auto flex items-center justify-between px-4 sm:px-6 h-16">
      <span class="text-lg sm:text-xl font-bold text-gray-900">星光科技</span>
      <!-- 桌面导航链接,手机上隐藏 -->
      <div class="hidden md:flex gap-6 lg:gap-8 text-gray-600">
        <a href="#" class="hover:text-gray-900 transition-colors">产品</a>
        <a href="#" class="hover:text-gray-900 transition-colors">特性</a>
        <a href="#" class="hover:text-gray-900 transition-colors">用户评价</a>
        <a href="#" class="hover:text-gray-900 transition-colors">联系我们</a>
      </div>
      <!-- 手机汉堡按钮 -->
      <button class="md:hidden p-2 text-gray-600">
        <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
        </svg>
      </button>
    </div>
  </nav>

  <main class="max-w-5xl mx-auto px-4 sm:px-6 pt-28 sm:pt-32 pb-16">
    <!-- Hero -->
    <div class="bg-gradient-to-br from-blue-50 via-white to-purple-50 rounded-2xl sm:rounded-3xl p-8 sm:p-16 text-center">
      <h1 class="text-3xl sm:text-4xl lg:text-5xl font-extrabold text-gray-900 tracking-tight">
        智能台灯 <span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600">Lumina</span>
      </h1>
      <p class="mt-4 sm:mt-6 text-base sm:text-lg lg:text-xl text-gray-500 leading-relaxed max-w-2xl mx-auto">
        光线随你而变。一盏懂你的台灯。
      </p>
      <button class="mt-6 sm:mt-8 px-6 sm:px-8 py-3 sm:py-4 bg-gradient-to-r from-blue-600 to-purple-600 text-white text-base sm:text-lg font-semibold rounded-xl shadow-lg shadow-blue-600/30
                     transform transition-all duration-200 ease-out
                     hover:-translate-y-1 hover:shadow-xl hover:shadow-blue-600/40
                     active:scale-95">
        立即购买
      </button>
    </div>

    <!-- 特性卡片 —— 响应式网格 -->
    <section class="mt-20 sm:mt-32">
      <h2 class="text-2xl sm:text-3xl font-bold text-gray-900 text-center">为什么选择 Lumina</h2>
      <div class="mt-8 sm:mt-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8">
        <div class="group p-5 sm:p-6 bg-white/80 backdrop-blur-sm rounded-2xl border border-gray-100 shadow-md
                        transition-all duration-200 hover:shadow-xl hover:-translate-y-1">
          <div class="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-blue-100 to-blue-50 rounded-xl flex items-center justify-center
                      transition-transform duration-200 group-hover:scale-110">
            <span class="text-xl sm:text-2xl">🧠</span>
          </div>
          <h3 class="mt-3 sm:mt-4 text-lg sm:text-xl font-semibold text-gray-900">AI 调光</h3>
          <p class="mt-2 text-sm sm:text-base text-gray-500 leading-relaxed">内置传感器实时感知环境光线,自动调整亮度和色温。</p>
        </div>

        <div class="group p-5 sm:p-6 bg-white/80 backdrop-blur-sm rounded-2xl border border-gray-100 shadow-md
                        transition-all duration-200 hover:shadow-xl hover:-translate-y-1">
          <div class="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-green-100 to-green-50 rounded-xl flex items-center justify-center
                      transition-transform duration-200 group-hover:scale-110">
            <span class="text-xl sm:text-2xl">👁️</span>
          </div>
          <h3 class="mt-3 sm:mt-4 text-lg sm:text-xl font-semibold text-gray-900">护眼模式</h3>
          <p class="mt-2 text-sm sm:text-base text-gray-500 leading-relaxed">无频闪、低蓝光,通过德国莱茵 TÜV 护眼认证。</p>
        </div>

        <div class="group p-5 sm:p-6 bg-white/80 backdrop-blur-sm rounded-2xl border border-gray-100 shadow-md
                        transition-all duration-200 hover:shadow-xl hover:-translate-y-1
                        sm:col-span-2 lg:col-span-1">
          <div class="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-purple-100 to-purple-50 rounded-xl flex items-center justify-center
                      transition-transform duration-200 group-hover:scale-110">
            <span class="text-xl sm:text-2xl">🎤</span>
          </div>
          <h3 class="mt-3 sm:mt-4 text-lg sm:text-xl font-semibold text-gray-900">语音控制</h3>
          <p class="mt-2 text-sm sm:text-base text-gray-500 leading-relaxed">支持 Siri、小爱同学、Google Assistant 语音指令。</p>
        </div>
      </div>
    </section>

    <!-- 用户评价 -->
    <section class="mt-20 sm:mt-32">
      <h2 class="text-2xl sm:text-3xl font-bold text-gray-900 text-center">用户评价</h2>
      <div class="mt-8 sm:mt-12 divide-y divide-gray-100">
        <div class="py-4 sm:py-6 flex gap-3 sm:gap-4">
          <img class="w-10 h-10 sm:w-12 sm:h-12 rounded-full grayscale hover:grayscale-0 transition-all duration-300" src="https://i.pravatar.cc/48?img=1" alt="用户" />
          <div>
            <p class="font-semibold text-gray-900">设计师小王</p>
            <p class="mt-1 text-sm sm:text-base text-gray-500">"用了两周,眼睛舒服多了。AI 调光真的很智能。"</p>
          </div>
        </div>
        <div class="py-4 sm:py-6 flex gap-3 sm:gap-4">
          <img class="w-10 h-10 sm:w-12 sm:h-12 rounded-full grayscale hover:grayscale-0 transition-all duration-300" src="https://i.pravatar.cc/48?img=2" alt="用户" />
          <div>
            <p class="font-semibold text-gray-900">程序员大刘</p>
            <p class="mt-1 text-sm sm:text-base text-gray-500">"晚上写代码的时候,灯光会自动变暖,不刺眼。"</p>
          </div>
        </div>
        <div class="py-4 sm:py-6 flex gap-3 sm:gap-4">
          <img class="w-10 h-10 sm:w-12 sm:h-12 rounded-full grayscale hover:grayscale-0 transition-all duration-300" src="https://i.pravatar.cc/48?img=3" alt="用户" />
          <div>
            <p class="font-semibold text-gray-900">学生小林</p>
            <p class="mt-1 text-sm sm:text-base text-gray-500">"期末复习全靠它了,灯光可以跟着时间变化。"</p>
          </div>
        </div>
      </div>
    </section>

    <footer class="mt-20 sm:mt-32 pt-8 border-t border-gray-100 flex flex-col sm:flex-row items-center justify-between gap-4 text-sm text-gray-400">
      <span>&copy; 2026 星光科技</span>
      <div class="flex gap-6">
        <a href="#" class="hover:text-gray-600 transition-colors">隐私政策</a>
        <a href="#" class="hover:text-gray-600 transition-colors">服务条款</a>
      </div>
    </footer>
  </main>
</body>
</html>

这一版的响应式处理清单:

元素手机平板桌面
导航链接隐藏显示显示
汉堡按钮显示隐藏隐藏
卡片网格1 列2 列3 列
Hero 标题text-3xltext-4xltext-5xl
按钮内边距px-6 py-3px-8 py-4px-8 py-4
圆角rounded-2xlrounded-3xlrounded-3xl
页脚方向纵向堆叠横向排列横向排列
截图内部间距p-8p-16p-16
本章小结
  • Tailwind 是 mobile-first:不加前缀的样式对所有屏幕生效
  • sm: / md: / lg: / xl: / 2xl: 是断点前缀
  • v4 也支持 max-* 变体表示"小于某断点"
  • 容器查询 @container + @md:* 让组件自适应父容器宽度
  • 响应式设计的关键:先写好手机版,再逐步叠加更大屏幕的样式

页面在各种屏幕上都很漂亮了。但只支持浅色背景——下一次我们加入深色主题

目录