Tailwind CSS 是一个实用优先(utility-first)的 CSS 框架,由 Adam Wathan 和 Tailwind Labs 团队创建。与 Bootstrap 等传统框架不同,Tailwind 不提供预设组件(如按钮、卡片),而是提供大量低级别的工具类(utility classes),让你直接在 HTML 中通过组合类名来构建任意设计。
Tailwind 的核心理念是:约束驱动的设计。通过一套精心设计的设计令牌(design tokens)——间距、颜色、字号、阴影等——确保整个项目的视觉一致性,同时保留完全的自定义能力。它作为 PostCSS 插件运行,在构建时生成最终 CSS,只包含你实际使用的样式,产物极小。
| 项目信息 | 详情 |
|---|---|
| 开发团队 | Tailwind Labs(Adam Wathan 等) |
| GitHub Stars | 87,000+ |
| 官方网站 | tailwindcss.com |
| 开源协议 | MIT License |
| 技术实现 | PostCSS 插件 / Rust(v4 Oxide 引擎) |
| 最新版本 | v4.x(Oxide 引擎,零配置) |
| 安装方式 | npm / Vite 插件 / CLI / CDN |
flex items-center gap-4 bg-blue-500 text-white rounded-lg p-4 这样的类名来直接表达样式,无需写任何自定义 CSS。
| 对比维度 | Tailwind CSS | Bootstrap | UnoCSS | CSS Modules |
|---|---|---|---|---|
| 设计理念 | 实用优先,原子化类名 | 组件优先,预设 UI 套件 | 即时按需,引擎驱动 | 局部作用域,模块化 |
| 学习曲线 | 中等(需记类名) | 低(文档组件直接复制) | 中等(兼容 Tailwind 语法) | 低(就是写 CSS) |
| 自定义能力 | 极强(完全可定制设计令牌) | 有限(覆盖变量 + 自定义 Sass) | 极强(可自定义规则引擎) | 完全自由(手写 CSS) |
| 产物体积 | 极小(Tree-shaking 只保留用到的) | 较大(即使只用部分组件) | 极小(按需生成) | 取决于手写量 |
| 开发速度 | 极快(无需切换文件) | 快(组件复制粘贴) | 极快(同 Tailwind) | 较慢(需写独立 CSS 文件) |
| 组件生态 | 第三方(Headless UI, daisyUI, shadcn/ui) | 官方内置丰富组件 | 较少 | 无 |
| 构建工具 | PostCSS 插件 / Vite 插件 | Sass 编译 | Vite 插件 / Webpack | CSS Loader / Vite 内置 |
| HTML 可读性 | 类名较长 | 语义化类名 | 类名较长(同 Tailwind) | 简洁类名 |
| 暗黑模式 | 内置 dark: 前缀 | v5.3+ 支持 | 内置支持 | 需手写 |
| 适用场景 | 高度定制化项目、设计系统 | 快速原型、管理后台 | 追求极致性能、Vite 项目 | 中大型团队协作、严格隔离 |
# 创建 Vite 项目
npm create vite@latest my-app -- --template react
cd my-app
# 安装 Tailwind CSS
npm install tailwindcss @tailwindcss/vite
# 在 vite.config.js 中添加插件
import tailwindcss from '@tailwindcss/vite'
export default {
plugins: [tailwindcss()]
}
在主 CSS 文件中导入 Tailwind:
/* src/index.css */ @import "tailwindcss";然后就可以在 HTML/JSX 中使用 Tailwind 类名了:
<div class="flex items-center gap-4 p-6 bg-white rounded-xl shadow-lg"> <h2 class="text-xl font-bold text-gray-900">Hello Tailwind!</h2> <p class="text-gray-500">快速上手,即刻体验</p> </div>
# 创建 Next.js 项目(会自动询问是否使用 Tailwind) npx create-next-app@latest my-app # 如果已有项目,手动安装 npm install tailwindcss @tailwindcss/postcss postcss配置 PostCSS:
/* app/globals.css */ @import "tailwindcss";
# 安装 Tailwind CLI npm install tailwindcss @tailwindcss/cli # 创建输入 CSS 文件 echo '@import "tailwindcss";' > src/input.css # 编译输出 npx @tailwindcss/cli -i src/input.css -o dist/output.css --watch在 HTML 中引用编译后的 CSS:
<link href="/dist/output.css" rel="stylesheet">
tailwind.config.js,直接在 CSS 中使用 @theme 指令配置。如果你的项目仍在使用 v3,请参考 官方迁移指南。
/* style.css */
.chat-notification {
display: flex;
align-items: center;
max-width: 24rem;
padding: 1.5rem;
border-radius: 0.5rem;
background-color: #fff;
box-shadow: 0 20px 25px -5px rgba(0,0,0,.1);
}
Tailwind 方式:
<div class="flex items-center max-w-sm p-6 rounded-lg bg-white shadow-xl"> ... </div>好处:无需离开 HTML、无需为类起名、CSS 文件不再膨胀、修改样式不用担心影响其他组件。
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <!-- 手机 1 列,平板 2 列,桌面 3 列 --> </div>默认断点:
sm:640px md:768px lg:1024px xl:1280px 2xl:1536px
<button class="bg-blue-500 hover:bg-blue-700 focus:ring-2 focus:ring-blue-300
active:bg-blue-800 disabled:opacity-50 disabled:cursor-not-allowed
transition-colors duration-200">
点击我
</button>
常用状态前缀:hover: focus: active: disabled: focus-visible: focus-within: group-hover: peer-checked:
dark: 前缀即可为暗黑模式添加样式:
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"> <h2 class="text-xl font-bold">自动适应明暗主题</h2> <p class="text-gray-600 dark:text-gray-400">内容文字</p> </div>Tailwind v4 默认使用
prefers-color-scheme 媒体查询自动跟随系统设置。也可以使用 CSS 自定义属性手动控制:
/* 通过 selector 策略手动控制 */ @custom-variant dark (&:where(.dark, .dark *));
class="dark" 即可手动切换到暗黑模式。
<div class="w-[calc(100%-2rem)] top-[117px] bg-[#1da1f2] grid-cols-[1fr_2fr_1fr]"> 自定义宽度、定位、颜色、网格列 </div>也支持任意属性(v3.1+):
<div class="[mask-type:luminance] [--my-var:12px]">...</div>
以下是 10 组最常用的 Tailwind CSS 类名模式,涵盖布局、排版、颜色、间距等核心场景。
<!-- 水平居中排列 --> <div class="flex items-center justify-center gap-4">...</div> <!-- 两端对齐 --> <div class="flex items-center justify-between">...</div> <!-- 垂直排列 --> <div class="flex flex-col gap-2">...</div> <!-- 换行 --> <div class="flex flex-wrap gap-3">...</div> <!-- 子项占满剩余空间 --> <div class="flex-1">...</div> <div class="flex-none">固定宽度</div> <div class="flex-shrink-0">不收缩</div>关键类:
flex inline-flex items-center items-start items-end justify-center justify-between justify-around gap-{n} flex-col flex-wrap flex-1 flex-none
<!-- 3 列等宽网格 --> <div class="grid grid-cols-3 gap-6">...</div> <!-- 响应式网格 --> <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">...</div> <!-- 自适应列宽(每列至少 250px) --> <div class="grid grid-cols-[repeat(auto-fill,minmax(250px,1fr))] gap-4">...</div> <!-- 跨列 --> <div class="col-span-2">占两列</div> <div class="col-span-full">占整行</div>关键类:
grid grid-cols-{n} grid-rows-{n} gap-{n} col-span-{n} row-span-{n} col-start-{n} place-items-center
<!-- 字号与行高 --> <h1 class="text-4xl font-bold leading-tight">大标题</h1> <p class="text-base leading-relaxed text-gray-600">正文内容</p> <span class="text-sm text-gray-400">辅助说明</span> <!-- 字重 --> <span class="font-light">细体</span> <span class="font-medium">中等</span> <span class="font-bold">粗体</span> <span class="font-extrabold">超粗</span> <!-- 文本处理 --> <p class="truncate">超长文本自动省略...</p> <p class="line-clamp-3">限制最多 3 行</p> <p class="uppercase tracking-wider">大写字母间距</p>字号:
text-xs text-sm text-base text-lg text-xl ... text-9xl
{属性}-{颜色}-{深度}:
<!-- 文本颜色 --> <p class="text-blue-500">蓝色文字</p> <p class="text-gray-900 dark:text-gray-100">自适应文字</p> <!-- 背景颜色 --> <div class="bg-gradient-to-r from-purple-500 to-pink-500">渐变背景</div> <div class="bg-black/50">50% 透明度黑色</div> <!-- 边框颜色 --> <div class="border border-gray-200 hover:border-blue-500">...</div> <!-- 环形颜色 --> <input class="focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" />颜色深度:
50 100 200 ... 900 950
slate gray zinc neutral stone red orange amber yellow lime green emerald teal cyan sky blue indigo violet purple fuchsia pink rose
1 = 0.25rem = 4px):
<!-- 内边距 --> <div class="p-4">四周 16px</div> <div class="px-6 py-3">水平 24px,垂直 12px</div> <div class="pt-8 pb-4 pl-6 pr-6">分别设置</div> <!-- 外边距 --> <div class="m-4">四周 16px</div> <div class="mx-auto">水平居中</div> <div class="mt-8 mb-4">上下不同</div> <div class="-mt-4">负外边距</div> <!-- 间距速查 --> <!-- 0=0, 1=4px, 2=8px, 3=12px, 4=16px, 5=20px, 6=24px, 8=32px, 10=40px, 12=48px, 16=64px -->
<!-- 边框 --> <div class="border">1px 边框</div> <div class="border-2 border-blue-500">2px 蓝色边框</div> <div class="border-b border-gray-200">仅底部边框</div> <div class="divide-y divide-gray-200">子元素之间加分割线</div> <!-- 圆角 --> <div class="rounded">小圆角(4px)</div> <div class="rounded-lg">中圆角(8px)</div> <div class="rounded-xl">大圆角(12px)</div> <div class="rounded-full">完全圆形</div> <div class="rounded-t-lg rounded-b-none">仅上方圆角</div>圆角:
rounded-none rounded-sm rounded rounded-md rounded-lg rounded-xl rounded-2xl rounded-3xl rounded-full
<!-- 阴影 --> <div class="shadow-sm">微阴影</div> <div class="shadow">默认阴影</div> <div class="shadow-md">中等阴影</div> <div class="shadow-lg">大阴影</div> <div class="shadow-xl">超大阴影</div> <div class="shadow-2xl">最大阴影</div> <div class="shadow-inner">内阴影</div> <!-- 透明度 --> <div class="opacity-50">50% 透明度</div> <div class="bg-black/25">25% 透明度背景</div> <div class="text-white/80">80% 透明度文字</div>
<!-- 过渡 -->
<button class="transition-colors duration-200 ease-in-out
bg-blue-500 hover:bg-blue-700">
平滑变色
</button>
<div class="transition-all duration-300 hover:scale-105 hover:shadow-lg">
悬停放大 + 阴影
</div>
<!-- 内置动画 -->
<div class="animate-spin">旋转加载</div>
<div class="animate-ping">脉冲效果</div>
<div class="animate-pulse">呼吸闪烁</div>
<div class="animate-bounce">弹跳效果</div>
过渡属性:transition transition-all transition-colors transition-opacity transition-shadow transition-transform
duration-75 duration-100 duration-150 duration-200 duration-300 duration-500 duration-700 duration-1000
<!-- 缩放 --> <div class="hover:scale-105">悬停放大 5%</div> <div class="scale-75">缩小到 75%</div> <!-- 旋转 --> <div class="rotate-45">旋转 45 度</div> <div class="hover:-rotate-6">悬停反向旋转</div> <!-- 平移 --> <div class="translate-x-4">右移 16px</div> <div class="hover:-translate-y-1">悬停上移</div> <!-- 倾斜 --> <div class="skew-x-6">水平倾斜</div> <!-- 变换原点 --> <div class="origin-top-left rotate-12">以左上角为原点旋转</div>
<!-- 模糊 --> <div class="blur-sm">轻微模糊</div> <div class="blur-md">中等模糊</div> <!-- 背景模糊(毛玻璃效果) --> <div class="backdrop-blur-md bg-white/30"> 毛玻璃效果 </div> <!-- 亮度/对比度/饱和度 --> <img class="brightness-110 contrast-125 saturate-150" /> <img class="grayscale hover:grayscale-0 transition-all" /> <!-- 投影(适合 PNG 图片/图标) --> <img class="drop-shadow-lg" /> <svg class="drop-shadow-md" />
| 前缀 | 最小宽度 | 对应设备 |
|---|---|---|
sm: | 640px | 大屏手机(横屏) |
md: | 768px | 平板 |
lg: | 1024px | 小桌面 / 大平板 |
xl: | 1280px | 桌面 |
2xl: | 1536px | 大桌面 |
<nav class="flex flex-col sm:flex-row items-center justify-between p-4">
<div class="text-xl font-bold">Logo</div>
<div class="flex gap-4 mt-4 sm:mt-0">
<a class="text-gray-600 hover:text-gray-900">首页</a>
<a class="text-gray-600 hover:text-gray-900">关于</a>
<a class="text-gray-600 hover:text-gray-900">联系</a>
</div>
</nav>
响应式卡片网格:
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 p-6">
<div class="bg-white rounded-xl shadow-md p-6 hover:shadow-lg transition-shadow">
<h3 class="text-lg font-semibold mb-2">卡片标题</h3>
<p class="text-gray-500 text-sm">卡片内容</p>
</div>
<!-- 更多卡片 -->
</div>
响应式文字大小:
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold"> 响应式标题 </h1>响应式隐藏/显示:
<div class="hidden md:block">桌面端显示</div> <div class="block md:hidden">移动端显示</div>
@theme 自定义断点:
@theme {
--breakpoint-xs: 475px;
--breakpoint-3xl: 1800px;
}
容器查询(Container Queries)— 基于父容器尺寸而非视口:
<div class="@container">
<div class="flex flex-col @md:flex-row gap-4">
<!-- 当容器宽度 >= 28rem 时变为横向排列 -->
</div>
</div>
容器断点前缀:@sm @md @lg @xl 等。
sm: md: lg: 逐步增强。避免反向思维(先设计桌面端再用 max-* 覆盖),那样会让样式更难维护。
@import "tailwindcss";
@theme {
/* 自定义颜色 */
--color-primary: #4361ee;
--color-primary-light: #6b83f2;
--color-primary-dark: #2b45c1;
/* 自定义字体 */
--font-sans: "Inter", "Noto Sans SC", sans-serif;
--font-mono: "JetBrains Mono", monospace;
/* 自定义间距 */
--spacing-18: 4.5rem;
--spacing-88: 22rem;
/* 自定义断点 */
--breakpoint-xs: 475px;
/* 自定义阴影 */
--shadow-soft: 0 2px 15px -3px rgba(0, 0, 0, 0.07),
0 10px 20px -2px rgba(0, 0, 0, 0.04);
/* 自定义动画 */
--animate-fade-in: fade-in 0.5s ease-out;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
使用:bg-primary text-primary-dark font-sans shadow-soft animate-fade-in
| 插件 | 用途 | 安装 |
|---|---|---|
@tailwindcss/typography | 为 Markdown/CMS 内容自动排版(prose 类) | npm i @tailwindcss/typography |
@tailwindcss/forms | 美化原生表单元素的默认样式 | npm i @tailwindcss/forms |
@tailwindcss/container-queries | 容器查询支持 | npm i @tailwindcss/container-queries |
daisyUI | 基于 Tailwind 的组件库(按钮、卡片、模态框等) | npm i daisyui |
tailwind-merge | 智能合并 Tailwind 类名,解决冲突 | npm i tailwind-merge |
clsx / cva | 条件类名拼接与变体管理 | npm i clsx class-variance-authority |
<article class="prose prose-lg dark:prose-invert max-w-none"> <!-- Markdown 渲染的 HTML 内容,自动获得优美排版 --> <h2>标题自动样式</h2> <p>段落自动间距和字号</p> <pre><code>代码块自动样式</code></pre> </article>
@apply 提取为自定义类:
/* 自定义 CSS 文件 */
@import "tailwindcss";
@layer components {
.btn-primary {
@apply px-4 py-2 bg-blue-500 text-white rounded-lg
hover:bg-blue-700 focus:ring-2 focus:ring-blue-300
transition-colors duration-200 font-medium;
}
.card {
@apply bg-white rounded-xl shadow-md p-6
hover:shadow-lg transition-shadow;
}
.input-field {
@apply w-full px-3 py-2 border border-gray-300 rounded-md
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent;
}
}
@apply,因为它违背了实用优先的理念。优先考虑使用组件框架(React/Vue 组件)来复用样式,只在确实需要全局复用的基础样式时使用 @apply。
以下是使用 Tailwind CSS 过程中最常见的 50 个问题及其解决方案,按类别分组。
@import "tailwindcss";(v4)或 @tailwind base; @tailwind components; @tailwind utilities;(v3)
tailwind.config.js 中 content 路径是否正确覆盖所有模板文件
content 路径正确:
// tailwind.config.js
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx,vue,html}",
"./components/**/*.{js,ts,jsx,tsx}",
],
}
注意:路径是 glob 模式,不要遗漏文件扩展名。v4 自动检测无需手动配置。
npm install postcss@latest autoprefixer@latest tailwindcss@latest如果项目有其他 PostCSS 插件,检查它们是否兼容 PostCSS 8。某些旧版插件需要更新。
@tailwindcss/vite 插件而不是 PostCSS 方式:
// vite.config.js
import tailwindcss from '@tailwindcss/vite'
export default {
plugins: [tailwindcss()]
}
v3 用户:确保 postcss.config.js 正确配置,且 Vite 能找到它(放在项目根目录)。
@import "tailwindcss" layer(utilities); 只导入工具类
corePlugins: { preflight: false }
@tailwindcss/vite
@tailwindcss/postcss
@tailwindcss/cli
tailwind.config.js 改为 tailwind.config.ts
npm install -D @types/tailwindcss
tsconfig.json 中添加 "allowJs": true
// 根目录 tailwind.config.js
content: [
"./apps/**/*.{js,ts,jsx,tsx}",
"./packages/ui/**/*.{js,ts,jsx,tsx}",
]
v4 自动检测项目中所有导入的文件,通常不需要额外配置。如果仍有问题,检查是否有 .gitignore 排除了依赖目录。
@tailwind base/components/utilities 替换为 @import "tailwindcss"
tailwind.config.js 中的配置迁移到 CSS 的 @theme 指令
npx @tailwindcss/upgrade
@import "tailwindcss"
className),在 VS Code 设置中添加:
"tailwindCSS.classAttributes": ["class", "className", "ngClass"]
tailwind-merge 库自动解决冲突:
import { twMerge } from 'tailwind-merge'
twMerge('p-4 p-6') // => 'p-6'
<!-- 全屏居中 --> <div class="flex items-center justify-center min-h-screen"> <div>居中内容</div> </div> <!-- 或使用 Grid(更简洁) --> <div class="grid place-items-center min-h-screen"> <div>居中内容</div> </div>
container 默认不居中,需要手动添加 mx-auto:
<div class="container mx-auto px-4">...</div>或在配置中设置容器默认居中:
@theme {
--container-center: true;
--container-padding: 1rem;
}
truncate 需要配合固定宽度才能生效:
<!-- 单行省略 --> <p class="truncate w-48">很长很长的文本内容...</p> <!-- 多行省略 --> <p class="line-clamp-3"> 限制为 3 行,超出部分显示省略号... </p>确保元素是块级元素且有明确的宽度约束(
w-*、max-w-* 或父容器限制)。
<!-- 正确写法(注意引号) -->
<div class="bg-[url('/images/hero.jpg')] bg-cover bg-center h-96">
</div>
<!-- 如果路径中有特殊字符,使用下划线代替空格 -->
<div class="bg-[url('/images/my_hero.jpg')]"></div>
常见问题:路径不正确、图片不在 public 目录、或缺少 bg-cover 和高度设置。
min-width: auto,长内容会撑开列。解决方法:
<div class="grid grid-cols-3 gap-4">
<div class="min-w-0">
<!-- min-w-0 允许子元素收缩 -->
<p class="truncate">很长的文本...</p>
</div>
</div>
给 grid 子元素添加 min-w-0 或 overflow-hidden 是标准做法。
z-index 只在定位元素上生效。确保同时设置了 position:
<div class="relative z-50">...</div> <!-- 或 --> <div class="sticky top-0 z-50">固定导航栏</div>如果还是不生效,检查是否有层叠上下文(stacking context)的问题 — 父元素的
z-index、transform、opacity 等属性可能创建了新的层叠上下文。
<!-- 基础渐变 --> <div class="bg-gradient-to-r from-blue-500 to-purple-500"></div> <!-- 三色渐变 --> <div class="bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500"></div> <!-- 径向渐变(v4 支持) --> <div class="bg-radial from-blue-500 to-transparent"></div>如果颜色之间过渡不自然,添加
via-* 中间色可以改善。
position: fixed 的支持有历史问题。解决方案:
transform 的父元素内使用 fixed
<div class="fixed bottom-0 inset-x-0 pb-[env(safe-area-inset-bottom)]"> 底部操作栏 </div>3. 考虑使用
sticky 替代 fixed(在合适的场景下)
align-items: stretch,子项会拉伸到等高。如果不等高,检查:
items-start 或 items-center
h-* 固定高度
<!-- 等高卡片 -->
<div class="flex gap-4">
<div class="flex-1 flex flex-col bg-white rounded-lg p-4">
<h3>标题</h3>
<p class="flex-1">内容(flex-1 撑开剩余空间)</p>
<button>操作</button>
</div>
</div>
min-width 媒体查询(移动优先)。md: 表示 768px 及以上。
md: 在 768px 以下生效。
md: 覆盖桌面端样式。
<!-- 正确:先移动,再桌面 --> <div class="flex-col md:flex-row">...</div> <!-- 错误理解:这不是"在 md 以下生效" -->
prefers-color-scheme(跟随系统)。如果要手动切换:
/* 在 CSS 中添加 */ @custom-variant dark (&:where(.dark, .dark *));然后在 HTML 根元素切换
dark 类:
// JavaScript
document.documentElement.classList.toggle('dark')
v3 用户需要在配置中设置 darkMode: 'class'。
max-* 断点,但可以组合使用:
<!-- 方式 1:在大屏覆盖 --> <div class="block md:hidden">仅手机显示</div> <!-- 方式 2:使用 max-* 变体(v3.2+) --> <div class="max-md:text-sm">仅在 md 断点以下生效</div> <!-- 方式 3:区间(v3.2+) --> <div class="md:max-lg:text-center">仅在 md 到 lg 之间居中</div>
<!-- 方式 1:根据模式切换图片 --> <img src="/logo-light.svg" class="dark:hidden" /> <img src="/logo-dark.svg" class="hidden dark:block" /> <!-- 方式 2:使用 CSS 反色/亮度调整 --> <img src="/logo.svg" class="dark:invert dark:brightness-200" /> <!-- 方式 3:使用透明背景 + 颜色适配 --> <img src="/logo.svg" class="dark:opacity-90" />
print: 变体控制打印样式:
<nav class="print:hidden">导航栏(打印时隐藏)</nav> <aside class="print:hidden">侧边栏</aside> <article class="print:text-black print:bg-white print:shadow-none"> <h1 class="print:text-2xl">标题</h1> <p class="print:text-sm print:leading-snug">正文</p> </article>
<!-- 响应式图片基础写法 --> <img src="..." class="w-full h-auto object-cover" /> <!-- 固定宽高比 --> <div class="aspect-video"> <img src="..." class="w-full h-full object-cover rounded-lg" /> </div> <!-- 响应式尺寸 --> <img src="..." class="w-full md:w-1/2 lg:w-1/3 h-auto" />关键类:
object-cover object-contain object-center aspect-square aspect-video
@theme 添加自定义断点:
@theme {
--breakpoint-xs: 475px;
}
v3 通过 tailwind.config.js:
theme: {
screens: {
'xs': '475px',
// ... 保留默认断点
'sm': '640px',
'md': '768px',
'lg': '1024px',
'xl': '1280px',
'2xl': '1536px',
}
}
screens 会替换默认值,使用 extend.screens 来追加。/* 全局 CSS */
@layer base {
:root {
color-scheme: light dark;
}
/* Webkit 浏览器自定义滚动条 */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: #f1f5f9; }
::-webkit-scrollbar-thumb { background: #94a3b8; border-radius: 4px; }
.dark ::-webkit-scrollbar-track { background: #1e293b; }
.dark ::-webkit-scrollbar-thumb { background: #475569; }
}
class="@container"
npm i @tailwindcss/container-queries
<div class="@container">
<div class="flex flex-col @md:flex-row">
<!-- 当容器宽度 >= 28rem 时变为横排 -->
</div>
</div>
.dark .third-party-component {
background: #1e293b;
color: #e2e8f0;
border-color: #334155;
}
3. 使用 color-scheme: dark 让原生控件自动适应
@theme 中是否定义了大量未使用的自定义值
safelist 是否过多
// 错误:Tailwind 无法检测
const color = `text-${props.color}-500`
// 正确:使用完整类名
const colorMap = {
red: 'text-red-500',
blue: 'text-blue-500',
}
// 错误
<div class={`bg-${color}-500`}>
// 正确 — 使用映射对象
const bgColors = {
primary: 'bg-blue-500',
danger: 'bg-red-500',
success: 'bg-green-500',
}
<div class={bgColors[variant]}>
content 扫描范围,排除 node_modules
@tailwindcss/vite 替代 PostCSS 方式
<link> 放在 <head> 中(不要异步加载)
<head> 中添加脚本提前设置主题:
<script>
if (localStorage.theme === 'dark' ||
(!localStorage.theme && matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
}
</script>
transition-all 会监听所有可动画属性的变化,性能开销较大:
transition-colors transition-opacity transition-transform
will-change-transform 提示浏览器优化(谨慎使用)
content-visibility: auto 跳过不可见项
safelist 会强制保留指定类名,即使未在模板中使用:
// 不好:匹配所有颜色的所有深度
safelist: [{ pattern: /^bg-/ }] // 数千个类
// 好:只保留需要的
safelist: ['bg-red-500', 'bg-blue-500', 'bg-green-500']
v4 建议:不使用 safelist,改用完整类名映射对象。
@apply 会将工具类展开为完整 CSS 规则,大量使用会导致产物膨胀。最佳实践:
@apply 只用于真正的全局基础样式(如 .btn、.input)
@layer components 确保正确的层叠顺序
font-display: swap 或 optional
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
next/font(自动优化字体加载)
size-adjust 让备用字体与目标字体大小匹配,减少偏移
// tailwind.config.js (v3)
const colors = require('tailwindcss/colors')
module.exports = {
theme: {
colors: {
// 只保留需要的颜色
white: colors.white,
black: colors.black,
gray: colors.gray,
blue: colors.blue,
red: colors.red,
}
}
}
<img loading="lazy"> 懒加载
<Image> 组件自动优化
currentColor 配合 Tailwind 颜色类
<svg class="w-6 h-6 text-blue-500" fill="currentColor">...</svg>4. 使用
aspect-ratio 类(aspect-video)预留空间避免 CLS
clsx 或 cn(tailwind-merge + clsx)工具函数:
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
function cn(...inputs) {
return twMerge(clsx(inputs))
}
// 使用
<button className={cn(
"px-4 py-2 rounded-lg font-medium transition-colors",
variant === "primary" && "bg-blue-500 text-white hover:bg-blue-700",
variant === "outline" && "border border-gray-300 hover:bg-gray-50",
disabled && "opacity-50 cursor-not-allowed",
className // 允许外部覆盖
)}>
这是 shadcn/ui 等流行组件库的标准做法。
@apply,确保 PostCSS 配置正确
:deep() 穿透子组件:
<style scoped>
:deep(.child-component) {
@apply text-blue-500 font-bold;
}
</style>
app/layout.tsx 中导入:
// app/layout.tsx
import './globals.css' // Tailwind CSS 入口
export default function RootLayout({ children }) {
return (
<html lang="zh-CN">
<body>{children}</body>
</html>
)
}
组件中不要 import 全局 CSS 文件,组件直接使用 Tailwind 类名即可。
@nuxtjs/tailwindcss 模块:
# 安装
npm install -D @nuxtjs/tailwindcss
# nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/tailwindcss'],
})
修改配置后需要重启开发服务器。确认配置文件位置和命名正确(tailwind.config.ts 或 tailwind.config.js)。
/* v4: 只导入 utilities */ @import "tailwindcss/utilities";
// v3: tailwind.config.js
corePlugins: { preflight: false }
2. 使用 prefix 避免类名冲突:
/* v4 */ @import "tailwindcss" prefix(tw); /* 使用: tw:flex tw:p-4 */3. 在组件库样式之后导入 Tailwind
typeof window !== 'undefined')
<head> 中,确保在页面渲染前执行
@astrojs/tailwind 集成:
# 安装 npx astro add tailwind确保
content 配置(v3)包含 .astro 文件:
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}']
v4 + Astro 使用 Vite 插件方式集成。
// .storybook/preview.js
import '../src/index.css' // 你的 Tailwind 入口 CSS
export const parameters = { ... }
确保 Storybook 的构建配置支持 PostCSS,必要时安装 @storybook/addon-postcss。
<style> 标签和 CSS 类名。需要将样式内联:
# Maizzle(Tailwind 邮件框架) npx create-maizzle my-email-project
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from '../tailwind.config'
const { theme } = resolveConfig(tailwindConfig)
// theme.colors.blue[500] === '#3b82f6'
2. 使用 @layer 控制优先级
!important 修饰符:!text-red-500