Chapter 03

响应式设计

断点前缀、移动优先策略、arbitrary values 与 @container 容器查询——让界面适配所有屏幕

1. 断点前缀系统

Tailwind 的响应式系统基于 断点前缀(breakpoint prefix):在工具类名前加上 sm:md: 等前缀,表示该样式只在对应屏幕宽度以上生效。

前缀最小宽度目标设备
(无前缀)0px+(所有屏幕)移动端基础样式
sm:640px+大手机 / 小平板
md:768px+平板
lg:1024px+笔记本
xl:1280px+桌面显示器
2xl:1536px+大型显示器
ℹ️

名词解释:移动优先(Mobile-First)
Tailwind 的断点是 min-width 媒体查询,不是 max-width。这意味着无前缀的工具类是移动端基础样式,加了前缀的工具类在达到该断点后生效(并覆盖更小屏幕的样式)。这种策略叫做"移动优先"——先为最小屏幕设计,再逐步为大屏增强。

2. 移动优先实战

<!-- 响应式文字大小:小屏小字,大屏大字 -->
<h1 class="text-2xl md:text-4xl lg:text-6xl font-bold">
  标题文字
</h1>
<!-- 0-767px: text-2xl(24px)
     768-1023px: text-4xl(36px)
     1024px+: text-6xl(60px) -->

<!-- 响应式 grid 列数 -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
  <!-- 手机: 1列 | 小平板: 2列 | 笔记本: 3列 | 桌面: 4列 -->
  <div>卡片1</div>
  <div>卡片2</div>
  <div>卡片3</div>
  <div>卡片4</div>
</div>

<!-- 响应式 padding / 间距 -->
<section class="px-4 sm:px-8 lg:px-16 py-8 lg:py-16">
  页面区块
</section>

3. 响应式导航栏实战

<!-- 移动端:汉堡菜单;桌面端:水平导航 -->
<nav class="flex items-center justify-between p-4 bg-white shadow">
  <!-- Logo -->
  <a href="/" class="text-xl font-bold text-cyan-600">MyApp</a>

  <!-- 桌面导航链接(小屏隐藏,md+ 显示)-->
  <div class="hidden md:flex items-center gap-6">
    <a href="#" class="text-gray-600 hover:text-cyan-600">首页</a>
    <a href="#" class="text-gray-600 hover:text-cyan-600">文档</a>
    <a href="#" class="text-gray-600 hover:text-cyan-600">关于</a>
    <button class="bg-cyan-500 text-white px-4 py-2 rounded-lg">开始使用</button>
  </div>

  <!-- 汉堡菜单按钮(小屏显示,md+ 隐藏)-->
  <button class="md:hidden p-2" id="menu-btn">
    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>
</nav>

4. Arbitrary Values 任意值

Tailwind 的调色板和间距系统已经覆盖大多数场景,但有时你需要一个设计稿中精确的值(如 123px、#1a2b3c)。v4 支持用方括号语法直接写任意值:

<!-- 任意宽度 / 高度 -->
<div class="w-[123px] h-[72px]">精确尺寸</div>

<!-- 任意颜色 -->
<div class="bg-[#1a2b3c] text-[#f0e9d2]">品牌色</div>

<!-- 任意 CSS 值 -->
<div class="top-[117px] left-[calc(50%-2rem)]">精确定位</div>

<!-- 任意属性(CSS 变量)-->
<div class="bg-[var(--brand-color)]">CSS 变量颜色</div>

<!-- 任意断点 -->
<div class="hidden [@media(min-width:900px)]:block">
  900px 以上显示
</div>

<!-- 带空格的任意值:空格用下划线代替 -->
<div class="grid grid-cols-[1fr_2fr_1fr]">
  <!-- grid-template-columns: 1fr 2fr 1fr -->
</div>
⚠️

任意值的使用建议:偶尔使用任意值是合理的,但如果频繁用到相同的任意值,考虑将其添加到 @theme 配置中作为 design token。大量使用任意值会破坏设计一致性。

5. 容器查询 @container

传统响应式设计依赖视口宽度断点,这对于可复用组件有局限性——同一个卡片组件在侧边栏(窄)和主内容区(宽)中应该有不同布局,但视口断点无法区分这种情况。

容器查询(Container Query)允许组件根据其父容器的宽度而非视口宽度来改变样式。Tailwind v4 原生内置此功能。

<!-- 1. 父容器标记为 containment context -->
<div class="@container">

  <!-- 2. 子组件使用 @sm: @md: @lg: 等容器断点前缀 -->
  <div class="flex flex-col @md:flex-row gap-4">
    <!-- 当容器 >= 448px 时改为水平排列 -->
    <img class="w-full @md:w-48 rounded-lg" src="..." alt="">
    <div>
      <h3 class="text-base @md:text-xl font-semibold">标题</h3>
      <p class="text-sm text-gray-500">描述文字</p>
    </div>
  </div>

</div>
容器前缀容器最小宽度
@xs:320px+
@sm:384px+
@md:448px+
@lg:512px+
@xl:576px+
@2xl:672px+

容器查询实战:自适应卡片

<!-- 该卡片在任何宽度的容器中都能自适应布局 -->
<div class="@container rounded-xl border p-4">
  <div class="flex flex-col @sm:flex-row gap-4 items-start">
    <!-- 头像 -->
    <div class="w-16 h-16 @sm:w-20 @sm:h-20 rounded-full bg-cyan-100 flex-shrink-0">
      <img src="/avatar.jpg" alt="avatar" class="w-full h-full rounded-full object-cover">
    </div>
    <!-- 信息 -->
    <div class="flex-1">
      <h3 class="text-lg font-bold">张三</h3>
      <p class="text-sm text-gray-500">全栈工程师</p>
      <p class="hidden @sm:block mt-2 text-sm text-gray-600">
        只在容器宽度 >= 384px 时显示的详细介绍
      </p>
    </div>
  </div>
</div>

本章小结:Tailwind 响应式设计的核心是"断点前缀 + 移动优先"。记住 5 个断点(sm/md/lg/xl/2xl)对应的宽度值,从无前缀(最小屏幕)开始设计,逐步添加更大屏幕的前缀覆盖样式。容器查询 @container 是 v4 内置的强大工具,让组件真正做到自包含的响应式。