Tailwind CSS 自定义样式
·
Tailwind CSS 自定义样式学习笔记
一、自定义样式的层次结构
┌──────────────────────────────────────────────────────┐
│ tailwind.config.js → 设计系统 Token(颜色/间距/字号) │
│ @layer base → 全局基础样式重置 │
│ @layer components → 组件级自定义类 │
│ @layer utilities → 自定义工具类 │
│ @layer 外部 → 第三方/覆盖样式 │
│ arbitrary values → 一次性行内自定义值 │
└──────────────────────────────────────────────────────┘
二、方法一:Arbitrary Values(任意值)
无需修改配置,直接在类名中使用方括号语法写入任意 CSS 值。
基本语法
<!-- 间距 -->
<div class="mt-[17px] w-[calc(100%-3rem)] p-[2.5rem]">
<!-- 颜色 -->
<span class="text-[#1da1f2] bg-[rgb(59,130,246,0.5)]">
<!-- 字体 -->
<p class="text-[22px] leading-[27px] font-[500] tracking-[0.01em]">
<!-- 动画 -->
<div class="animate-[spin_1.5s_linear_infinite]">
<!-- 背景图 -->
<div class="bg-[url('/hero-pattern.png')] bg-[size:100px_100px]">
任意变体(Arbitrary Variants)
<!-- 任意媒体查询 -->
<div class="@[supports(display:grid)]:grid">
<!-- 任意选择器 -->
<div class="[&:nth-child(3)]:underline">
<div class="[&::before]:content-['→'] [&::before]:mr-2">
<!-- 子元素选择器 -->
<nav class="[&>li]:flex [&>li]:items-center">
<!-- 父级上下文 -->
<div class="[.dark_&]:text-white">
注意事项
- 任意值中的空格用
_代替:animate-[spin_1s_linear_infinite] - 任意值中的逗号用
_代替:grid-cols-[repeat(3,1fr)]→grid-cols-[repeat(3,1fr)] - 仅用于一次性场景,频繁出现应提取到配置中
三、方法二:扩展 Theme 配置
2.1 扩展 vs 覆盖
// tailwind.config.js
module.exports = {
theme: {
// ❌ 覆盖 — 完全替换默认值,丢失 Tailwind 默认色板
colors: {
brand: '#3b82f6',
},
// ✅ 扩展 — 在默认值基础上追加
extend: {
colors: {
brand: '#3b82f6',
},
},
},
};
2.2 自定义颜色
module.exports = {
theme: {
extend: {
colors: {
// 简单值
'brand': '#3b82f6',
// 色阶对象(生成 text-brand-50 ~ text-brand-950)
brand: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554',
},
// CSS 变量引用
surface: 'var(--color-surface)',
on: {
surface: 'var(--color-on-surface)',
},
},
},
},
};
<button class="bg-brand-500 text-white hover:bg-brand-600">品牌按钮</button>
<div class="bg-surface text-on-surface">主题卡片</div>
2.3 自定义间距 / 尺寸
extend: {
spacing: {
'4.5': '1.125rem',
'18': '4.5rem',
'128': '32rem',
},
width: {
'1/7': '14.2857%',
'2/7': '28.5714%',
},
height: {
'screen/2': '50vh',
},
}
2.4 自定义字体
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
display: ['Cal Sans', 'sans-serif'],
},
fontSize: {
'xxs': ['0.625rem', { lineHeight: '0.875rem' }],
'2xl': ['1.25rem', { lineHeight: '1.75rem', letterSpacing: '-0.01em' }],
},
}
<h1 class="font-display text-2xl">标题</h1>
<code class="font-mono text-xxs">代码</code>
2.5 自定义动画
extend: {
keyframes: {
'fade-in': {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
'slide-in-right': {
'0%': { transform: 'translateX(100%)' },
'100%': { transform: 'translateX(0)' },
},
'shimmer': {
'100%': { transform: 'translateX(100%)' },
},
},
animation: {
'fade-in': 'fade-in 0.3s ease-out forwards',
'slide-in-right': 'slide-in-right 0.4s ease-out',
'shimmer': 'shimmer 2s infinite',
},
}
<div class="animate-fade-in">淡入效果</div>
<div class="animate-slide-in-right">右侧滑入</div>
2.6 自定义阴影 / 边框圆角 / 过渡
extend: {
boxShadow: {
'glow': '0 0 15px rgba(59, 130, 246, 0.5)',
'inner-lg': 'inset 0 2px 4px 0 rgb(0 0 0 / 0.1)',
},
borderRadius: {
'4xl': '2rem',
'5xl': '2.5rem',
},
transitionTimingFunction: {
'bounce-in': 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
},
}
四、方法三:@layer 指令
4.1 Base 层 — 全局基础样式
@tailwind base;
@layer base {
/* 全局字体平滑 */
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* CSS 变量定义 */
:root {
--color-surface: #ffffff;
--color-on-surface: #1a1a2e;
--header-height: 4rem;
}
.dark {
--color-surface: #1a1a2e;
--color-on-surface: #e2e8f0;
}
/* 重置或覆盖默认样式 */
h1 {
@apply text-2xl font-bold tracking-tight;
}
h2 {
@apply text-xl font-semibold;
}
/* 焦点样式 */
*:focus-visible {
@apply outline-2 outline-offset-2 outline-blue-500;
}
}
4.2 Components 层 — 组件级样式
@tailwind components;
@layer components {
/* 使用 @apply 聚合 */
.btn {
@apply inline-flex items-center justify-center
rounded-md px-4 py-2 text-sm font-medium
transition-colors focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-offset-2
disabled:pointer-events-none disabled:opacity-50;
}
.btn-primary {
@apply btn bg-blue-600 text-white hover:bg-blue-700
focus-visible:ring-blue-500;
}
/* 也可以写原生 CSS */
.input-field {
@apply w-full rounded-md border border-gray-300 bg-white
px-3 py-2 text-sm transition-colors;
}
.input-field:focus {
@apply border-blue-500 ring-1 ring-blue-500 outline-none;
}
/* 响应式组件 */
.container-narrow {
@apply mx-auto w-full px-4 sm:px-6 lg:max-w-3xl;
}
}
4.3 Utilities 层 — 自定义工具类
@tailwind utilities;
@layer utilities {
/* 自定义工具类 */
.text-balance {
text-wrap: balance;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
.line-clamp-4 {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
}
}
Layer 优先级
base < components < utilities < 无 layer 的样式
utilities层优先级最高,可以覆盖components层- 不在
@layer中的样式优先级最高(慎用)
五、方法四:Plugin 插件
5.1 内联插件
// tailwind.config.js
const plugin = require('tailwindcss/plugin');
module.exports = {
plugins: [
// 添加自定义工具类
plugin(function ({ addUtilities, theme }) {
const newUtilities = {
'.text-shadow': {
textShadow: '0 2px 4px rgba(0,0,0,0.1)',
},
'.text-shadow-lg': {
textShadow: '0 4px 8px rgba(0,0,0,0.15)',
},
'.text-shadow-none': {
textShadow: 'none',
},
};
addUtilities(newUtilities);
}),
// 添加自定义组件
plugin(function ({ addComponents, theme }) {
addComponents({
'.card': {
backgroundColor: theme('colors.white'),
borderRadius: theme('borderRadius.xl'),
padding: theme('spacing.6'),
boxShadow: theme('boxShadow.lg'),
border: `1px solid ${theme('colors.gray.200')}`,
},
'.card-compact': {
padding: theme('spacing.4'),
},
});
}),
// 添加基础样式
plugin(function ({ addBase, theme }) {
addBase({
'h1': { fontSize: theme('fontSize.2xl') },
'h2': { fontSize: theme('fontSize.xl') },
});
}),
// 动态生成工具类
plugin(function ({ addUtilities, e, theme }) {
const gradients = theme('gradients', {});
Object.entries(gradients).forEach(([name, value]) => {
addUtilities({
[`.bg-gradient-${e(name)}`]: {
backgroundImage: value,
},
});
});
}),
],
theme: {
gradients: {
'blue': 'linear-gradient(to right, #3b82f6, #8b5cf6)',
'green': 'linear-gradient(to right, #10b981, #3b82f6)',
'sunset': 'linear-gradient(to right, #f97316, #ec4899)',
},
},
};
5.2 独立插件包
// my-tailwind-plugin/index.js
const plugin = require('tailwindcss/plugin');
module.exports = plugin.withOptions(
function (options = {}) {
return function ({ addUtilities, theme }) {
const prefix = options.prefix ?? 'my';
addUtilities({
[`.${prefix}-text-gradient`]: {
backgroundImage: `var(--gradient, ${theme('gradients.blue', 'linear-gradient(to right, #3b82f6, #8b5cf6)')})`,
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
},
});
};
},
function (options) {
return {
theme: {
gradients: {
blue: 'linear-gradient(to right, #3b82f6, #8b5cf6)',
sunset: 'linear-gradient(to right, #f97316, #ec4899)',
},
},
};
}
);
// 使用
module.exports = {
plugins: [
require('./my-tailwind-plugin')({ prefix: 'app' }),
],
};
六、方法五:CSS 变量 + Tailwind 联动
6.1 定义 CSS 变量
@layer base {
:root {
--color-background: #ffffff;
--color-foreground: #171717;
--color-primary: #2563eb;
--color-muted: #f5f5f5;
--radius: 0.5rem;
}
.dark {
--color-background: #0a0a0a;
--color-foreground: #ededed;
--color-primary: #3b82f6;
--color-muted: #262626;
}
}
6.2 在 Tailwind 配置中引用
module.exports = {
theme: {
extend: {
colors: {
background: 'var(--color-background)',
foreground: 'var(--color-foreground)',
primary: 'var(--color-primary)',
muted: 'var(--color-muted)',
},
borderRadius: {
DEFAULT: 'var(--radius)',
},
},
},
};
<div class="bg-background text-foreground">
<button class="bg-primary text-white rounded-md">按钮</button>
<div class="bg-muted p-4">静音区域</div>
</div>
6.3 运行时切换主题
// 切换暗色模式
document.documentElement.classList.toggle('dark');
// 动态修改变量(如用户自定义主题色)
document.documentElement.style.setProperty('--color-primary', '#ec4899');
七、方法六:Important 修饰符与优先级控制
<!-- ! 前缀强制 important -->
<p class="!text-red-500 font-bold">
<!-- 生成: color: #ef4444 !important; -->
// 全局开启 important(避免与第三方 CSS 冲突)
module.exports = {
important: true, // 所有工具类都加 !important
// 或指定选择器(推荐,避免与第三方库冲突)
important: '#app',
};
/* 生成结果 */
#app .text-red-500 {
color: #ef4444;
}
八、完整配置示例
// tailwind.config.js
const plugin = require('tailwindcss/plugin');
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx,vue}'],
important: '#app',
theme: {
extend: {
// 颜色系统
colors: {
brand: {
50: '#eff6ff',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
},
surface: 'var(--color-surface)',
},
// 字体
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
// 动画
keyframes: {
'fade-in': {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
},
animation: {
'fade-in': 'fade-in 0.3s ease-out',
},
// 自定义间距
spacing: {
'18': '4.5rem',
},
},
},
plugins: [
// 自定义工具类插件
plugin(function ({ addUtilities }) {
addUtilities({
'.text-balance': { textWrap: 'balance' },
'.scrollbar-hide': {
'-ms-overflow-style': 'none',
'scrollbar-width': 'none',
'&::-webkit-scrollbar': { display: 'none' },
},
});
}),
],
};
九、决策速查表
| 需求 | 推荐方案 | 示例 |
|---|---|---|
| 一次性特殊值 | Arbitrary Values | top-[17px] |
| 设计系统级颜色/间距 | theme.extend |
colors.brand.500 |
| 全局基础样式 | @layer base |
字体平滑、CSS 变量 |
| 组件级样式聚合 | @layer components + @apply |
.btn-primary |
| 自定义工具类 | @layer utilities 或 Plugin |
.text-balance |
| 动态主题切换 | CSS 变量 + theme.extend |
var(--color-primary) |
| 可复用插件 | Plugin 包 | addUtilities / addComponents |
| 覆盖第三方样式 | important 或 ! 前缀 |
!text-red-500 |
核心原则
- Arbitrary Values 用于一次性 — 出现 2 次以上就应提取到配置
extend优先于覆盖 — 保留 Tailwind 默认值- CSS 变量实现动态主题 — 配合
theme.extend双向联动 @layer控制优先级 — base < components < utilities- Plugin 用于跨项目复用 — 单项目用
@layer即可
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)