Tailwind 是流行的原子化 css 框,star 很多,npm下载量也很大。
1 什么是原子化 CSS?
传统的 CSS 写法是定义一个类,然后在类内部写样式,例如:
<div class="text"></div>
.text {
font-size: 16px;
border: 1px solid #000;
padding: 4px;
}
而原子化 CSS 则是将样式细分为多个小的类,每个类只包含一个样式属性,例如:
<div class="text-base p-1 border border-black border-solid"></div>
.text-base {
font-size: 16px;
}
.p-1 {
padding: 4px;
}
.border {
border-width: 1px;
}
.border-black {
border-color: black;
}
.border-solid {
border-style: solid;
}
2 Tailwind 的优势
- 减少命名困扰:不需要为每个样式起名字,直接使用预定义的类名。
- 避免样式重复:相同的样式只需定义一次,避免了重复代码。
- 局部作用域:样式只作用于特定的 HTML 标签,避免全局污染。
3 使用 Tailwind
- 创建项目:
pnpm create vite tailwind-test --template react-ts
cd tailwind-test
pnpm i
pnpm i tailwindcss -D
npx tailwindcss init
- 配置 Tailwind:在 src/index.css 中引入 Tailwind 的基础样式、组件样式和工具样式:
@tailwind base;
@tailwind components;
@tailwind utilities;
这些层级按照上述顺序被应用,这意味着 utilities 中的样式会覆盖 components 中的样式,而 components 中的样式会覆盖 base 中的样式。
- tailwind.config.js:
/** @type {import('tailwindcss').Config} */
export default {
// 指定需要处理的文件
content: ['./src/**/*.{js,ts,jsx,tsx}', './index.html'],
// 主题配置
theme: {
// 扩展默认主题
extend: {}
},
// 插件配置
plugins: []
}
- vite 引入:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from 'tailwindcss'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
css: {
postcss: {
plugins: [tailwindcss]
}
}
})
- 使用 Tailwind 类:
function App() {
return (
<div className="container mx-auto p-8 bg-gray-50">
<h1 className="text-4xl font-bold mb-8 text-indigo-700 text-center">Tailwind CSS 示例</h1>
{/* 文本样式 */}
<Section title="文本样式">
<p className="text-lg text-gray-700 mb-2 leading-relaxed">这是普通文本</p>
<p className="text-xl font-bold text-emerald-600 mb-2">这是粗体绿色文本</p>
<p className="text-sm italic text-purple-600">这是小号斜体紫色文本</p>
</Section>
{/* 背景和边框 */}
<Section title="背景和边框">
<div className="bg-amber-100 p-6 rounded-lg shadow-lg border border-amber-200">
黄色背景,圆角,阴影
</div>
<div className="mt-4 border-2 border-teal-400 p-6 rounded-md">青色边框</div>
</Section>
{/* 弹性布局 */}
<Section title="弹性布局">
<div className="flex justify-between items-center bg-gray-100 p-6 rounded-lg">
{Object.entries(bgColors).map(([color, bgClass], index) => (
<div key={color} className={`${bgClass} text-white p-3 rounded-md shadow-md`}>
项目 {index + 1}
</div>
))}
</div>
</Section>
{/* 响应式设计 */}
<Section title="响应式设计">
<div className="bg-pink-200 p-6 sm:bg-purple-200 md:bg-indigo-200 lg:bg-blue-200 rounded-lg transition-colors duration-300">
这个div在不同屏幕尺寸下会改变背景颜色
</div>
</Section>
{/* 悬停和状态 */}
<Section title="悬停和状态">
<button className="bg-indigo-500 hover:bg-indigo-700 text-white font-bold py-3 px-6 rounded-full transition duration-300 shadow-md hover:shadow-lg">
悬停我
</button>
<input
type="text"
className="mt-4 w-full border-2 border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 rounded-lg p-3 transition duration-300"
placeholder="点击我聚焦"
/>
</Section>
</div>
)
}
// 定义颜色映射对象
const bgColors: Record<string, string> = {
blue: 'bg-blue-500',
green: 'bg-green-500',
red: 'bg-red-500'
}
// 提取可重用的 Section 组件
function Section({ title, children }) {
return (
<section className="mb-12 bg-white p-6 rounded-xl shadow-md">
<h2 className="text-2xl font-semibold mb-6 text-indigo-600 border-b-2 border-indigo-200 pb-2">
{title}
</h2>
{children}
</section>
)
}
export default App
- 运行项目:
pnpm dev
4 配置与扩展
- 修改预定义类:在
tailwind.config.js
中修改配置,例如:
theme: {
extend: {
padding: {
'1': '30px',
},
},
}
使用 p-1
来应用 30px
的内边距。例如:
<div class="p-1">
This div has a padding of 30px on all sides.
</div>
这样设置后,p-1
将不再是默认的 0.25rem
(通常是 4px
),而是 30px
。
- 临时设置值:使用
[]
语法,例如text-[14px]
生成font-size: 14px
的样式。 - 响应式与状态样式:例如
hover:text-[30px]
和md:bg-blue-500
。 - 扩展类:使用
@layer
(指定层级自定义样式) 和@apply
(直接自定义样式) 指令:
// 确保自定义样式与 Tailwind 的默认样式保持一致的优先级和顺序
@layer components {
.custom-component {
// 将预定义的实用工具类bg-blue-500和text-white应用到.custom-component类上。
@apply bg-blue-500 text-white;
}
}
// 在其他地方就可以很方便使用 .custom-button 这个类名应用如下样式
.custom-button {
@apply py-2 px-4 bg-blue-500 text-white rounded;
}
或开发 Tailwind 插件(跨项目复用):
// custom-plugin.js
// 导入 Tailwind CSS 的插件模块
const plugin = require('tailwindcss/plugin');
// 导出插件函数
module.exports = plugin(function({ addUtilities }) {
// 添加自定义的 CSS 工具类
addUtilities({
// 定义 .yun 类,设置背景颜色为蓝色,文字颜色为黄色
'.yun': {
background: 'blue',
color: 'yellow'
},
// 定义 .yun-text 类,设置字体大小为 70px
'.yun-text': {
'font-size': '70px'
}
})
})
上面插件在 tailwind.config.js 里引入后,就可以在使用上面定义的类了:
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{js,ts,jsx,tsx}', './index.html'],
theme: {
extend: {}
},
plugins: [require('./custom-plugin')]
}
除此之外,还可以这样扩展:
module.exports = {
theme: {
extend: {
// 自定义颜色
colors: {
'custom-blue': '#1da1f2',
'custom-green': {
light: '#4ade80',
DEFAULT: '#22c55e',
dark: '#16a34a',
},
},
// 自定义字体大小
fontSize: {
'xxs': '0.625rem',
'2xl+': '1.75rem',
},
// 自定义间距
spacing: {
'72': '18rem',
'84': '21rem',
'96': '24rem',
},
// 自定义断点
screens: {
'xs': '475px',
'3xl': '1600px',
},
},
},
// 自定义变体
variants: {
extend: {
backgroundColor: ['active'],
textColor: ['visited'],
}
},
}
使用:
<div class="container mx-auto p-4">
<!-- 使用自定义颜色 -->
<h1 class="text-4xl font-bold text-custom-blue mb-4">欢迎使用扩展配置</h1>
<!-- 使用自定义字体大小 -->
<p class="text-xxs text-gray-500 mb-2">这是超小号文字</p>
<p class="text-2xl+ text-gray-700 mb-4">这是略大于2xl的文字</p>
<!-- 使用自定义间距 -->
<div class="bg-custom-green p-72 mb-4">
<p class="text-white">这个div有很大的内边距</p>
</div>
<!-- 使用自定义断点 -->
<div class="xs:bg-red-500 sm:bg-blue-500 md:bg-green-500 lg:bg-yellow-500 xl:bg-purple-500 2xl:bg-pink-500 3xl:bg-orange-500 p-4 mb-4">
<p class="text-white">这个div在不同屏幕尺寸下会改变颜色</p>
</div>
<!-- 使用自定义变体 -->
<button class="bg-gray-300 hover:bg-gray-400 active:bg-custom-green-dark text-black font-bold py-2 px-4 rounded">
点击我
</button>
<a href="#" class="text-blue-500 visited:text-purple-500">
这是一个链接
</a>
</div>
5 Tailwind 的实现原理
Tailwind 是一个基于 PostCSS 的插件,通过解析、转换和生成 CSS 代码。
它通过提取器(extractor)扫描 JS 和 HTML 文件中的类名,并基于这些类名生成最终的 CSS 代码。
tailwind 还有种叫 JIT 的编译方式,JIT 模式通过分析 HTML、JavaScript 和模板文件,识别出所有使用的 Tailwind 类,然后只生成这些类的 CSS。这种方法既保持了 Tailwind 的灵活性,又解决了传统方式下 CSS 文件过大的问题。
6 反对声音与解决方案
- 可读性与可维护性:通过 Tailwind CSS IntelliSense 插件提供智能提示,提升开发体验。
- 调试难度:在 Chrome DevTools 中可以直接查看样式,调试更方便。
- 类名冲突:通过添加前缀解决类名冲突。
这个插件触发提示需要先敲一个空格,这点要注意下。
7 总结
Tailwind 是一个高效、灵活的原子化 CSS 框架,简化了样式编写,避免了样式冲突,提升了开发效率。
通过配置文件和插件扩展,Tailwind 能适应各种项目需求。