tailwind-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tailwind CSS Best Practices

Tailwind CSS 最佳实践

Comprehensive patterns for building consistent, maintainable interfaces with Tailwind CSS v4. Contains 26+ rules covering responsive design, dark mode, component patterns, and configuration best practices.
使用 Tailwind CSS v4 构建一致、可维护界面的全面模式。包含26+条规则,覆盖响应式设计、暗色模式、组件模式和配置最佳实践。

Metadata

元数据

  • Version: 4.0.0
  • Framework: Tailwind CSS v3.4+ / v4.0+
  • Rule Count: 26 rules across 7 categories
  • License: MIT
  • Documentation: tailwindcss.com/docs
  • 版本: 4.0.0
  • 框架: Tailwind CSS v3.4+ / v4.0+
  • 规则数量: 7个类别下共26条规则
  • 许可证: MIT
  • 文档: tailwindcss.com/docs

When to Apply

适用场景

Reference these guidelines when:
  • Writing responsive layouts
  • Implementing dark mode
  • Creating reusable component styles
  • Configuring Tailwind
  • Optimizing CSS output
在以下场景参考这些指南:
  • 编写响应式布局
  • 实现暗色模式
  • 创建可复用组件样式
  • 配置 Tailwind
  • 优化 CSS 输出

Rule Categories by Priority

按优先级划分的规则类别

PriorityCategoryImpactPrefix
1Responsive DesignCRITICAL
resp-
2Dark ModeCRITICAL
dark-
3Component PatternsHIGH
comp-
4Custom ConfigurationHIGH
config-
5Spacing & TypographyMEDIUM
space-
6AnimationMEDIUM
anim-
7PerformanceLOW
perf-
优先级类别影响程度前缀
1响应式设计关键
resp-
2暗色模式关键
dark-
3组件模式
comp-
4自定义配置
config-
5间距与排版
space-
6动画
anim-
7性能
perf-

Quick Reference

快速参考

1. Responsive Design (CRITICAL)

1. 响应式设计(关键)

  • resp-mobile-first
    - Mobile-first approach
  • resp-breakpoints
    - Use breakpoints correctly
  • resp-container
    - Container patterns
  • resp-grid-flex
    - Grid vs Flexbox decisions
  • resp-hidden-shown
    - Conditional display
  • resp-mobile-first
    - 移动端优先方法
  • resp-breakpoints
    - 正确使用断点
  • resp-container
    - 容器模式
  • resp-grid-flex
    - Grid 与 Flexbox 选择
  • resp-hidden-shown
    - 条件显示

2. Dark Mode (CRITICAL)

2. 暗色模式(关键)

  • dark-setup
    - Configure dark mode
  • dark-classes
    - Apply dark mode classes
  • dark-toggle
    - Implement dark mode toggle
  • dark-system-preference
    - Respect system preference
  • dark-colors
    - Design for both modes
  • dark-setup
    - 配置暗色模式
  • dark-classes
    - 应用暗色模式类
  • dark-toggle
    - 实现暗色模式切换
  • dark-system-preference
    - 遵循系统偏好设置
  • dark-colors
    - 适配两种模式的设计

3. Component Patterns (HIGH)

3. 组件模式(高)

  • comp-clsx-cn
    - Conditional classes utility
  • comp-variants
    - Component variants pattern
  • comp-slots
    - Slot-based components
  • comp-composition
    - Composing utilities
  • comp-clsx-cn
    - 条件类工具
  • comp-variants
    - 组件变体模式
  • comp-slots
    - 基于插槽的组件
  • comp-composition
    - 工具组合

4. Custom Configuration (HIGH)

4. 自定义配置(高)

  • config-extend
    - Extend vs override theme
  • config-colors
    - Custom color palette
  • config-fonts
    - Custom fonts
  • config-screens
    - Custom breakpoints
  • config-plugins
    - Using plugins
  • config-extend
    - 扩展与覆盖主题
  • config-colors
    - 自定义调色板
  • config-fonts
    - 自定义字体
  • config-screens
    - 自定义断点
  • config-plugins
    - 使用插件

5. Spacing & Typography (MEDIUM)

5. 间距与排版(中)

  • space-consistent
    - Consistent spacing scale
  • space-margins
    - Margin patterns
  • space-padding
    - Padding patterns
  • typo-scale
    - Typography scale
  • typo-line-height
    - Line height
  • space-consistent
    - 一致的间距比例
  • space-margins
    - 外边距模式
  • space-padding
    - 内边距模式
  • typo-scale
    - 排版比例
  • typo-line-height
    - 行高

6. Animation (MEDIUM)

6. 动画(中)

  • anim-transitions
    - Transition utilities
  • anim-keyframes
    - Custom keyframes
  • anim-reduced-motion
    - Respect motion preferences
  • anim-transitions
    - 过渡工具
  • anim-keyframes
    - 自定义关键帧
  • anim-reduced-motion
    - 遵循动效偏好设置

7. Performance (LOW)

7. 性能(低)

  • perf-purge
    - Content configuration
  • perf-jit
    - JIT mode benefits
  • perf-arbitrary
    - Arbitrary values usage
  • perf-purge
    - 内容配置
  • perf-jit
    - JIT 模式优势
  • perf-arbitrary
    - 任意值使用

Essential Patterns

核心模式

Mobile-First Responsive Design

移动端优先的响应式设计

tsx
// ✅ Mobile-first: start with mobile, add larger breakpoints
<div className="
  w-full           // Mobile: full width
  md:w-1/2         // Tablet: half width
  lg:w-1/3         // Desktop: third width
">
  <p className="
    text-sm          // Mobile: small text
    md:text-base     // Tablet: base text
    lg:text-lg       // Desktop: large text
  ">
    Content
  </p>
</div>

// ❌ Don't think desktop-first
<div className="w-1/3 md:w-1/2 sm:w-full">  // Confusing
tsx
// ✅ Mobile-first: start with mobile, add larger breakpoints
<div className="
  w-full           // Mobile: full width
  md:w-1/2         // Tablet: half width
  lg:w-1/3         // Desktop: third width
">
  <p className="
    text-sm          // Mobile: small text
    md:text-base     // Tablet: base text
    lg:text-lg       // Desktop: large text
  ">
    Content
  </p>
</div>

// ❌ Don't think desktop-first
<div className="w-1/3 md:w-1/2 sm:w-full">  // Confusing

Dark Mode Implementation

暗色模式实现

tsx
// tailwind.config.js
module.exports = {
  darkMode: 'class', // or 'media' for system preference
  // ...
}

// Component
<div className="
  bg-white dark:bg-gray-900
  text-gray-900 dark:text-white
  border border-gray-200 dark:border-gray-700
">
  <h2 className="text-gray-900 dark:text-white">Title</h2>
  <p className="text-gray-600 dark:text-gray-400">Description</p>
</div>

// Toggle with JavaScript
function toggleDarkMode() {
  document.documentElement.classList.toggle('dark')
}
tsx
// tailwind.config.js
module.exports = {
  darkMode: 'class', // or 'media' for system preference
  // ...
}

// Component
<div className="
  bg-white dark:bg-gray-900
  text-gray-900 dark:text-white
  border border-gray-200 dark:border-gray-700
">
  <h2 className="text-gray-900 dark:text-white">Title</h2>
  <p className="text-gray-600 dark:text-gray-400">Description</p>
</div>

// Toggle with JavaScript
function toggleDarkMode() {
  document.documentElement.classList.toggle('dark')
}

Conditional Classes with clsx/cn

使用 clsx/cn 实现条件类

tsx
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

// cn utility - merges Tailwind classes intelligently
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

// Usage
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'danger'
  size?: 'sm' | 'md' | 'lg'
  className?: string
  children: React.ReactNode
}

function Button({ variant = 'primary', size = 'md', className, children }: ButtonProps) {
  return (
    <button
      className={cn(
        // Base styles
        'inline-flex items-center justify-center rounded-md font-medium transition-colors',
        'focus:outline-none focus:ring-2 focus:ring-offset-2',

        // Variants
        {
          'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500':
            variant === 'primary',
          'bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500':
            variant === 'secondary',
          'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500':
            variant === 'danger',
        },

        // Sizes
        {
          'px-3 py-1.5 text-sm': size === 'sm',
          'px-4 py-2 text-base': size === 'md',
          'px-6 py-3 text-lg': size === 'lg',
        },

        // Allow override
        className
      )}
    >
      {children}
    </button>
  )
}
tsx
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

// cn utility - merges Tailwind classes intelligently
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

// Usage
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'danger'
  size?: 'sm' | 'md' | 'lg'
  className?: string
  children: React.ReactNode
}

function Button({ variant = 'primary', size = 'md', className, children }: ButtonProps) {
  return (
    <button
      className={cn(
        // Base styles
        'inline-flex items-center justify-center rounded-md font-medium transition-colors',
        'focus:outline-none focus:ring-2 focus:ring-offset-2',

        // Variants
        {
          'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500':
            variant === 'primary',
          'bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500':
            variant === 'secondary',
          'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500':
            variant === 'danger',
        },

        // Sizes
        {
          'px-3 py-1.5 text-sm': size === 'sm',
          'px-4 py-2 text-base': size === 'md',
          'px-6 py-3 text-lg': size === 'lg',
        },

        // Allow override
        className
      )}
    >
      {children}
    </button>
  )
}

Tailwind Configuration

Tailwind 配置

js
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.{js,ts,jsx,tsx}',
  ],
  darkMode: 'class',
  theme: {
    // Override defaults
    screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
      '2xl': '1536px',
    },

    // Extend (recommended - keeps defaults)
    extend: {
      colors: {
        primary: {
          50: '#f0f9ff',
          100: '#e0f2fe',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
        },
        secondary: {
          // ...
        },
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
        mono: ['JetBrains Mono', 'monospace'],
      },
      spacing: {
        '18': '4.5rem',
        '88': '22rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
  ],
}
js
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.{js,ts,jsx,tsx}',
  ],
  darkMode: 'class',
  theme: {
    // Override defaults
    screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
      '2xl': '1536px',
    },

    // Extend (recommended - keeps defaults)
    extend: {
      colors: {
        primary: {
          50: '#f0f9ff',
          100: '#e0f2fe',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
        },
        secondary: {
          // ...
        },
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
        mono: ['JetBrains Mono', 'monospace'],
      },
      spacing: {
        '18': '4.5rem',
        '88': '22rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
  ],
}

Responsive Grid Layout

响应式网格布局

tsx
// Product grid - responsive columns
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
  {products.map(product => (
    <ProductCard key={product.id} product={product} />
  ))}
</div>

// Dashboard layout - sidebar + main
<div className="flex flex-col lg:flex-row min-h-screen">
  <aside className="
    w-full lg:w-64
    bg-gray-900
    lg:min-h-screen
  ">
    <nav>...</nav>
  </aside>
  <main className="flex-1 p-4 lg:p-8">
    <div className="max-w-7xl mx-auto">
      {children}
    </div>
  </main>
</div>
tsx
// Product grid - responsive columns
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
  {products.map(product => (
    <ProductCard key={product.id} product={product} />
  ))}
</div>

// Dashboard layout - sidebar + main
<div className="flex flex-col lg:flex-row min-h-screen">
  <aside className="
    w-full lg:w-64
    bg-gray-900
    lg:min-h-screen
  ">
    <nav>...</nav>
  </aside>
  <main className="flex-1 p-4 lg:p-8">
    <div className="max-w-7xl mx-auto">
      {children}
    </div>
  </main>
</div>

Form Styling

表单样式

tsx
<form className="space-y-6">
  <div>
    <label htmlFor="email" className="block text-sm font-medium text-gray-700 dark:text-gray-300">
      Email
    </label>
    <input
      type="email"
      id="email"
      className="
        mt-1 block w-full rounded-md
        border-gray-300 dark:border-gray-600
        bg-white dark:bg-gray-800
        text-gray-900 dark:text-white
        shadow-sm
        focus:border-blue-500 focus:ring-blue-500
        disabled:bg-gray-100 disabled:cursor-not-allowed
      "
    />
  </div>

  <button
    type="submit"
    className="
      w-full flex justify-center
      py-2 px-4
      border border-transparent rounded-md
      shadow-sm text-sm font-medium
      text-white bg-blue-600
      hover:bg-blue-700
      focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500
      disabled:opacity-50 disabled:cursor-not-allowed
    "
  >
    Submit
  </button>
</form>
tsx
<form className="space-y-6">
  <div>
    <label htmlFor="email" className="block text-sm font-medium text-gray-700 dark:text-gray-300">
      Email
    </label>
    <input
      type="email"
      id="email"
      className="
        mt-1 block w-full rounded-md
        border-gray-300 dark:border-gray-600
        bg-white dark:bg-gray-800
        text-gray-900 dark:text-white
        shadow-sm
        focus:border-blue-500 focus:ring-blue-500
        disabled:bg-gray-100 disabled:cursor-not-allowed
      "
    />
  </div>

  <button
    type="submit"
    className="
      w-full flex justify-center
      py-2 px-4
      border border-transparent rounded-md
      shadow-sm text-sm font-medium
      text-white bg-blue-600
      hover:bg-blue-700
      focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500
      disabled:opacity-50 disabled:cursor-not-allowed
    "
  >
    Submit
  </button>
</form>

Animations with Reduced Motion

适配动效偏好的动画

tsx
// Respect user's motion preferences
<div className="
  transition-transform duration-300
  hover:scale-105
  motion-reduce:transition-none
  motion-reduce:hover:transform-none
">
  Card content
</div>

// Custom animation
<div className="animate-fade-in motion-reduce:animate-none">
  Content
</div>
js
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      keyframes: {
        'fade-in': {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
      },
      animation: {
        'fade-in': 'fade-in 0.3s ease-out',
      },
    },
  },
}
tsx
// Respect user's motion preferences
<div className="
  transition-transform duration-300
  hover:scale-105
  motion-reduce:transition-none
  motion-reduce:hover:transform-none
">
  Card content
</div>

// Custom animation
<div className="animate-fade-in motion-reduce:animate-none">
  Content
</div>
js
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      keyframes: {
        'fade-in': {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
      },
      animation: {
        'fade-in': 'fade-in 0.3s ease-out',
      },
    },
  },
}

How to Use

使用方法

Read individual rule files for detailed explanations and code examples:
rules/resp-mobile-first.md
rules/dark-setup.md
rules/comp-clsx-cn.md
阅读单个规则文件获取详细说明和代码示例:
rules/resp-mobile-first.md
rules/dark-setup.md
rules/comp-clsx-cn.md

References

参考资料

Ecosystem Tools

生态工具

  • Tailwind CSS IntelliSense - VS Code autocomplete and linting
  • Prettier Plugin - Automatic class sorting
  • tailwind-merge - Conflict-free class merging
  • clsx - Conditional class utility
  • CVA - Component variant system
  • Tailwind CSS IntelliSense - VS Code 自动补全与代码检查
  • Prettier Plugin - 自动类排序
  • tailwind-merge - 无冲突类合并
  • clsx - 条件类工具
  • CVA - 组件变体系统

License

许可证

MIT License - See repository for full license text.
This skill is part of the Agent Skills collection, providing AI-powered development assistance with industry best practices.
MIT 许可证 - 查看仓库获取完整许可证文本。
本技能属于 Agent Skills 集合,提供基于行业最佳实践的 AI 驱动开发辅助。