Tailwind CSS 最佳实践 #

代码组织 #

类名顺序 #

保持一致的类名顺序,提高可读性:

html
<!-- 推荐顺序:布局 → 尺寸 → 间距 → 视觉 → 状态 -->
<button class="
  flex items-center justify-center
  w-full h-12
  px-4 py-2
  bg-blue-500 text-white rounded-lg shadow
  hover:bg-blue-600 focus:ring-2 focus:ring-blue-500
  transition-colors
">
  按钮
</button>

使用 Prettier 插件 #

自动排序类名:

bash
npm install -D prettier prettier-plugin-tailwindcss
json
// .prettierrc
{
  "plugins": ["prettier-plugin-tailwindcss"]
}

多行格式 #

对于复杂的元素,使用多行格式:

html
<div class="
  relative
  flex items-center justify-between
  w-full
  px-6 py-4
  bg-white
  border-b border-gray-200
  shadow-sm
  hover:shadow-md
  transition-shadow
">
  内容
</div>

组件设计 #

何时提取组件 #

提取规则:重复三次以上

html
<!-- 第一次:直接使用实用类 -->
<button class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
  按钮
</button>

<!-- 第二次:继续使用实用类 -->
<button class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
  按钮
</button>

<!-- 第三次:考虑提取组件 -->
<Button>按钮</Button>

组件抽象方式 #

1. 使用框架组件 #

jsx
// React 组件
function Button({ children, variant = 'primary', size = 'md' }) {
  const variants = {
    primary: 'bg-blue-500 hover:bg-blue-600 text-white',
    secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800',
    outline: 'border-2 border-blue-500 text-blue-500 hover:bg-blue-500 hover:text-white',
  }
  
  const sizes = {
    sm: 'px-3 py-1.5 text-sm',
    md: 'px-4 py-2',
    lg: 'px-6 py-3 text-lg',
  }
  
  return (
    <button className={`
      inline-flex items-center justify-center
      rounded font-medium
      ${variants[variant]}
      ${sizes[size]}
      transition-colors
    `}>
      {children}
    </button>
  )
}

2. 使用 @apply(谨慎使用) #

css
@layer components {
  .btn {
    @apply inline-flex items-center justify-center;
    @apply px-4 py-2 rounded font-medium;
    @apply transition-colors;
  }
  
  .btn-primary {
    @apply bg-blue-500 text-white hover:bg-blue-600;
  }
}

避免 @apply 滥用 #

css
/* 不推荐:过度使用 @apply */
.card {
  @apply bg-white rounded-lg shadow-md p-6 m-4 border border-gray-200 hover:shadow-lg transition-shadow;
}

/* 推荐:保持简洁 */
.card {
  @apply bg-white rounded-lg shadow-md;
  padding: 1.5rem;
}

命名约定 #

语义化命名 #

javascript
// 推荐:语义化颜色名
colors: {
  primary: '#3b82f6',
  secondary: '#6b7280',
  success: '#22c55e',
  warning: '#f59e0b',
  danger: '#ef4444',
}

// 不推荐:具体颜色名
colors: {
  blue: '#3b82f6',
  gray: '#6b7280',
  green: '#22c55e',
}

组件命名 #

jsx
// 推荐:清晰的组件名
<Card>
  <CardHeader>标题</CardHeader>
  <CardBody>内容</CardBody>
  <CardFooter>底部</CardFooter>
</Card>

// 不推荐:模糊的命名
<Box>
  <BoxHeader>标题</BoxHeader>
  <BoxContent>内容</BoxContent>
</Box>

响应式设计 #

移动优先 #

html
<!-- 推荐:移动优先 -->
<div class="text-sm md:text-base lg:text-lg">
  响应式文字
</div>

<!-- 不推荐:桌面优先 -->
<div class="text-lg md:text-base lg:text-sm">
  响应式文字
</div>

断点策略 #

html
<!-- 使用合理的断点 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
  卡片网格
</div>

暗色模式 #

统一配色方案 #

html
<!-- 推荐:统一的配色 -->
<div class="
  bg-white dark:bg-gray-800
  text-gray-900 dark:text-white
  border-gray-200 dark:border-gray-700
">
  内容
</div>

避免硬编码 #

javascript
// 推荐:使用主题配置
module.exports = {
  theme: {
    extend: {
      colors: {
        surface: {
          DEFAULT: '#ffffff',
          dark: '#1f2937',
        },
      },
    },
  },
}

性能优化 #

正确配置 content #

javascript
// 推荐:精确指定路径
module.exports = {
  content: [
    './src/**/*.{html,js,ts,jsx,tsx}',
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
}

// 不推荐:扫描所有文件
module.exports = {
  content: ['./**/*'],
}

避免动态类名 #

jsx
// 不推荐:动态拼接类名
<div class={`text-${color}-500`}>

// 推荐:完整类名映射
const colorClasses = {
  red: 'text-red-500',
  blue: 'text-blue-500',
  green: 'text-green-500',
}

<div class={colorClasses[color]}>

使用 Safelist #

javascript
// 对于必须动态生成的类
module.exports = {
  safelist: [
    'text-red-500',
    'text-blue-500',
    'text-green-500',
  ],
}

可访问性 #

焦点状态 #

html
<!-- 始终提供可见的焦点状态 -->
<button class="
  bg-blue-500 text-white px-4 py-2 rounded
  focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
">
  按钮
</button>

颜色对比度 #

html
<!-- 确保足够的对比度 -->
<p class="text-gray-900 dark:text-white">
  高对比度文字
</p>

<!-- 避免低对比度 -->
<p class="text-gray-400">
  低对比度文字(不推荐)
</p>

语义化 HTML #

html
<!-- 推荐:语义化标签 -->
<nav>
  <ul>
    <li><a href="#">首页</a></li>
    <li><a href="#">关于</a></li>
  </ul>
</nav>

<!-- 不推荐:滥用 div -->
<div>
  <div><div>首页</div></div>
  <div><div>关于</div></div>
</div>

团队协作 #

配置文件规范 #

javascript
// tailwind.config.js
module.exports = {
  // 内容路径
  content: ['./src/**/*.{html,js,ts,jsx,tsx}'],
  
  // 暗色模式
  darkMode: 'class',
  
  // 主题扩展
  theme: {
    extend: {
      // 颜色
      colors: {},
      
      // 间距
      spacing: {},
      
      // 字体
      fontFamily: {},
    },
  },
  
  // 插件
  plugins: [],
}

文档注释 #

html
<!-- 
  卡片组件
  用途:展示内容卡片
  变体:default, highlighted, bordered
-->
<div class="bg-white rounded-lg shadow-md p-6">
  卡片内容
</div>

常见问题 #

1. 类名太长? #

html
<!-- 使用组件抽象 -->
<Button variant="primary" size="lg">
  按钮
</Button>

2. 样式不一致? #

javascript
// 使用主题配置保持一致性
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#3b82f6',
      },
    },
  },
}

3. 难以维护? #

jsx
// 使用组件和良好的代码组织
function Card({ title, children }) {
  return (
    <div className="bg-white rounded-lg shadow-md p-6">
      <h3 className="text-lg font-semibold">{title}</h3>
      <div className="mt-2">{children}</div>
    </div>
  )
}

总结 #

  1. 保持类名有序:使用 Prettier 插件自动排序
  2. 合理提取组件:重复三次以上再提取
  3. 谨慎使用 @apply:优先使用框架组件
  4. 移动优先设计:从小屏幕开始
  5. 统一配色方案:使用主题配置
  6. 关注可访问性:提供焦点状态和足够对比度
  7. 优化性能:正确配置 content 和避免动态类名

恭喜你完成了 Tailwind CSS 完全指南的学习!现在你已经掌握了从基础到高级的 Tailwind CSS 技能,可以开始在实际项目中应用了。

最后更新:2026-03-28