前端开发
用 Tailwind CSS 实现响应式布局与深色模式(含…
在 Tailwind CSS 项目中做移动优先响应式设计、容器查询、深色模式切换与主题令牌时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
用 Tailwind CSS 实现响应式通用
解决思路
- 采用移动优先:无前缀工具类作用于所有屏幕,断点前缀作用于该尺寸及以上;写 text-sm md:text-base lg:text-lg,不要写成 lg:text-lg md:text-base text-sm 的桌面优先顺序。
- 使用默认断点:sm: 640px、md: 768px、lg: 1024px、xl: 1280px、2xl: 1536px(对应 @media (min-width: ...))。
- 按 2025/2026 常见设备宽度测试:320px、375px、390-430px、768px、1024px、1280px、1440px、1920px。
- 在 @theme 中自定义断点,如 --breakpoint-xs: 20rem、--breakpoint-3xl: 100rem、--breakpoint-4xl: 120rem,也可覆盖内置断点(--breakpoint-sm: 36rem、--breakpoint-lg: 62rem)。
- 采用内容驱动断点:按内容需要定义如 --breakpoint-prose: 65ch、--breakpoint-content: 75rem,在布局破裂处添加断点,而不是按设备规格。
- 响应式网格:grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4。
- 响应式排版:标题 text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold;正文 text-sm md:text-base lg:text-lg leading-relaxed。
- 响应式间距:section 用 py-8 md:py-12 lg:py-16 px-4 md:px-8 lg:px-12,内部容器 max-w-4xl mx-auto。
- 响应式导航:flex flex-col md:flex-row items-center justify-between,桌面菜单 hidden md:flex gap-4,移动按钮 md:hidden。
- 按屏幕尺寸显示/隐藏:桌面用 hidden md:block,移动用 block md:hidden;按断点切换内容用 sm:hidden、hidden sm:inline md:hidden、hidden md:inline lg:hidden 等组合。
- 使用容器查询(v4):先 @plugin "@tailwindcss/container-queries",父元素加 @container,子元素用 @md:flex-row @lg:gap-8;需要多上下文时用命名容器 @container/card 与 @lg/card:grid-cols-2。
- 容器查询断点:@xs 20rem、@sm 24rem、@md 28rem、@lg 32rem、@xl 36rem、@2xl 42rem、@3xl 48rem。
- 选择容器查询还是视口查询:可复用组件、卡片、侧栏小部件、CMS/嵌入内容用容器查询;页面级布局、导航栏、Hero、全宽区块用视口查询。
- 最大宽度断点:用 md:hidden 只作用于小于 md 的屏幕,或用任意值 [@media(max-width:600px)]:text-sm。
- 深色模式策略一(默认 media):直接 @import "tailwindcss",无需额外配置,用 dark: 变体跟随系统 prefers-color-scheme,如 bg-white dark:bg-gray-900。
- 深色模式策略二(selector 手动切换):在 CSS 中写 @custom-variant dark (&:where(.dark, .dark *));,在 html 或 body 上加 .dark 类启用。
- JavaScript 简单切换:document.documentElement.classList.toggle('dark')。
- JavaScript 带 localStorage 持久化:initDarkMode 读取 localStorage.getItem('darkMode'),无记录时回退到 window.matchMedia('(prefers-color-scheme: dark)').matches,用 classList.toggle('dark', isDark) 应用;toggleDarkMode 用 classList.toggle 的返回值写入 localStorage。
- 三态切换(light/dark/system):setTheme 写入 localStorage 的 theme,applyTheme 读取 theme(默认 system),system 时按 matchMedia 判断;用 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ...) 监听系统变化,仅当 theme 为 system 时重新 applyTheme。
- data 属性策略:@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));,在 html 上写 data-theme="dark"。
- Next.js 用 next-themes:npm install next-themes;在 app/providers.tsx 中用 'use client' 包裹 ThemeProvider(attribute="class" defaultTheme="system");在 app/layout.tsx 的 html 上加 suppressHydrationWarning 并包 Providers;在 ThemeToggle.tsx 中用 useTheme() 的 theme/setTheme 切换。
- 深色模式配色:主文本 text-gray-900 dark:text-gray-100,次文本 text-gray-600 dark:text-gray-400,弱化文本 text-gray-400 dark:text-gray-500;页面背景 bg-white dark:bg-gray-900,卡片 bg-gray-50 dark:bg-gray-800,抬升背景 bg-gray-100 dark:bg-gray-700;边框 border-gray-200 dark:border-gray-700;按钮 bg-blue-500 hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700。
- 用 CSS 变量做深色模式:在 @theme 定义 --color-bg-primary、--color-bg-secondary、--color-text-primary、--color-text-secondary 等语义色,在 @media (prefers-color-scheme: dark) 的 :root 中覆盖,使用时写 bg-[var(--color-bg-primary)] text-[var(--color-text-primary)]。
- Typography 插件深色模式:在 article 上用 prose dark:prose-invert。
- 响应式与深色模式组合:在同一元素上叠加断点与 dark:,如 grid grid-cols-1 md:grid-cols-2 bg-white dark:bg-gray-900 p-4 md:p-8 text-gray-900 dark:text-white,以及 hidden dark:md:block。
- 触控友好:交互元素至少 min-h-11 min-w-11(44px),导航链接 block py-3 px-4 min-h-11,按钮之间用 flex gap-3 保持间距(WCAG 2.2 最低 24x24px,推荐 44x44px)。
- 流式排版消除断点跳变:在 @theme 定义 --text-fluid-base: clamp(1rem, 0.9rem + 0.5vw, 1.25rem)、--text-fluid-lg、--text-fluid-xl,使用 text-fluid-xl、text-fluid-base。
- 使用语义化深色模式颜色令牌:--color-surface、--color-surface-dark、--color-on-surface、--color-on-surface-dark,而不是直接使用原始颜色。
- 开发期用 debug-screens 插件测试所有断点:npm install -D @tailwindcss/debug-screens,然后 @plugin "@tailwindcss/debug-screens"。
- 用组件类减少重复:在 @layer components 中定义 .card { @apply bg-white dark:bg-gray-800 rounded-lg p-6 shadow-sm; } 与 .section { @apply py-12 md:py-16 lg:py-24; }。
- 保证两种模式下的对比度(WCAG 2.2):普通文本至少 4.5:1,大文本(18pt+)至少 3:1,交互元素与相邻颜色至少 3:1;按钮加 focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2。
- 尊重减少动效偏好:加 motion-reduce:transition-none motion-reduce:hover:scale-100,与 transition-transform duration-300 hover:scale-105 搭配。
- 响应式图片性能优化:首屏以下图片加 loading="lazy" 与 class="w-full h-auto";用 srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w" 与 sizes="(min-width: 1024px) 50vw, 100vw"。
- 刘海屏安全区:定义 @utility safe-area-pb { padding-bottom: env(safe-area-inset-bottom); },在固定底部导航上使用 safe-area-pb。
适用边界 · 注意事项
- 项目未使用 Tailwind CSS v4 或无法使用 @theme/@custom-variant/@plugin 语法时,本经验的配置写法不适用。
- 需要支持不支持 prefers-color-scheme、CSS 变量或容器查询的旧浏览器时,相关深色模式与容器查询方案会失效。
- 使用 next-themes 的方案仅适用于 Next.js 项目,其他框架需改用原生 classList/localStorage 切换。