核心理念
理解 Tailwind CSS 的核心理念是高效使用它的关键。本章将深入讲解功能类优先的设计思想和 Tailwind 的工作方式。
功能类优先
Tailwind CSS 的核心思想是"功能类优先"(Utility-First)。这意味着你应该使用小型的、单一目的的工具类来构建界面,而不是编写自定义 CSS。
传统方式 vs Tailwind 方式
传统方式: 先定义 CSS 类,然后在 HTML 中使用
<style>
.notification {
background-color: white;
border-radius: 8px;
padding: 16px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
gap: 16px;
max-width: 400px;
margin: 0 auto;
}
.notification-icon {
width: 48px;
height: 48px;
flex-shrink: 0;
}
.notification-title {
font-size: 18px;
font-weight: 600;
color: #1f2937;
}
.notification-text {
color: #6b7280;
margin-top: 4px;
}
</style>
<div class="notification">
<img class="notification-icon" src="icon.svg" alt="">
<div>
<div class="notification-title">通知标题</div>
<p class="notification-text">这是通知的内容描述</p>
</div>
</div>
Tailwind 方式: 直接在 HTML 中使用工具类
<div class="mx-auto flex max-w-sm items-center gap-4 rounded-lg bg-white p-4 shadow-md">
<img class="size-12 shrink-0" src="icon.svg" alt="">
<div>
<div class="text-lg font-semibold text-gray-800">通知标题</div>
<p class="mt-1 text-gray-500">这是通知的内容描述</p>
</div>
</div>
功能类优先的优势
开发速度快:不需要在 HTML 和 CSS 文件之间来回切换,也不需要思考类名。样式直接写在元素上,所见即所得。
修改更安全:每个工具类只影响当前元素,修改样式不会意外影响其他页面或组件。
维护更容易:六个月后回来维护代码,不需要回忆当初写的 CSS 是什么意思,直接看类名就明白。
代码更便携:结构和样式在同一个地方,复制粘贴组件时不会遗漏样式。
CSS 不会无限增长:工具类是可复用的,项目变大不会导致 CSS 文件线性增长。
命名约定
Tailwind CSS 的类名遵循一致的命名约定,掌握规律后很容易记忆。
基本格式
大多数工具类遵循 属性-值 的格式:
| 类名 | CSS 属性 | 值 |
|---|---|---|
text-center | text-align | center |
font-bold | font-weight | bold |
bg-white | background-color | white |
p-4 | padding | 1rem |
m-2 | margin | 0.5rem |
数值比例
间距、尺寸等使用数值比例系统:
<div class="p-1">padding: 0.25rem (4px)</div>
<div class="p-2">padding: 0.5rem (8px)</div>
<div class="p-4">padding: 1rem (16px)</div>
<div class="p-6">padding: 1.5rem (24px)</div>
<div class="p-8">padding: 2rem (32px)</div>
比例系统基于 4px 的基础单位,数值越大,间距越大。
方向修饰符
可以使用方向修饰符指定特定方向:
<div class="p-4">四个方向</div>
<div class="px-4">左右方向</div>
<div class="py-4">上下方向</div>
<div class="pt-4">上方</div>
<div class="pr-4">右侧</div>
<div class="pb-4">下方</div>
<div class="pl-4">左侧</div>
方向修饰符规则:
t= top(上)r= right(右)b= bottom(下)l= left(左)x= 水平方向(左右)y= 垂直方向(上下)
常用工具类概览
布局类
<div class="flex">display: flex</div>
<div class="grid">display: grid</div>
<div class="block">display: block</div>
<div class="hidden">display: none</div>
<div class="flex items-center justify-center">
Flexbox 居中布局
</div>
<div class="grid grid-cols-3 gap-4">
三列网格布局
</div>
尺寸类
<div class="w-full">width: 100%</div>
<div class="w-1/2">width: 50%</div>
<div class="w-64">width: 16rem</div>
<div class="h-screen">height: 100vh</div>
<div class="max-w-md">max-width: 28rem</div>
间距类
<div class="p-4">内边距 1rem</div>
<div class="m-4">外边距 1rem</div>
<div class="gap-4">间隙 1rem</div>
<div class="space-y-4">子元素垂直间距</div>
文字类
<p class="text-sm">小号文字</p>
<p class="text-lg">大号文字</p>
<p class="text-2xl">超大号文字</p>
<p class="font-bold">粗体文字</p>
<p class="text-center">居中文字</p>
<p class="text-gray-500">灰色文字</p>
背景和边框
<div class="bg-white">白色背景</div>
<div class="bg-blue-500">蓝色背景</div>
<div class="border">1px 边框</div>
<div class="border-2">2px 边框</div>
<div class="rounded">圆角</div>
<div class="rounded-lg">大圆角</div>
<div class="rounded-full">完全圆形</div>
组合使用
Tailwind 的强大之处在于组合多个工具类创建复杂组件。
按钮示例
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
基础按钮
</button>
<button class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded">
轮廓按钮
</button>
<button class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded-full">
圆形按钮
</button>
卡片示例
<div class="max-w-sm rounded overflow-hidden shadow-lg bg-white">
<img class="w-full" src="/img/card-top.jpg" alt="图片">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">卡片标题</div>
<p class="text-gray-700 text-base">
这是卡片的描述内容,可以包含多行文字。
</p>
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
标签1
</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
标签2
</span>
</div>
</div>
处理重复样式
使用 Tailwind 时,你可能会遇到重复的类组合。有几种处理方式:
使用组件抽象
在 React、Vue 等框架中,可以创建组件来封装重复的样式:
function Button({ children, variant = 'primary' }) {
const baseClasses = 'font-bold py-2 px-4 rounded'
const variants = {
primary: 'bg-blue-500 hover:bg-blue-700 text-white',
secondary: 'bg-gray-500 hover:bg-gray-700 text-white',
outline: 'bg-transparent border border-blue-500 text-blue-500 hover:bg-blue-500 hover:text-white',
}
return (
<button className={`${baseClasses} ${variants[variant]}`}>
{children}
</button>
)
}
使用 @apply 指令
在 CSS 文件中使用 @apply 提取重复的类:
@layer components {
.btn {
@apply font-bold py-2 px-4 rounded;
}
.btn-primary {
@apply bg-blue-500 hover:bg-blue-700 text-white;
}
}
优先使用组件抽象,@apply 仅在必要时使用。Tailwind 官方推荐保持工具类的使用方式。
状态变体
Tailwind 的一个核心特性是可以通过变体(variants)来控制样式应用的条件。
悬停和焦点状态
使用 hover: 和 focus: 前缀为元素添加交互状态样式:
<!-- 悬停状态 -->
<button class="bg-sky-500 hover:bg-sky-700">
悬停时变深
</button>
<!-- 焦点状态 -->
<input class="border-gray-300 focus:border-blue-500 focus:ring-2">
聚焦时显示蓝色边框
</input>
变体的工作原理:每个变体只做一件事——在特定条件下应用样式。这与传统 CSS 不同,传统方式通常在一个类中定义多个状态:
<!-- 传统 CSS 方式 -->
<style>
.btn {
background-color: #0ea5e9;
}
.btn:hover {
background-color: #0284c7;
}
</style>
<!-- Tailwind 方式:分离关注 -->
<button class="bg-sky-500 hover:bg-sky-700">
保存更改
</button>
生成的 CSS 如下,注意样式只在悬停时生效:
.bg-sky-500 {
background-color: var(--color-sky-500);
}
.hover\:bg-sky-700:hover {
background-color: var(--color-sky-700);
}
变体堆叠
可以组合多个变体来创建复杂条件:
<!-- 悬停且禁用时的样式 -->
<button class="bg-blue-500 disabled:hover:bg-blue-500 opacity-50">
特殊状态
</button>
<!-- 深色模式下悬停 -->
<a class="text-gray-600 dark:hover:text-white">
链接
</a>
常用状态变体
| 变体 | 触发条件 | 示例 |
|---|---|---|
hover: | 鼠标悬停 | hover:bg-blue-500 |
focus: | 元素聚焦 | focus:ring-2 |
active: | 元素被激活(点击) | active:scale-95 |
disabled: | 元素禁用 | disabled:opacity-50 |
first: | 父元素的第一个子元素 | first:mt-0 |
last: | 父元素的最后一个子元素 | last:mb-0 |
odd: | 奇数位置子元素 | odd:bg-gray-100 |
even: | 偶数位置子元素 | even:bg-gray-50 |
checked: | 复选框/单选框选中 | checked:bg-blue-500 |
响应式设计理念
移动优先原则
Tailwind 采用移动优先(Mobile-First)的断点系统。这意味着:
- 无前缀的工具类在所有屏幕尺寸生效
- 带断点前缀的工具类只在指定断点及以上生效
<!-- 正确理解移动优先 -->
<div class="text-center sm:text-left">
移动端居中,sm 及以上屏幕左对齐
</div>
<!-- 常见错误:sm 不是"小屏幕" -->
<div class="sm:text-center">
错误!这只在 640px 及以上居中,小屏幕无样式
</div>
断点系统
Tailwind 默认提供五个断点:
| 前缀 | 最小宽度 | 典型设备 |
|---|---|---|
sm: | 640px | 大手机/小平板 |
md: | 768px | 平板电脑 |
lg: | 1024px | 笔记本电脑 |
xl: | 1280px | 桌面显示器 |
2xl: | 1536px | 大屏幕显示器 |
断点范围控制:
使用 max-* 变体限制样式在特定断点以下生效:
<!-- 只在 md 断点以下生效 -->
<div class="flex max-md:flex-col">
中等屏幕以下垂直排列
</div>
<!-- 只在 md 到 lg 之间生效 -->
<div class="hidden md:max-lg:block">
仅中等屏幕可见
</div>
响应式最佳实践
<!-- 推荐:从移动端样式开始,逐步添加大屏样式 -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
响应式网格
</div>
<!-- 不推荐:试图"只在小屏幕生效" -->
<div class="sm:hidden">
这种写法表示"640px及以上隐藏"
</div>
<!-- 正确写法:小屏幕显示,大屏幕隐藏 -->
<div class="block sm:hidden">
仅小屏幕可见
</div>
暗黑模式
Tailwind 内置了对暗黑模式的完整支持。
基本使用
使用 dark: 前缀为暗黑模式定义样式:
<div class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white">
<p class="text-gray-600 dark:text-gray-300">
自适应主题的文字
</p>
</div>
暗黑模式的触发方式
方式一:跟随系统偏好(默认)
<!-- 自动跟随操作系统的深色模式 -->
<html class="dark">
方式二:手动切换
// 通过 JavaScript 切换
document.documentElement.classList.toggle('dark')
方式三:CSS 配置
/* 使用 CSS 变量控制 */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *)) {
@slot;
}
暗黑模式最佳实践
<!-- 完整的暗黑模式组件 -->
<div class="bg-white dark:bg-gray-900 rounded-lg shadow-lg dark:shadow-none p-6">
<h3 class="text-gray-900 dark:text-white font-bold">
标题
</h3>
<p class="text-gray-600 dark:text-gray-400">
这是一段描述文字,会根据主题自动切换颜色。
</p>
<button class="mt-4 bg-blue-500 hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700 text-white px-4 py-2 rounded">
按钮
</button>
</div>
任意值
当需要使用主题之外的值时,可以使用方括号语法指定任意值。
基本语法
<!-- 任意颜色 -->
<button class="bg-[#1da1f2] text-white">
Facebook 蓝
</button>
<!-- 任意尺寸 -->
<div class="w-[320px] h-[240px]">
固定尺寸
</div>
<!-- 任意间距 -->
<div class="mt-[13px] mb-[27px]">
精确间距
</div>
主题值引用
在任意值中引用主题变量:
<!-- 使用主题颜色 -->
<div class="bg-[var(--color-blue-500)]">
引用主题变量
</div>
<!-- 使用 calc 计算 -->
<div class="max-h-[calc(100vh-4rem)]">
计算高度
</div>
<!-- 使用主题间距函数 -->
<div class="p-[--spacing(8)]">
使用主题间距
</div>
任意属性
使用 [属性名:值] 语法设置任意 CSS 属性:
<!-- 设置 CSS 变量 -->
<div class="[--gutter:1rem]">
定义变量
</div>
<!-- 任意 CSS 属性 -->
<div class="[mask-image:url('gradient.png')]">
遮罩效果
</div>
任意值最佳实践
<!-- 不推荐:复杂值难以阅读 -->
<div class="grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
</div>
<!-- 推荐:使用内联样式或自定义 CSS -->
<div style="grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))">
更清晰的复杂样式
</div>
样式冲突处理
当多个工具类设置相同的 CSS 属性时,需要理解如何处理冲突。
冲突规则
后定义的类优先:当两个类设置同一属性时,CSS 文件中后出现的生效:
<!-- grid 会覆盖 flex,因为它在 CSS 中后出现 -->
<div class="flex grid">
这是网格布局
</div>
生成的 CSS 顺序:
.flex { display: flex; }
.grid { display: grid; } /* 后出现,优先级更高 */
避免冲突
最佳做法是不要添加冲突的类,而是根据条件选择正确的类:
// React 示例
function Layout({ useGrid }) {
return (
<div className={useGrid ? 'grid' : 'flex'}>
{/* 内容 */}
</div>
);
}
重要修饰符
需要强制覆盖时,可以在类名末尾添加 !:
<!-- bg-red-500! 会覆盖 bg-teal-500 -->
<div class="bg-teal-500 bg-red-500!">
强制红色背景
</div>
生成的 CSS:
.bg-teal-500 {
background-color: var(--color-teal-500);
}
.bg-red-500\! {
background-color: var(--color-red-500) !important;
}
!important只在确实需要覆盖第三方样式或无法控制的高优先级选择器时使用。过度使用会破坏 CSS 的可维护性。
全局重要标志
导入 Tailwind 时设置 important 标志,使所有工具类都带 !important:
@import "tailwindcss" important;
这在与现有高优先级 CSS 集成时非常有用。
类组合技术
多类组合
Tailwind 使用 CSS 变量实现多个类的组合效果:
<!-- 多个滤镜效果组合 -->
<div class="blur-sm grayscale">
模糊 + 灰度
</div>
生成的 CSS 原理:
.blur-sm {
--tw-blur: blur(var(--blur-sm));
filter: var(--tw-blur,) var(--tw-grayscale,);
}
.grayscale {
--tw-grayscale: grayscale(100%);
filter: var(--tw-blur,) var(--tw-grayscale,);
}
每个类设置自己的 CSS 变量,最终的 filter 属性组合所有变量。这种模式也用于:
- 渐变颜色
- 阴影颜色
- 变换效果
复杂选择器
使用任意变体创建复杂选择器:
<!-- 父元素悬停时子元素样式 -->
<div class="group">
<span class="group-hover:underline">
悬停父元素时下划线
</span>
</div>
<!-- 兄弟元素选择器 -->
<div>
<span data-active></span>
<span class="[&>[data-active]+span]:text-blue-600">
紧跟 data-active 后的 span 变蓝
</span>
</div>
组件抽象策略
循环渲染
当重复元素通过循环渲染时,类列表只写一次:
// React 示例
function AvatarList({ users }) {
return (
<div class="flex -space-x-2">
{users.map(user => (
<img
key={user.id}
class="inline-block h-12 w-12 rounded-full ring-2 ring-white"
src={user.avatar}
alt={user.name}
/>
))}
</div>
);
}
多光标编辑
对于同一文件内的重复,使用编辑器的多光标功能:
<!-- 使用 Alt+Click 或 Ctrl+D 选择多个相同类列表 -->
<nav class="flex justify-center space-x-4">
<a href="#" class="px-3 py-2 rounded-lg font-medium text-gray-700 hover:bg-gray-100">
首页
</a>
<a href="#" class="px-3 py-2 rounded-lg font-medium text-gray-700 hover:bg-gray-100">
产品
</a>
<a href="#" class="px-3 py-2 rounded-lg font-medium text-gray-700 hover:bg-gray-100">
关于
</a>
</nav>
组件封装
对于跨文件复用的样式,创建组件:
// React 组件封装
export function Button({ variant = 'primary', size = 'md', children }) {
const baseClasses = 'font-medium rounded-lg transition-colors';
const variants = {
primary: 'bg-blue-500 hover:bg-blue-600 text-white',
secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-900',
outline: 'border-2 border-blue-500 text-blue-500 hover:bg-blue-50',
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
return (
<button className={`${baseClasses} ${variants[variant]} ${sizes[size]}`}>
{children}
</button>
);
}
自定义 CSS(传统方式)
对于简单场景,可以编写自定义 CSS:
<button class="btn-primary">保存</button>
@import "tailwindcss";
@layer components {
.btn-primary {
border-radius: calc(infinity * 1px);
background-color: var(--color-violet-500);
padding-inline: --spacing(5);
padding-block: --spacing(2);
font-weight: var(--font-weight-semibold);
color: var(--color-white);
&:hover {
@media (hover: hover) {
background-color: var(--color-violet-700);
}
}
}
}
Tailwind CSS v4.0 的核心理念更新
v4.0 在核心理念上带来了一些重要变化:
CSS-first 配置
不再需要 JavaScript 配置文件,直接在 CSS 中配置:
@import "tailwindcss";
@theme {
--font-display: "Satoshi", sans-serif;
--color-brand-500: oklch(0.7 0.15 250);
--breakpoint-xs: 30rem;
}
原生 CSS 变量
所有设计令牌自动暴露为 CSS 变量:
:root {
--color-blue-500: oklch(0.7 0.15 250);
--font-family-sans: Inter, sans-serif;
--spacing: 0.25rem;
}
在任意地方使用:
<div style="background-color: var(--color-blue-500)">
使用主题变量
</div>
动态值支持
间距和尺寸工具类现在动态生成,无需预定义:
<!-- 无需在主题中定义 17 -->
<div class="p-17 mt-29 w-42">
动态间距和尺寸
</div>
小结
本章深入讲解了 Tailwind CSS 的核心理念:
设计思想
- 功能类优先:使用小型、单一目的的工具类构建界面
- 分离关注:每个类只做一件事,在特定条件下生效
- 移动优先:从小屏幕样式开始,逐步增强大屏体验
技术机制
- 状态变体:hover、focus、active 等条件前缀
- 响应式断点:sm、md、lg、xl、2xl 断点系统
- 暗黑模式:dark: 前缀实现主题切换
- 任意值:方括号语法突破主题限制
最佳实践
- 避免冲突:不添加冲突的类,根据条件选择
- 组件封装:循环、多光标、组件抽象处理重复
- 慎用 important:只在必要时使用强制覆盖
v4.0 新特性
- CSS-first 配置:直接在 CSS 中定义主题
- 原生 CSS 变量:设计令牌全局可用
- 动态值:间距和尺寸类按需生成
下一章,我们将学习 Tailwind CSS 的布局系统,包括 Flexbox、Grid 和容器查询等现代布局技术。