tailwind-css-standards.md 11 KB

Tailwind CSS 样式规范

版本信息

版本 日期 描述 作者
1.0 2025-10-15 初始Tailwind CSS样式规范 Winston

概述

本文档定义了出行服务项目中Tailwind CSS的使用规范和最佳实践,特别针对Taro小程序环境的适配和优化。

技术栈配置

核心依赖

{
  "tailwindcss": "^4.1.11",
  "weapp-tailwindcss": "^4.2.5",
  "@tailwindcss/postcss": "^4.1.11",
  "autoprefixer": "^10.4.21",
  "postcss": "^8.4.38"
}

配置规范

Tailwind配置

// tailwind.config.js
const { iconsPlugin, getIconCollections } = require("@egoist/tailwindcss-icons")

module.exports = {
  content: [
    './src/**/*.{html,js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        // 项目品牌色
        primary: {
          50: '#f0f9ff',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
        },
        // 语义化颜色
        destructive: {
          50: '#fef2f2',
          500: '#ef4444',
          600: '#dc2626',
        },
      },
      spacing: {
        '18': '4.5rem',
        '88': '22rem',
      },
      borderRadius: {
        '4xl': '2rem',
      }
    },
  },
  plugins: [
    iconsPlugin({
      collections: getIconCollections(["mdi", "lucide", "heroicons"]),
    }),
  ],
  corePlugins: {
    preflight: false, // 小程序环境禁用preflight
  },
}

Webpack配置(小程序适配)

// config/index.ts
mini: {
  webpackChain(chain) {
    chain.merge({
      plugin: {
        install: {
          plugin: UnifiedWebpackPluginV5,
          args: [{
            cssSelectorReplacement: {
              universal: ['view','text','button', 'input']
            },
            cssChildCombinatorReplaceValue: ['view', 'text', 'button', 'input']
          }]
        }
      }
    })
  }
}

样式类名使用规范

原子化类名原则

推荐做法:

// ✅ 使用原子化类名
<View className="flex items-center justify-between p-4 bg-white rounded-lg shadow-sm">
  <Text className="text-lg font-semibold text-gray-900">标题</Text>
  <Button className="px-3 py-1 bg-blue-500 text-white rounded">按钮</Button>
</View>

不推荐做法:

// ❌ 避免自定义CSS类
<View className="card-container">
  <Text className="card-title">标题</Text>
  <Button className="card-button">按钮</Button>
</View>

// 对应的CSS
.card-container { /* ... */ }
.card-title { /* ... */ }
.card-button { /* ... */ }

响应式设计

移动端优先:

<View className="w-full md:w-1/2 lg:w-1/3">
  <Text className="text-sm md:text-base lg:text-lg">响应式文本</Text>
</View>

小程序专用响应式:

<View className="w-full min-[375px]:w-11/12 min-[414px]:w-5/6">
  <Text className="text-[32rpx] min-[375px]:text-[34rpx]">适配不同屏幕</Text>
</View>

组件样式规范

shadcn/ui组件适配

按钮组件样式:

// src/components/ui/button.tsx
const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
  {
    variants: {
      variant: {
        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
        destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
        outline: 'border border-input hover:bg-accent hover:text-accent-foreground',
        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
        ghost: 'hover:bg-accent hover:text-accent-foreground',
        link: 'underline-offset-4 hover:underline text-primary',
      },
      size: {
        default: 'h-10 py-2 px-4',
        sm: 'h-9 px-3 rounded-md text-xs',
        lg: 'h-11 px-8 rounded-md',
        icon: 'h-10 w-10',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'default',
    },
  }
)

表单组件样式

输入框组件:

// src/components/ui/input.tsx
const inputVariants = cva(
  'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
  {
    variants: {
      variant: {
        default: '',
        search: 'pl-8',
      },
    },
    defaultVariants: {
      variant: 'default',
    },
  }
)

布局系统规范

容器布局

页面容器:

<View className="min-h-screen bg-gray-50">
  {/* 安全区域适配 */}
  <View className="safe-area">
    {/* 内容容器 */}
    <View className="container mx-auto px-4">
      {/* 页面内容 */}
    </View>
  </View>
</View>

Flex布局:

<View className="flex flex-col space-y-4">
  <View className="flex items-center justify-between">
    <Text>左侧</Text>
    <Text>右侧</Text>
  </View>

  <View className="flex-1">
    <Text>自适应内容</Text>
  </View>
</View>

Grid布局

网格系统:

<View className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  <View className="bg-white p-4 rounded-lg shadow">卡片1</View>
  <View className="bg-white p-4 rounded-lg shadow">卡片2</View>
  <View className="bg-white p-4 rounded-lg shadow">卡片3</View>
</View>

颜色系统规范

语义化颜色

文本颜色:

<Text className="text-primary">主要文本</Text>
<Text className="text-secondary">次要文本</Text>
<Text className="text-muted-foreground">弱化文本</Text>
<Text className="text-destructive">错误文本</Text>

背景颜色:

<View className="bg-background">页面背景</View>
<View className="bg-card">卡片背景</View>
<View className="bg-popover">弹出层背景</View>
<View className="bg-muted">弱化背景</View>

品牌颜色使用

主要品牌色:

<Button className="bg-primary text-primary-foreground">主要按钮</Button>
<Text className="text-primary">品牌文字</Text>
<View className="border-primary">品牌边框</View>

状态颜色:

<View className="text-success">成功状态</View>
<View className="text-warning">警告状态</View>
<View className="text-error">错误状态</View>
<View className="text-info">信息状态</View>

间距和尺寸规范

间距系统

垂直间距:

<View className="space-y-2">  {/* 小间距 */}
<View className="space-y-4">  {/* 中等间距 */}
<View className="space-y-6">  {/* 大间距 */}
<View className="space-y-8">  {/* 超大间距 */}

水平间距:

<View className="space-x-2">  {/* 小间距 */}
<View className="space-x-4">  {/* 中等间距 */}
<View className="space-x-6">  {/* 大间距 */}

尺寸系统

固定尺寸:

<View className="w-16 h-16">     {/* 64px */}
<View className="w-24 h-24">     {/* 96px */}
<View className="w-32 h-32">     {/* 128px */}

相对尺寸:

<View className="w-1/2">     {/* 50%宽度 */}
<View className="w-full">    {/* 100%宽度 */}
<View className="w-auto">    {/* 自动宽度 */}
<View className="min-w-0">   {/* 最小宽度0 */}

字体和排版规范

字体大小

文本层级:

<Text className="text-xs">  辅助文本 (12px)</Text>
<Text className="text-sm">  小文本 (14px)</Text>
<Text className="text-base">基础文本 (16px)</Text>
<Text className="text-lg">  大文本 (18px)</Text>
<Text className="text-xl">  标题文本 (20px)</Text>
<Text className="text-2xl"> 大标题 (24px)</Text>

字体粗细

字重层级:

<Text className="font-normal">正常</Text>
<Text className="font-medium">中等</Text>
<Text className="font-semibold">半粗</Text>
<Text className="font-bold">粗体</Text>

行高和字距

行高控制:

<Text className="leading-tight">   紧密行高</Text>
<Text className="leading-normal"> 正常行高</Text>
<Text className="leading-relaxed">宽松行高</Text>
<Text className="leading-loose">  超松行高</Text>

交互状态规范

悬停状态

按钮悬停:

<Button className="bg-primary hover:bg-primary/90">
  悬停变暗
</Button>

卡片悬停:

<View className="bg-white hover:bg-gray-50 transition-colors">
  悬停变亮
</View>

焦点状态

输入框焦点:

<Input className="focus:ring-2 focus:ring-primary focus:border-transparent" />

按钮焦点:

<Button className="focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2">
  焦点环
</Button>

激活状态

按钮激活:

<Button className="active:scale-95 transition-transform">
  点击缩放
</Button>

动画和过渡规范

过渡动画

基础过渡:

<View className="transition-all duration-300 ease-in-out">
  所有属性过渡
</View>

<View className="transition-colors duration-200">
  颜色过渡
</View>

<View className="transition-transform duration-150">
  变换过渡
</View>

变换动画

缩放变换:

<View className="hover:scale-105 active:scale-95 transition-transform">
  悬停放大,点击缩小
</View>

位移变换:

<View className="hover:-translate-y-1 transition-transform">
  悬停上移
</View>

小程序特殊适配

rpx单位使用

响应式单位:

<View className="w-[750rpx] h-[200rpx]">
  <Text className="text-[32rpx]">使用rpx单位</Text>
</View>

安全区域适配

iPhone安全区域:

<View className="pb-safe">
  {/* 底部安全区域 */}
</View>

<View className="pt-safe">
  {/* 顶部安全区域 */}
</View>

性能优化规范

类名合并

使用cn工具:

import { cn } from '@/utils/cn'

export function Component({ className, variant }) {
  return (
    <View className={cn(
      'base-classes',
      variant === 'primary' && 'primary-classes',
      className
    )}>
      内容
    </View>
  )
}

避免样式冲突

作用域样式:

// 使用特定的前缀或命名空间
<View className="travel-home-page">
  <Text className="travel-home-title">标题</Text>
</View>

最佳实践总结

  1. 原子化优先: 优先使用Tailwind原子类,避免自定义CSS
  2. 语义化命名: 使用有意义的颜色和尺寸命名
  3. 响应式设计: 移动端优先,逐步增强
  4. 一致性: 保持整个项目的样式一致性
  5. 性能: 合理使用类名合并,避免样式冗余
  6. 可维护性: 建立统一的样式规范和组件库

文档状态: 正式版 下次评审: 2025-11-15