tailwindcss-mobile-first

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Mobile-First Responsive Design (2025/2026)

移动优先响应式设计(2025/2026)

Core Philosophy

核心理念

Mobile-first design is the industry standard for 2025/2026. With mobile traffic consistently exceeding 60% of global web traffic and Google's mobile-first indexing, starting with mobile ensures optimal user experience and SEO performance.
移动优先设计是2025/2026年的行业标准。随着移动流量持续占全球网络流量的60%以上,再加上谷歌的移动优先索引,从移动端入手可确保最佳用户体验和SEO表现。

The Mobile-First Mindset

移动优先思维

html
<!-- CORRECT: Mobile-first (progressive enhancement) -->
<div class="text-sm md:text-base lg:text-lg">
  Start small, enhance upward
</div>

<!-- INCORRECT: Desktop-first (graceful degradation) -->
<div class="lg:text-lg md:text-base text-sm">
  Starts large, reduces down (more code, more bugs)
</div>
Key Principle: Unprefixed utilities apply to ALL screen sizes. Breakpoint prefixes apply at that size AND ABOVE.
html
<!-- 正确:移动优先(渐进式增强) -->
<div class="text-sm md:text-base lg:text-lg">
  从小尺寸开始,逐步向上增强
</div>

<!-- 错误:桌面优先(优雅降级) -->
<div class="lg:text-lg md:text-base text-sm">
  从大尺寸开始,逐步缩小(代码更多,bug更多)
</div>
核心原则:无前缀的工具类适用于所有屏幕尺寸。带断点前缀的工具类适用于该尺寸及以上的屏幕。

2025/2026 Breakpoint Strategy

2025/2026断点策略

Tailwind's Default Breakpoints

Tailwind默认断点

PrefixMin-widthTarget Devices
(none)0pxAll mobile phones (base)
sm:
640px (40rem)Large phones, small tablets
md:
768px (48rem)Tablets (portrait)
lg:
1024px (64rem)Tablets (landscape), laptops
xl:
1280px (80rem)Desktops
2xl:
1536px (96rem)Large desktops
前缀最小宽度目标设备
(无)0px所有移动设备(基础)
sm:
640px (40rem)大屏手机、小尺寸平板
md:
768px (48rem)平板(竖屏)
lg:
1024px (64rem)平板(横屏)、笔记本电脑
xl:
1280px (80rem)桌面电脑
2xl:
1536px (96rem)大尺寸桌面电脑

Content-Driven Breakpoints

内容驱动的断点

Best Practice 2025/2026: Let content determine breakpoints, not device dimensions.
css
@theme {
  /* Override defaults based on YOUR content needs */
  --breakpoint-sm: 36rem;  /* 576px - when your content needs more space */
  --breakpoint-md: 48rem;  /* 768px */
  --breakpoint-lg: 62rem;  /* 992px - common content width */
  --breakpoint-xl: 75rem;  /* 1200px */
  --breakpoint-2xl: 90rem; /* 1440px */

  /* Add custom breakpoints for specific content needs */
  --breakpoint-xs: 20rem;  /* 320px - very small devices */
  --breakpoint-3xl: 120rem; /* 1920px - ultra-wide */
}
2025/2026最佳实践:让内容决定断点,而非设备尺寸。
css
@theme {
  /* 根据你的内容需求覆盖默认值 */
  --breakpoint-sm: 36rem;  /* 576px - 当内容需要更多空间时 */
  --breakpoint-md: 48rem;  /* 768px */
  --breakpoint-lg: 62rem;  /* 992px - 常见内容宽度 */
  --breakpoint-xl: 75rem;  /* 1200px */
  --breakpoint-2xl: 90rem; /* 1440px */

  /* 为特定内容需求添加自定义断点 */
  --breakpoint-xs: 20rem;  /* 320px - 极小尺寸设备 */
  --breakpoint-3xl: 120rem; /* 1920px - 超宽屏 */
}

Screen Coverage Strategy

屏幕覆盖策略

html
<!-- Cover the most common device ranges (2025/2026 data) -->

<!-- 375px-430px: ~50% of mobile devices (iPhone, modern Android) -->
<div class="px-4">Mobile base</div>

<!-- 768px+: Tablets and small laptops -->
<div class="px-4 md:px-6">Tablet enhancement</div>

<!-- 1024px+: Desktop experience -->
<div class="px-4 md:px-6 lg:px-8">Desktop enhancement</div>

<!-- 1440px+: Wide desktop experience -->
<div class="px-4 md:px-6 lg:px-8 xl:px-12">Wide desktop</div>
html
<!-- 覆盖最常见的设备范围(2025/2026数据) -->

<!-- 375px-430px:约50%的移动设备(iPhone、现代安卓手机) -->
<div class="px-4">移动端基础样式</div>

<!-- 768px+:平板和小尺寸笔记本 -->
<div class="px-4 md:px-6">平板增强样式</div>

<!-- 1024px+:桌面端体验 -->
<div class="px-4 md:px-6 lg:px-8">桌面端增强样式</div>

<!-- 1440px+:宽屏桌面体验 -->
<div class="px-4 md:px-6 lg:px-8 xl:px-12">宽屏桌面样式</div>

Fluid Typography System

流体排版系统

CSS Clamp for Smooth Scaling

用于平滑缩放的CSS Clamp

Fluid typography eliminates jarring size jumps between breakpoints:
css
@theme {
  /* Fluid typography scale */
  --text-fluid-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
  --text-fluid-sm: clamp(0.875rem, 0.8rem + 0.375vw, 1rem);
  --text-fluid-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
  --text-fluid-lg: clamp(1.125rem, 1rem + 0.625vw, 1.25rem);
  --text-fluid-xl: clamp(1.25rem, 1rem + 1.25vw, 1.5rem);
  --text-fluid-2xl: clamp(1.5rem, 1.1rem + 2vw, 2rem);
  --text-fluid-3xl: clamp(1.875rem, 1.2rem + 3.375vw, 2.5rem);
  --text-fluid-4xl: clamp(2.25rem, 1rem + 6.25vw, 3.5rem);
  --text-fluid-5xl: clamp(3rem, 1rem + 10vw, 5rem);
}
Important for Accessibility: Always combine
vw
with
rem
to respect user zoom preferences (WCAG compliance).
流体排版可消除断点间突兀的尺寸跳跃:
css
@theme {
  /* 流体排版比例 */
  --text-fluid-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
  --text-fluid-sm: clamp(0.875rem, 0.8rem + 0.375vw, 1rem);
  --text-fluid-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
  --text-fluid-lg: clamp(1.125rem, 1rem + 0.625vw, 1.25rem);
  --text-fluid-xl: clamp(1.25rem, 1rem + 1.25vw, 1.5rem);
  --text-fluid-2xl: clamp(1.5rem, 1.1rem + 2vw, 2rem);
  --text-fluid-3xl: clamp(1.875rem, 1.2rem + 3.375vw, 2.5rem);
  --text-fluid-4xl: clamp(2.25rem, 1rem + 6.25vw, 3.5rem);
  --text-fluid-5xl: clamp(3rem, 1rem + 10vw, 5rem);
}
无障碍重要提示:始终将
vw
rem
结合使用,以尊重用户的缩放偏好(符合WCAG标准)。

Using Fluid Typography

使用流体排版

html
<!-- Fluid heading that scales smoothly -->
<h1 class="text-fluid-4xl font-bold leading-tight">
  Responsive Heading
</h1>

<!-- Fluid body text -->
<p class="text-fluid-base leading-relaxed max-w-prose">
  Body text that scales proportionally with the viewport
  while respecting user's font size preferences.
</p>

<!-- Fluid with breakpoint overrides for fine control -->
<h2 class="text-fluid-2xl lg:text-fluid-3xl font-semibold">
  Section Title
</h2>
html
<!-- 可平滑缩放的流体标题 -->
<h1 class="text-fluid-4xl font-bold leading-tight">
  响应式标题
</h1>

<!-- 流体正文文本 -->
<p class="text-fluid-base leading-relaxed max-w-prose">
  可随视窗成比例缩放的正文文本,同时尊重用户的字体大小偏好。
</p>

<!-- 带断点覆盖的流体样式,用于精细控制 -->
<h2 class="text-fluid-2xl lg:text-fluid-3xl font-semibold">
  章节标题
</h2>

Fluid Spacing System

流体间距系统

Clamp-Based Spacing

基于Clamp的间距

css
@theme {
  /* Fluid spacing scale */
  --spacing-fluid-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.5rem);
  --spacing-fluid-sm: clamp(0.5rem, 0.4rem + 0.5vw, 1rem);
  --spacing-fluid-md: clamp(1rem, 0.75rem + 1.25vw, 2rem);
  --spacing-fluid-lg: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  --spacing-fluid-xl: clamp(2rem, 1.25rem + 3.75vw, 4rem);
  --spacing-fluid-2xl: clamp(3rem, 1.5rem + 7.5vw, 6rem);
  --spacing-fluid-section: clamp(4rem, 2rem + 10vw, 8rem);
}
css
@theme {
  /* 流体间距比例 */
  --spacing-fluid-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.5rem);
  --spacing-fluid-sm: clamp(0.5rem, 0.4rem + 0.5vw, 1rem);
  --spacing-fluid-md: clamp(1rem, 0.75rem + 1.25vw, 2rem);
  --spacing-fluid-lg: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  --spacing-fluid-xl: clamp(2rem, 1.25rem + 3.75vw, 4rem);
  --spacing-fluid-2xl: clamp(3rem, 1.5rem + 7.5vw, 6rem);
  --spacing-fluid-section: clamp(4rem, 2rem + 10vw, 8rem);
}

Using Fluid Spacing

使用流体间距

html
<!-- Fluid section padding -->
<section class="py-fluid-section px-fluid-md">
  <div class="max-w-7xl mx-auto">
    <h2 class="mb-fluid-lg">Section Title</h2>
    <div class="grid gap-fluid-md grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
      <!-- Cards -->
    </div>
  </div>
</section>

<!-- Hero section with fluid spacing -->
<header class="min-h-screen flex items-center py-fluid-2xl px-fluid-md">
  <div class="max-w-4xl">
    <h1 class="text-fluid-5xl mb-fluid-md">Hero Title</h1>
    <p class="text-fluid-lg mb-fluid-lg">Hero description</p>
    <button class="px-fluid-md py-fluid-sm">Get Started</button>
  </div>
</header>
html
<!-- 流体章节内边距 -->
<section class="py-fluid-section px-fluid-md">
  <div class="max-w-7xl mx-auto">
    <h2 class="mb-fluid-lg">章节标题</h2>
    <div class="grid gap-fluid-md grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
      <!-- 卡片 -->
    </div>
  </div>
</section>

<!-- 带流体间距的Hero区域 -->
<header class="min-h-screen flex items-center py-fluid-2xl px-fluid-md">
  <div class="max-w-4xl">
    <h1 class="text-fluid-5xl mb-fluid-md">Hero标题</h1>
    <p class="text-fluid-lg mb-fluid-lg">Hero描述</p>
    <button class="px-fluid-md py-fluid-sm">开始使用</button>
  </div>
</header>

Touch-Friendly Interactive Elements

触控友好的交互元素

WCAG 2.2 Touch Target Requirements

WCAG 2.2触控目标要求

Minimum sizes (2025 standards):
  • WCAG 2.2 Level AA: 24x24 CSS pixels minimum
  • Recommended: 44x44 CSS pixels (Apple, Google, Microsoft guidelines)
  • Optimal: 48x48 CSS pixels for critical actions
html
<!-- WCAG 2.2 compliant touch targets -->

<!-- Minimum AA compliant (24px) -->
<button class="min-h-6 min-w-6 p-1">
  <svg class="h-4 w-4">...</svg>
</button>

<!-- Recommended size (44px) -->
<button class="min-h-11 min-w-11 p-2.5">
  <svg class="h-6 w-6">...</svg>
  <span class="sr-only">Action</span>
</button>

<!-- Optimal for primary actions (48px) -->
<button class="min-h-12 min-w-12 px-6 py-3 text-base">
  Primary Action
</button>
2025标准最小尺寸
  • WCAG 2.2 AA级别:最小24x24 CSS像素
  • 推荐尺寸:44x44 CSS像素(苹果、谷歌、微软指南)
  • 最优尺寸:关键操作使用48x48 CSS像素
html
<!-- 符合WCAG 2.2标准的触控目标 -->

<!-- 最小AA合规尺寸(24px) -->
<button class="min-h-6 min-w-6 p-1">
  <svg class="h-4 w-4">...</svg>
</button>

<!-- 推荐尺寸(44px) -->
<button class="min-h-11 min-w-11 p-2.5">
  <svg class="h-6 w-6">...</svg>
  <span class="sr-only">操作</span>
</button>

<!-- 主要操作的最优尺寸(48px) -->
<button class="min-h-12 min-w-12 px-6 py-3 text-base">
  主要操作
</button>

Extended Touch Targets

扩展触控目标

html
<!-- Extend touch target beyond visible element -->
<a href="/link" class="relative inline-block text-sm">
  Small visible link
  <!-- Invisible extended touch area -->
  <span class="absolute -inset-3" aria-hidden="true"></span>
</a>

<!-- Icon button with extended target -->
<button class="relative p-2 -m-2 rounded-lg hover:bg-gray-100">
  <svg class="h-5 w-5" aria-hidden="true">...</svg>
  <span class="sr-only">Close</span>
</button>
html
<!-- 扩展触控目标至可见元素之外 -->
<a href="/link" class="relative inline-block text-sm">
  小尺寸可见链接
  <!-- 不可见的扩展触控区域 -->
  <span class="absolute -inset-3" aria-hidden="true"></span>
</a>

<!-- 带扩展目标的图标按钮 -->
<button class="relative p-2 -m-2 rounded-lg hover:bg-gray-100">
  <svg class="h-5 w-5" aria-hidden="true">...</svg>
  <span class="sr-only">关闭</span>
</button>

Touch Target Spacing

触控目标间距

html
<!-- Adequate spacing between touch targets (minimum 8px gap) -->
<nav class="flex gap-3">
  <a href="#" class="min-h-11 px-4 py-2.5">Home</a>
  <a href="#" class="min-h-11 px-4 py-2.5">About</a>
  <a href="#" class="min-h-11 px-4 py-2.5">Contact</a>
</nav>

<!-- Stacked navigation with adequate spacing -->
<nav class="flex flex-col">
  <a href="#" class="py-3 px-4 min-h-11 border-b border-gray-100">Link 1</a>
  <a href="#" class="py-3 px-4 min-h-11 border-b border-gray-100">Link 2</a>
  <a href="#" class="py-3 px-4 min-h-11">Link 3</a>
</nav>

<!-- Button group with safe spacing -->
<div class="flex flex-wrap gap-3">
  <button class="min-h-11 px-4 py-2">Cancel</button>
  <button class="min-h-11 px-4 py-2 bg-blue-600 text-white">Confirm</button>
</div>
html
<!-- 触控目标间的足够间距(最小8px间隙) -->
<nav class="flex gap-3">
  <a href="#" class="min-h-11 px-4 py-2.5">首页</a>
  <a href="#" class="min-h-11 px-4 py-2.5">关于我们</a>
  <a href="#" class="min-h-11 px-4 py-2.5">联系我们</a>
</nav>

<!-- 带足够间距的堆叠式导航 -->
<nav class="flex flex-col">
  <a href="#" class="py-3 px-4 min-h-11 border-b border-gray-100">链接1</a>
  <a href="#" class="py-3 px-4 min-h-11 border-b border-gray-100">链接2</a>
  <a href="#" class="py-3 px-4 min-h-11">链接3</a>
</nav>

<!-- 带安全间距的按钮组 -->
<div class="flex flex-wrap gap-3">
  <button class="min-h-11 px-4 py-2">取消</button>
  <button class="min-h-11 px-4 py-2 bg-blue-600 text-white">确认</button>
</div>

Container Queries (2025 Game-Changer)

容器查询(2025年变革性特性)

Container queries enable component-level responsiveness, independent of viewport size.
容器查询支持组件级响应式,独立于视窗尺寸。

Setup

设置

css
@import "tailwindcss";
@plugin "@tailwindcss/container-queries";
css
@import "tailwindcss";
@plugin "@tailwindcss/container-queries";

Container Query Breakpoints

容器查询断点

ClassMin-width
@xs
20rem (320px)
@sm
24rem (384px)
@md
28rem (448px)
@lg
32rem (512px)
@xl
36rem (576px)
@2xl
42rem (672px)
@3xl
48rem (768px)
@4xl
56rem (896px)
@5xl
64rem (1024px)
类名最小宽度
@xs
20rem (320px)
@sm
24rem (384px)
@md
28rem (448px)
@lg
32rem (512px)
@xl
36rem (576px)
@2xl
42rem (672px)
@3xl
48rem (768px)
@4xl
56rem (896px)
@5xl
64rem (1024px)

Practical Container Query Patterns

实用容器查询模式

html
<!-- Card that responds to its container, not viewport -->
<article class="@container">
  <div class="
    flex flex-col @sm:flex-row
    gap-4 p-4
    bg-white rounded-xl shadow-sm
  ">
    <img
      src="..."
      class="
        w-full @sm:w-32 @lg:w-48
        aspect-video @sm:aspect-square
        object-cover rounded-lg
      "
    />
    <div class="flex-1 min-w-0">
      <h3 class="text-base @md:text-lg @lg:text-xl font-semibold truncate">
        Card Title
      </h3>
      <p class="
        text-sm @md:text-base
        text-gray-600
        line-clamp-2 @lg:line-clamp-3
        mt-2
      ">
        Description that adapts to available space...
      </p>
      <div class="mt-4 flex flex-wrap gap-2 @md:gap-3">
        <span class="text-xs @md:text-sm px-2 py-1 bg-gray-100 rounded">Tag</span>
      </div>
    </div>
  </div>
</article>
html
<!-- 响应容器而非视窗的卡片 -->
<article class="@container">
  <div class="
    flex flex-col @sm:flex-row
    gap-4 p-4
    bg-white rounded-xl shadow-sm
  ">
    <img
      src="..."
      class="
        w-full @sm:w-32 @lg:w-48
        aspect-video @sm:aspect-square
        object-cover rounded-lg
      "
    />
    <div class="flex-1 min-w-0">
      <h3 class="text-base @md:text-lg @lg:text-xl font-semibold truncate">
        卡片标题
      </h3>
      <p class="
        text-sm @md:text-base
        text-gray-600
        line-clamp-2 @lg:line-clamp-3
        mt-2
      ">
        可根据可用空间自适应的描述...
      </p>
      <div class="mt-4 flex flex-wrap gap-2 @md:gap-3">
        <span class="text-xs @md:text-sm px-2 py-1 bg-gray-100 rounded">标签</span>
      </div>
    </div>
  </div>
</article>

Named Containers

命名容器

html
<div class="@container/sidebar w-64">
  <nav class="
    flex flex-col @lg/sidebar:flex-row
    @lg/sidebar:items-center
    gap-2 @lg/sidebar:gap-4
  ">
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
  </nav>
</div>

<main class="@container/main flex-1">
  <div class="
    grid grid-cols-1
    @md/main:grid-cols-2
    @xl/main:grid-cols-3
    gap-6
  ">
    <!-- Grid items respond to main container -->
  </div>
</main>
html
<div class="@container/sidebar w-64">
  <nav class="
    flex flex-col @lg/sidebar:flex-row
    @lg/sidebar:items-center
    gap-2 @lg/sidebar:gap-4
  ">
    <a href="#">链接1</a>
    <a href="#">链接2</a>
  </nav>
</div>

<main class="@container/main flex-1">
  <div class="
    grid grid-cols-1
    @md/main:grid-cols-2
    @xl/main:grid-cols-3
    gap-6
  ">
    <!-- 网格项响应主容器 -->
  </div>
</main>

When to Use Container vs Viewport Queries

何时使用容器查询vs视窗查询

Use Container QueriesUse Viewport Queries
Reusable componentsPage-level layouts
Sidebar widgetsNavigation bars
Card gridsHero sections
Embedded contentFull-width sections
CMS/dynamic contentFixed app shells
使用容器查询的场景使用视窗查询的场景
可复用组件页面级布局
侧边栏小部件导航栏
卡片网格Hero区域
嵌入内容全宽区域
CMS/动态内容固定应用外壳

Responsive Layout Patterns

响应式布局模式

Mobile-First Grid System

移动优先网格系统

html
<!-- Auto-responsive grid with minimum card width -->
<div class="
  grid gap-6
  grid-cols-1
  sm:grid-cols-2
  lg:grid-cols-3
  xl:grid-cols-4
">
  <!-- Cards automatically flow -->
</div>

<!-- CSS Grid auto-fit (no breakpoints needed) -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(280px,1fr))] gap-6">
  <!-- Cards auto-fit with 280px minimum -->
</div>

<!-- CSS Grid auto-fill for fixed-size items -->
<div class="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-4">
  <!-- Fixed minimum size, grows to fill -->
</div>
html
<!-- 带最小卡片宽度的自动响应式网格 -->
<div class="
  grid gap-6
  grid-cols-1
  sm:grid-cols-2
  lg:grid-cols-3
  xl:grid-cols-4
">
  <!-- 卡片自动换行 -->
</div>

<!-- 无需断点的CSS Grid auto-fit -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(280px,1fr))] gap-6">
  <!-- 卡片自动适配,最小宽度280px -->
</div>

<!-- 用于固定尺寸项的CSS Grid auto-fill -->
<div class="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-4">
  <!-- 固定最小尺寸,自动填充剩余空间 -->
</div>

Responsive Flexbox Patterns

响应式Flexbox模式

html
<!-- Stack to row -->
<div class="flex flex-col md:flex-row gap-4">
  <div class="flex-1">Content 1</div>
  <div class="flex-1">Content 2</div>
</div>

<!-- Wrap with centered items -->
<div class="flex flex-wrap justify-center gap-4">
  <div class="w-full sm:w-auto">Item 1</div>
  <div class="w-full sm:w-auto">Item 2</div>
  <div class="w-full sm:w-auto">Item 3</div>
</div>

<!-- Mobile stack, desktop inline with push -->
<div class="flex flex-col sm:flex-row sm:items-center gap-4">
  <div class="flex-1">
    <h3>Title</h3>
    <p class="text-sm text-gray-600">Description</p>
  </div>
  <button class="sm:ml-auto min-h-11 px-4 py-2">Action</button>
</div>
html
<!-- 堆叠式转横向 -->
<div class="flex flex-col md:flex-row gap-4">
  <div class="flex-1">内容1</div>
  <div class="flex-1">内容2</div>
</div>

<!-- 可换行且项居中 -->
<div class="flex flex-wrap justify-center gap-4">
  <div class="w-full sm:w-auto">项1</div>
  <div class="w-full sm:w-auto">项2</div>
  <div class="w-full sm:w-auto">项3</div>
</div>

<!-- 移动端堆叠,桌面端横向并右推操作按钮 -->
<div class="flex flex-col sm:flex-row sm:items-center gap-4">
  <div class="flex-1">
    <h3>标题</h3>
    <p class="text-sm text-gray-600">描述</p>
  </div>
  <button class="sm:ml-auto min-h-11 px-4 py-2">操作</button>
</div>

Responsive Sidebar Layouts

响应式侧边栏布局

html
<!-- Collapsible sidebar -->
<div class="flex min-h-screen">
  <!-- Sidebar: hidden on mobile, visible on desktop -->
  <aside class="
    hidden lg:flex lg:flex-col
    w-64 border-r bg-gray-50
  ">
    <nav class="flex-1 p-4">...</nav>
  </aside>

  <!-- Main content -->
  <main class="flex-1 p-4 lg:p-8">
    Content
  </main>
</div>

<!-- Mobile drawer + desktop sidebar -->
<div class="relative flex min-h-screen">
  <!-- Mobile drawer overlay -->
  <div class="
    fixed inset-0 z-40 lg:hidden
    bg-black/50
    data-[open=false]:hidden
  " data-open="false">
    <aside class="w-64 h-full bg-white">
      Mobile navigation
    </aside>
  </div>

  <!-- Desktop sidebar -->
  <aside class="hidden lg:block w-64 border-r">
    Desktop navigation
  </aside>

  <main class="flex-1">Content</main>
</div>
html
<!-- 可折叠侧边栏 -->
<div class="flex min-h-screen">
  <!-- 侧边栏:移动端隐藏,桌面端可见 -->
  <aside class="
    hidden lg:flex lg:flex-col
    w-64 border-r bg-gray-50
  ">
    <nav class="flex-1 p-4">...</nav>
  </aside>

  <!-- 主内容 -->
  <main class="flex-1 p-4 lg:p-8">
    内容
  </main>
</div>

<!-- 移动端抽屉+桌面端侧边栏 -->
<div class="relative flex min-h-screen">
  <!-- 移动端抽屉遮罩 -->
  <div class="
    fixed inset-0 z-40 lg:hidden
    bg-black/50
    data-[open=false]:hidden
  " data-open="false">
    <aside class="w-64 h-full bg-white">
      移动端导航
    </aside>
  </div>

  <!-- 桌面端侧边栏 -->
  <aside class="hidden lg:block w-64 border-r">
    桌面端导航
  </aside>

  <main class="flex-1">内容</main>
</div>

Holy Grail Layout (2025)

圣杯布局(2025版)

html
<div class="min-h-screen grid grid-rows-[auto_1fr_auto]">
  <!-- Header -->
  <header class="sticky top-0 z-50 h-16 bg-white border-b shadow-sm">
    <nav class="h-full max-w-7xl mx-auto px-4 flex items-center justify-between">
      <Logo />
      <ul class="hidden md:flex gap-6">...</ul>
      <button class="md:hidden min-h-11 min-w-11">Menu</button>
    </nav>
  </header>

  <!-- Main content area with optional sidebars -->
  <div class="
    grid
    grid-cols-1
    md:grid-cols-[240px_1fr]
    lg:grid-cols-[240px_1fr_280px]
    gap-0
  ">
    <nav class="hidden md:block border-r p-4">Left Nav</nav>
    <main class="p-4 md:p-6 lg:p-8">Main Content</main>
    <aside class="hidden lg:block border-l p-4">Right Sidebar</aside>
  </div>

  <!-- Footer -->
  <footer class="bg-gray-900 text-white py-8 md:py-12">
    Footer content
  </footer>
</div>
html
<div class="min-h-screen grid grid-rows-[auto_1fr_auto]">
  <!-- 头部 -->
  <header class="sticky top-0 z-50 h-16 bg-white border-b shadow-sm">
    <nav class="h-full max-w-7xl mx-auto px-4 flex items-center justify-between">
      <Logo />
      <ul class="hidden md:flex gap-6">...</ul>
      <button class="md:hidden min-h-11 min-w-11">菜单</button>
    </nav>
  </header>

  <!-- 带可选侧边栏的主内容区域 -->
  <div class="
    grid
    grid-cols-1
    md:grid-cols-[240px_1fr]
    lg:grid-cols-[240px_1fr_280px]
    gap-0
  ">
    <nav class="hidden md:block border-r p-4">左侧导航</nav>
    <main class="p-4 md:p-6 lg:p-8">主内容</main>
    <aside class="hidden lg:block border-l p-4">右侧侧边栏</aside>
  </div>

  <!-- 页脚 -->
  <footer class="bg-gray-900 text-white py-8 md:py-12">
    页脚内容
  </footer>
</div>

Responsive Images

响应式图片

Aspect Ratio Containers

宽高比容器

html
<!-- Maintain aspect ratio across all sizes -->
<div class="aspect-video overflow-hidden rounded-lg">
  <img src="..." class="w-full h-full object-cover" loading="lazy" />
</div>

<!-- Responsive aspect ratio -->
<div class="aspect-square sm:aspect-video lg:aspect-[4/3] overflow-hidden">
  <img src="..." class="w-full h-full object-cover" />
</div>
html
<!-- 在所有尺寸下保持宽高比 -->
<div class="aspect-video overflow-hidden rounded-lg">
  <img src="..." class="w-full h-full object-cover" loading="lazy" />
</div>

<!-- 响应式宽高比 -->
<div class="aspect-square sm:aspect-video lg:aspect-[4/3] overflow-hidden">
  <img src="..." class="w-full h-full object-cover" />
</div>

Responsive Image Sizes

响应式图片尺寸

html
<!-- Art direction with picture element -->
<picture>
  <source media="(min-width: 1024px)" srcset="large.jpg" />
  <source media="(min-width: 640px)" srcset="medium.jpg" />
  <img
    src="small.jpg"
    alt="Description"
    class="w-full h-auto rounded-lg"
    loading="lazy"
  />
</picture>

<!-- Responsive srcset -->
<img
  src="image-800.jpg"
  srcset="
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1200.jpg 1200w,
    image-1600.jpg 1600w
  "
  sizes="
    (min-width: 1280px) 1200px,
    (min-width: 768px) 80vw,
    100vw
  "
  alt="Responsive image"
  class="w-full h-auto"
  loading="lazy"
/>
html
<!-- 使用picture元素进行艺术方向控制 -->
<picture>
  <source media="(min-width: 1024px)" srcset="large.jpg" />
  <source media="(min-width: 640px)" srcset="medium.jpg" />
  <img
    src="small.jpg"
    alt="描述"
    class="w-full h-auto rounded-lg"
    loading="lazy"
  />
</picture>

<!-- 响应式srcset -->
<img
  src="image-800.jpg"
  srcset="
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1200.jpg 1200w,
    image-1600.jpg 1600w
  "
  sizes="
    (min-width: 1280px) 1200px,
    (min-width: 768px) 80vw,
    100vw
  "
  alt="响应式图片"
  class="w-full h-auto"
  loading="lazy"
/>

Responsive Typography Patterns

响应式排版模式

Heading Hierarchy

标题层级

html
<!-- Mobile-first heading scale -->
<h1 class="
  text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl
  font-bold leading-tight tracking-tight
">
  Main Heading
</h1>

<h2 class="
  text-xl sm:text-2xl md:text-3xl lg:text-4xl
  font-semibold leading-snug
">
  Section Heading
</h2>

<h3 class="
  text-lg sm:text-xl md:text-2xl
  font-medium
">
  Subsection Heading
</h3>
html
<!-- 移动优先标题比例 -->
<h1 class="
  text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl
  font-bold leading-tight tracking-tight
">
  主标题
</h1>

<h2 class="
  text-xl sm:text-2xl md:text-3xl lg:text-4xl
  font-semibold leading-snug
">
  章节标题
</h2>

<h3 class="
  text-lg sm:text-xl md:text-2xl
  font-medium
">
  子章节标题
</h3>

Readable Body Text

易读正文文本

html
<!-- Optimal line length and spacing -->
<article class="max-w-prose mx-auto">
  <p class="
    text-base md:text-lg
    leading-relaxed md:leading-loose
    text-gray-700 dark:text-gray-300
  ">
    Body text optimized for readability with 45-75 characters per line.
  </p>
</article>

<!-- Text that balances across lines -->
<h2 class="text-balance text-2xl md:text-3xl font-bold max-w-2xl">
  This heading will balance text across lines to avoid orphans
</h2>
html
<!-- 最优行宽和间距 -->
<article class="max-w-prose mx-auto">
  <p class="
    text-base md:text-lg
    leading-relaxed md:leading-loose
    text-gray-700 dark:text-gray-300
  ">
  每行45-75个字符的正文文本,优化可读性。
  </p>
</article>

<!-- 自动平衡行的文本 -->
<h2 class="text-balance text-2xl md:text-3xl font-bold max-w-2xl">
  此标题会自动平衡文本行,避免孤行
</h2>

Mobile Navigation Patterns

移动端导航模式

Hamburger to Full Nav

汉堡菜单转完整导航

html
<nav class="relative">
  <!-- Desktop navigation -->
  <ul class="hidden md:flex items-center gap-6">
    <li><a href="#" class="py-2 hover:text-blue-600">Home</a></li>
    <li><a href="#" class="py-2 hover:text-blue-600">Products</a></li>
    <li><a href="#" class="py-2 hover:text-blue-600">About</a></li>
    <li><a href="#" class="py-2 hover:text-blue-600">Contact</a></li>
  </ul>

  <!-- Mobile menu button -->
  <button
    class="md:hidden min-h-11 min-w-11 p-2"
    aria-expanded="false"
    aria-controls="mobile-menu"
    aria-label="Toggle navigation menu"
  >
    <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>

  <!-- Mobile menu (controlled via JS) -->
  <div
    id="mobile-menu"
    class="
      md:hidden
      absolute top-full left-0 right-0
      bg-white shadow-lg border-t
      hidden
    "
  >
    <ul class="py-2">
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">Home</a></li>
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">Products</a></li>
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">About</a></li>
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">Contact</a></li>
    </ul>
  </div>
</nav>
html
<nav class="relative">
  <!-- 桌面端导航 -->
  <ul class="hidden md:flex items-center gap-6">
    <li><a href="#" class="py-2 hover:text-blue-600">首页</a></li>
    <li><a href="#" class="py-2 hover:text-blue-600">产品</a></li>
    <li><a href="#" class="py-2 hover:text-blue-600">关于我们</a></li>
    <li><a href="#" class="py-2 hover:text-blue-600">联系我们</a></li>
  </ul>

  <!-- 移动端菜单按钮 -->
  <button
    class="md:hidden min-h-11 min-w-11 p-2"
    aria-expanded="false"
    aria-controls="mobile-menu"
    aria-label="切换导航菜单"
  >
    <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>

  <!-- 移动端菜单(通过JS控制) -->
  <div
    id="mobile-menu"
    class="
      md:hidden
      absolute top-full left-0 right-0
      bg-white shadow-lg border-t
      hidden
    "
  >
    <ul class="py-2">
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">首页</a></li>
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">产品</a></li>
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">关于我们</a></li>
      <li><a href="#" class="block px-4 py-3 min-h-11 hover:bg-gray-50">联系我们</a></li>
    </ul>
  </div>
</nav>

Bottom Navigation (Mobile App Style)

底部导航(移动端应用风格)

html
<!-- Fixed bottom navigation for mobile -->
<nav class="
  fixed bottom-0 inset-x-0 z-50
  md:hidden
  bg-white border-t shadow-lg
  safe-area-pb
">
  <ul class="flex justify-around">
    <li>
      <a href="#" class="
        flex flex-col items-center
        min-h-14 min-w-14 px-3 py-2
        text-xs
        text-gray-600 hover:text-blue-600
        aria-current:text-blue-600
      ">
        <svg class="h-6 w-6 mb-1">...</svg>
        Home
      </a>
    </li>
    <li>
      <a href="#" class="flex flex-col items-center min-h-14 min-w-14 px-3 py-2 text-xs">
        <svg class="h-6 w-6 mb-1">...</svg>
        Search
      </a>
    </li>
    <li>
      <a href="#" class="flex flex-col items-center min-h-14 min-w-14 px-3 py-2 text-xs">
        <svg class="h-6 w-6 mb-1">...</svg>
        Profile
      </a>
    </li>
  </ul>
</nav>

<!-- Add padding to main content to prevent overlap -->
<main class="pb-20 md:pb-0">
  Content
</main>
html
<!-- 移动端固定底部导航 -->
<nav class="
  fixed bottom-0 inset-x-0 z-50
  md:hidden
  bg-white border-t shadow-lg
  safe-area-pb
">
  <ul class="flex justify-around">
    <li>
      <a href="#" class="
        flex flex-col items-center
        min-h-14 min-w-14 px-3 py-2
        text-xs
        text-gray-600 hover:text-blue-600
        aria-current:text-blue-600
      ">
        <svg class="h-6 w-6 mb-1">...</svg>
        首页
      </a>
    </li>
    <li>
      <a href="#" class="flex flex-col items-center min-h-14 min-w-14 px-3 py-2 text-xs">
        <svg class="h-6 w-6 mb-1">...</svg>
        搜索
      </a>
    </li>
    <li>
      <a href="#" class="flex flex-col items-center min-h-14 min-w-14 px-3 py-2 text-xs">
        <svg class="h-6 w-6 mb-1">...</svg>
        个人中心
      </a>
    </li>
  </ul>
</nav>

<!-- 为主内容添加内边距,避免被底部导航遮挡 -->
<main class="pb-20 md:pb-0">
  内容
</main>

Safe Area Handling (Notched Devices)

安全区域处理(带刘海的设备)

css
@utility safe-area-pt {
  padding-top: env(safe-area-inset-top);
}

@utility safe-area-pb {
  padding-bottom: env(safe-area-inset-bottom);
}

@utility safe-area-pl {
  padding-left: env(safe-area-inset-left);
}

@utility safe-area-pr {
  padding-right: env(safe-area-inset-right);
}

@utility safe-area-p {
  padding-top: env(safe-area-inset-top);
  padding-right: env(safe-area-inset-right);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
}
html
<!-- Header that respects notch -->
<header class="sticky top-0 safe-area-pt bg-white">
  <div class="h-16 flex items-center px-4">
    Navigation
  </div>
</header>

<!-- Bottom navigation with safe area -->
<nav class="fixed bottom-0 inset-x-0 safe-area-pb bg-white border-t">
  Bottom nav
</nav>
css
@utility safe-area-pt {
  padding-top: env(safe-area-inset-top);
}

@utility safe-area-pb {
  padding-bottom: env(safe-area-inset-bottom);
}

@utility safe-area-pl {
  padding-left: env(safe-area-inset-left);
}

@utility safe-area-pr {
  padding-right: env(safe-area-inset-right);
}

@utility safe-area-p {
  padding-top: env(safe-area-inset-top);
  padding-right: env(safe-area-inset-right);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
}
html
<!-- 尊重刘海区域的头部 -->
<header class="sticky top-0 safe-area-pt bg-white">
  <div class="h-16 flex items-center px-4">
    导航
  </div>
</header>

<!-- 带安全区域的底部导航 -->
<nav class="fixed bottom-0 inset-x-0 safe-area-pb bg-white border-t">
  底部导航
</nav>

Performance Optimization for Mobile

移动端性能优化

Lazy Loading

懒加载

html
<!-- Native lazy loading for images -->
<img src="image.jpg" alt="..." loading="lazy" class="w-full h-auto" />

<!-- Lazy load below-fold content -->
<div class="contents" data-lazy-load>
  Heavy component loaded on demand
</div>
html
<!-- 图片原生懒加载 -->
<img src="image.jpg" alt="..." loading="lazy" class="w-full h-auto" />

<!-- 懒加载视口外内容 -->
<div class="contents" data-lazy-load>
  按需加载的重型组件
</div>

Content Visibility

内容可见性

css
@utility content-auto {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}
html
<!-- Skip rendering off-screen content -->
<section class="content-auto">
  Large section that may be off-screen
</section>
css
@utility content-auto {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}
html
<!-- 跳过渲染视口外内容 -->
<section class="content-auto">
  可能处于视口外的大型区域
</section>

Reduced Data Usage

减少数据使用

html
<!-- Show simpler version on slow connections -->
<picture>
  <source
    srcset="video-poster.jpg"
    media="(prefers-reduced-data: reduce)"
  />
  <img src="animated.gif" alt="..." />
</picture>
html
<!-- 在慢速网络下显示简化版本 -->
<picture>
  <source
    srcset="video-poster.jpg"
    media="(prefers-reduced-data: reduce)"
  />
  <img src="animated.gif" alt="..." />
</picture>

Responsive Testing Checklist

响应式测试清单

Essential Tests

必要测试

  1. 320px - Smallest supported width (older iPhones)
  2. 375px - Modern iPhone base
  3. 414px - Large phones (iPhone Plus/Max)
  4. 768px - iPad portrait
  5. 1024px - iPad landscape / small laptop
  6. 1280px - Standard laptop
  7. 1440px - Large desktop
  8. 1920px - Full HD desktop
  1. 320px - 最小支持宽度(旧款iPhone)
  2. 375px - 现代iPhone基础宽度
  3. 414px - 大屏手机(iPhone Plus/Max)
  4. 768px - iPad竖屏
  5. 1024px - iPad横屏 / 小尺寸笔记本
  6. 1280px - 标准笔记本
  7. 1440px - 大尺寸桌面
  8. 1920px - 全高清桌面

Quality Checks

质量检查

  • Text remains readable at all sizes
  • Touch targets are minimum 44px on mobile
  • No horizontal scroll on any viewport
  • Images don't overflow containers
  • Navigation is accessible on all sizes
  • Forms are usable on mobile
  • Modals fit mobile screens
  • Tables have mobile alternatives
  • Performance under 3s LCP on 3G
  • 所有尺寸下文本保持可读
  • 移动端触控目标最小为44px
  • 任何视口下无水平滚动
  • 图片不会溢出容器
  • 导航在所有尺寸下均可访问
  • 表单在移动端可用
  • 模态框适配移动端屏幕
  • 表格有移动端替代方案
  • 3G网络下LCP性能低于3秒

Best Practices Summary

最佳实践总结

PracticeImplementation
Mobile-first utilitiesUnprefixed first, then
sm:
,
md:
,
lg:
Touch targets
min-h-11 min-w-11
(44px minimum)
Fluid typography
clamp(min, preferred, max)
with
rem + vw
Fluid spacing
clamp()
for padding and margins
Container queries
@container
for component responsiveness
Safe areas
env(safe-area-inset-*)
for notched devices
Readable text
max-w-prose
(65ch) and
leading-relaxed
Lazy loading
loading="lazy"
on below-fold images
Touch spacing
gap-3
(12px) minimum between targets
Viewport meta
width=device-width, initial-scale=1
实践实现方式
移动优先工具类先使用无前缀,再用
sm:
md:
lg:
触控目标
min-h-11 min-w-11
(最小44px)
流体排版
rem + vw
clamp(min, preferred, max)
流体间距使用
clamp()
处理内边距和外边距
容器查询使用
@container
实现组件级响应式
安全区域使用
env(safe-area-inset-*)
处理刘海设备
易读文本使用
max-w-prose
(65字符行宽)和
leading-relaxed
懒加载视口外图片使用
loading="lazy"
触控间距触控目标间使用
gap-3
(最小12px间隙)
视口元标签
width=device-width, initial-scale=1