Skip to content

TailwindCSS

简介

Tailwind CSS是一个功能类优先(utility-first)的CSS框架,它与传统的UI框架(如Bootstrap、Bulma等)不同,不提供预设的组件样式,而是提供大量的功能类(utility classes),让开发者可以直接在HTML中组合这些类来构建自定义设计,而无需编写CSS。

核心理念

功能类优先(Utility-First)

Tailwind的核心理念是通过组合小型、单一用途的功能类来构建界面,而不是通过预定义的组件类:

html
<!-- 传统CSS方式 -->
<button class="btn btn-primary">按钮</button>

<!-- Tailwind方式 -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  按钮
</button>

响应式设计

Tailwind内置了一套响应式系统,可以轻松创建适应不同屏幕尺寸的界面:

html
<div class="text-center sm:text-left md:text-right lg:text-justify">
  这段文本在不同屏幕尺寸下有不同的对齐方式
</div>

状态变体

Tailwind提供了丰富的状态变体,如悬停、聚焦、激活等:

html
<button class="bg-blue-500 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-300 active:bg-blue-800">
  交互按钮
</button>

安装与配置

通过NPM安装

bash
# 安装Tailwind CSS
npm install -D tailwindcss

# 生成配置文件
npx tailwindcss init

配置文件

javascript
// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{html,js,jsx,ts,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        'brand': '#3490dc',
        'brand-light': '#6cb2eb',
      },
      spacing: {
        '72': '18rem',
        '84': '21rem',
        '96': '24rem',
      },
      fontFamily: {
        'sans': ['Inter', 'sans-serif'],
      },
    },
  },
  plugins: [],
}

在CSS中引入

css
/* src/styles.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* 自定义样式可以放在这里 */
@layer components {
  .btn-primary {
    @apply py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75;
  }
}

构建过程

bash
# 使用CLI构建
npx tailwindcss -i ./src/styles.css -o ./dist/output.css --watch

# 或在package.json中添加脚本
"scripts": {
  "dev": "tailwindcss -i ./src/styles.css -o ./dist/output.css --watch"
}

核心功能类

布局

html
<!-- 容器 -->
<div class="container mx-auto px-4">
  <!-- 内容 -->
</div>

<!-- 显示属性 -->
<div class="block sm:inline md:flex lg:grid">
  <!-- 内容 -->
</div>

<!-- 定位 -->
<div class="relative">
  <div class="absolute top-0 right-0">
    <!-- 绝对定位元素 -->
  </div>
</div>

<!-- Z-index -->
<div class="z-10"><!-- 内容 --></div>
<div class="z-20"><!-- 内容 --></div>

排版

html
<!-- 字体系列 -->
<p class="font-sans">Sans-serif字体</p>
<p class="font-serif">Serif字体</p>
<p class="font-mono">等宽字体</p>

<!-- 字体大小 -->
<p class="text-xs">超小文本</p>
<p class="text-sm">小文本</p>
<p class="text-base">基础文本</p>
<p class="text-lg">大文本</p>
<p class="text-xl">超大文本</p>
<p class="text-2xl">2xl文本</p>
<!-- 更多尺寸... -->

<!-- 字体粗细 -->
<p class="font-thin">细体</p>
<p class="font-normal">常规</p>
<p class="font-medium">中等</p>
<p class="font-bold">粗体</p>

<!-- 文本对齐 -->
<p class="text-left">左对齐</p>
<p class="text-center">居中对齐</p>
<p class="text-right">右对齐</p>

<!-- 文本颜色 -->
<p class="text-blue-500">蓝色文本</p>
<p class="text-red-600">红色文本</p>

背景

html
<!-- 背景颜色 -->
<div class="bg-white">白色背景</div>
<div class="bg-gray-100">浅灰色背景</div>
<div class="bg-blue-500">蓝色背景</div>

<!-- 背景渐变 -->
<div class="bg-gradient-to-r from-cyan-500 to-blue-500">
  渐变背景
</div>

<!-- 背景图片 -->
<div class="bg-cover bg-center" style="background-image: url('/img/background.jpg')">
  背景图片
</div>

边框

html
<!-- 边框宽度 -->
<div class="border">默认边框</div>
<div class="border-2">宽边框</div>
<div class="border-4">更宽边框</div>

<!-- 边框颜色 -->
<div class="border border-blue-500">蓝色边框</div>
<div class="border border-red-500">红色边框</div>

<!-- 边框圆角 -->
<div class="rounded">圆角</div>
<div class="rounded-md">中等圆角</div>
<div class="rounded-lg">大圆角</div>
<div class="rounded-full">完全圆形</div>

间距

html
<!-- 内边距 -->
<div class="p-4">所有方向内边距</div>
<div class="px-4">水平内边距</div>
<div class="py-4">垂直内边距</div>
<div class="pt-4">顶部内边距</div>
<div class="pr-4">右侧内边距</div>
<div class="pb-4">底部内边距</div>
<div class="pl-4">左侧内边距</div>

<!-- 外边距 -->
<div class="m-4">所有方向外边距</div>
<div class="mx-4">水平外边距</div>
<div class="my-4">垂直外边距</div>
<div class="mt-4">顶部外边距</div>
<div class="mr-4">右侧外边距</div>
<div class="mb-4">底部外边距</div>
<div class="ml-4">左侧外边距</div>

<!-- 自动外边距 -->
<div class="mx-auto">水平居中</div>

Flexbox

html
<div class="flex flex-row justify-between items-center">
  <div>项目1</div>
  <div>项目2</div>
  <div>项目3</div>
</div>

<!-- Flex方向 -->
<div class="flex flex-row">行方向</div>
<div class="flex flex-col">列方向</div>

<!-- 主轴对齐 -->
<div class="flex justify-start">起点对齐</div>
<div class="flex justify-center">居中对齐</div>
<div class="flex justify-end">终点对齐</div>
<div class="flex justify-between">两端对齐</div>
<div class="flex justify-around">环绕对齐</div>

<!-- 交叉轴对齐 -->
<div class="flex items-start">起点对齐</div>
<div class="flex items-center">居中对齐</div>
<div class="flex items-end">终点对齐</div>
<div class="flex items-stretch">拉伸对齐</div>

<!-- Flex项目 -->
<div class="flex">
  <div class="flex-1">伸缩项目</div>
  <div class="flex-none">不伸缩项目</div>
  <div class="flex-grow">只增长项目</div>
  <div class="flex-shrink">只收缩项目</div>
</div>

Grid

html
<!-- 基本网格 -->
<div class="grid grid-cols-3 gap-4">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

<!-- 响应式网格 -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
  <!-- 内容 -->
</div>

<!-- 网格跨列 -->
<div class="grid grid-cols-3 gap-4">
  <div class="col-span-2">跨越2列</div>
  <div>1列</div>
  <div>1列</div>
  <div class="col-span-3">跨越3列</div>
</div>

自定义与扩展

使用@apply组合功能类

css
@layer components {
  .card {
    @apply bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow duration-300;
  }
  
  .btn {
    @apply font-bold py-2 px-4 rounded;
  }
  
  .btn-blue {
    @apply btn bg-blue-500 text-white hover:bg-blue-700;
  }
  
  .btn-gray {
    @apply btn bg-gray-300 text-gray-700 hover:bg-gray-400;
  }
}

扩展主题

javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      // 扩展颜色
      colors: {
        'custom-blue': '#1da1f2',
        'custom-green': '#17bf63',
      },
      // 扩展字体
      fontFamily: {
        'display': ['Poppins', 'sans-serif'],
        'body': ['Roboto', 'sans-serif'],
      },
      // 扩展断点
      screens: {
        '3xl': '1600px',
      },
      // 扩展间距
      spacing: {
        '128': '32rem',
      },
      // 扩展阴影
      boxShadow: {
        'outline-blue': '0 0 0 3px rgba(66, 153, 225, 0.5)',
      },
    },
  },
}

创建插件

javascript
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents, theme }) {
      const buttons = {
        '.btn': {
          padding: `${theme('spacing.2')} ${theme('spacing.4')}`,
          fontWeight: theme('fontWeight.bold'),
          borderRadius: theme('borderRadius.default'),
          '&:focus': {
            outline: 'none',
            boxShadow: theme('boxShadow.outline'),
          },
        },
        '.btn-blue': {
          backgroundColor: theme('colors.blue.500'),
          color: theme('colors.white'),
          '&:hover': {
            backgroundColor: theme('colors.blue.600'),
          },
        },
      }

      addComponents(buttons)
    }),
  ],
}

优化生产环境

清除未使用的CSS

Tailwind默认使用PurgeCSS来移除生产环境中未使用的CSS类:

javascript
// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{html,js,jsx,ts,tsx,vue}',
  ],
  // 其他配置...
}

压缩CSS

bash
# 使用--minify选项
npx tailwindcss -i ./src/styles.css -o ./dist/output.css --minify

与框架集成

React集成

jsx
// App.jsx
import React from 'react';

function App() {
  return (
    <div className="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12">
      <div className="relative py-3 sm:max-w-xl sm:mx-auto">
        <div className="absolute inset-0 bg-gradient-to-r from-cyan-400 to-light-blue-500 shadow-lg transform -skew-y-6 sm:skew-y-0 sm:-rotate-6 sm:rounded-3xl"></div>
        <div className="relative px-4 py-10 bg-white shadow-lg sm:rounded-3xl sm:p-20">
          <div className="max-w-md mx-auto">
            <div className="text-center">
              <h1 className="text-3xl font-extrabold text-gray-900">Tailwind CSS with React</h1>
              <p className="mt-2 text-gray-600">使用Tailwind CSS构建React应用</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

Vue集成

vue
<!-- App.vue -->
<template>
  <div class="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12">
    <div class="relative py-3 sm:max-w-xl sm:mx-auto">
      <div class="absolute inset-0 bg-gradient-to-r from-cyan-400 to-light-blue-500 shadow-lg transform -skew-y-6 sm:skew-y-0 sm:-rotate-6 sm:rounded-3xl"></div>
      <div class="relative px-4 py-10 bg-white shadow-lg sm:rounded-3xl sm:p-20">
        <div class="max-w-md mx-auto">
          <div class="text-center">
            <h1 class="text-3xl font-extrabold text-gray-900">Tailwind CSS with Vue</h1>
            <p class="mt-2 text-gray-600">使用Tailwind CSS构建Vue应用</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

最佳实践

组织大型项目

  • 使用@layer components创建可复用组件
  • 使用@apply提取重复的功能类组合
  • 使用主题配置保持设计一致性
  • 考虑使用组件库(如Headless UI)与Tailwind结合

响应式设计策略

  • 采用移动优先的设计方法
  • 使用响应式前缀(sm:, md:, lg:, xl:)逐步增强界面
  • 避免在所有断点都重复定义相同的样式

性能优化

  • 确保正确配置content选项以清除未使用的CSS
  • 考虑使用@apply减少HTML中的类名长度
  • 在开发中使用JIT模式加快编译速度

与其他CSS方案对比

特性Tailwind CSSBootstrapCSS-in-JS传统CSS
学习曲线中等低-中
自定义性
开发速度
文件大小小(优化后)小-中取决于项目
组件化通过@apply预设组件原生支持需手动实现
主题支持强大有限强大需手动实现
类型安全可能有

常见问题与解决方案

类名过长

html
<!-- 问题:类名过长难以维护 -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
  按钮
</button>

<!-- 解决方案:使用@apply创建组件类 -->
<!-- 在CSS中 -->
@layer components {
  .btn-primary {
    @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline;
  }
}

<!-- 在HTML中 -->
<button class="btn-primary">按钮</button>

条件样式

jsx
// React中的条件样式
function Button({ primary }) {
  return (
    <button
      className={`
        font-bold py-2 px-4 rounded
        ${primary ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}
      `}
    >
      按钮
    </button>
  );
}

// 使用库如classnames或clsx
import classNames from 'classnames';

function Button({ primary, disabled }) {
  return (
    <button
      className={classNames(
        'font-bold py-2 px-4 rounded',
        {
          'bg-blue-500 text-white': primary && !disabled,
          'bg-gray-200 text-gray-800': !primary && !disabled,
          'bg-gray-300 text-gray-500 cursor-not-allowed': disabled
        }
      )}
    >
      按钮
    </button>
  );
}

学习资源