tailwind-css-patterns by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill tailwind-css-patterns使用 Tailwind CSS 实用程序优先框架构建现代化、响应式用户界面的专家指南。涵盖 v4.1+ 特性,包括 CSS 优先配置、自定义实用程序和增强的开发体验。
function ProductCard({ product }: { product: Product }) {
return (
<div className="bg-white rounded-lg shadow-lg overflow-hidden
sm:flex sm:max-w-2xl">
<img
className="h-48 w-full object-cover sm:h-auto sm:w-48"
src={product.image}
alt={product.name}
/>
<div className="p-6">
<h3 className="text-lg font-semibold text-gray-900">
{product.name}
</h3>
<p className="mt-2 text-gray-600">
{product.description}
</p>
<button className="mt-4 px-4 py-2 bg-indigo-600 text-white
rounded-lg hover:bg-indigo-700 transition">
Add to Cart
</button>
</div>
</div>
);
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
@apply 与复杂选择器一起使用使用实用程序类直接在标记中应用样式:
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Click me
</button>
带有前缀的移动优先断点:
<div class="w-full md:w-1/2 lg:w-1/3">
<!-- 移动设备上全宽,平板上一半,桌面上三分之一 -->
</div>
断点前缀:
sm: - 640px 及以上md: - 768px 及以上lg: - 1024px 及以上xl: - 1280px 及以上2xl: - 1536px 及以上基础 flex 容器:
<div class="flex items-center justify-between">
<div>Left</div>
<div>Center</div>
<div>Right</div>
</div>
响应式 flex 方向:
<div class="flex flex-col md:flex-row gap-4">
<div class="flex-1">Item 1</div>
<div class="flex-1">Item 2</div>
<div class="flex-1">Item 3</div>
</div>
常见 flex 模式:
<!-- 居中内容 -->
<div class="flex items-center justify-center min-h-screen">
<div>Centered Content</div>
</div>
<!-- 项目间间距 -->
<div class="flex justify-between items-center">
<span>Left</span>
<span>Right</span>
</div>
<!-- 带间距的垂直堆叠 -->
<div class="flex flex-col gap-4">
<div>Item 1</div>
<div>Item 2</div>
</div>
基础网格:
<div class="grid grid-cols-3 gap-4">
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>
响应式网格:
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- 移动设备 1 列,平板 2 列,桌面 4 列 -->
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
自动适应列:
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
<!-- 根据容器宽度自动适应列 -->
</div>
带最大宽度的居中容器:
<div class="container mx-auto px-4 max-w-7xl">
<!-- 带内边距的居中内容 -->
</div>
响应式最大宽度:
<div class="w-full max-w-md mx-auto">
<!-- 最大 448px 宽度,居中 -->
</div>
统一间距:
<div class="p-4">Padding all sides</div>
<div class="m-4">Margin all sides</div>
单边间距:
<div class="pt-4 pr-8 pb-4 pl-8">
<!-- 上 1rem,右 2rem,下 1rem,左 2rem -->
</div>
基于轴的间距:
<div class="px-4 py-8">
<!-- 水平内边距 1rem,垂直内边距 2rem -->
</div>
响应式间距:
<div class="p-4 md:p-8 lg:p-12">
<!-- 在更大的断点处增加内边距 -->
</div>
子元素间间距:
<div class="space-y-4">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<h1 class="text-4xl font-bold">Large Heading</h1>
<h2 class="text-2xl font-semibold">Subheading</h2>
<p class="text-base font-normal">Body text</p>
<small class="text-sm text-gray-600">Small text</small>
响应式排版:
<h1 class="text-2xl md:text-4xl lg:text-6xl font-bold">
Responsive Heading
</h1>
<p class="leading-relaxed tracking-wide">
Text with relaxed line height and wide letter spacing
</p>
<p class="text-left md:text-center">
Left aligned on mobile, centered on tablet+
</p>
<div class="bg-blue-500">Blue background</div>
<div class="bg-gray-100">Light gray background</div>
<div class="bg-gradient-to-r from-blue-500 to-purple-600">
Gradient background
</div>
<p class="text-gray-900">Dark text</p>
<p class="text-blue-600">Blue text</p>
<p class="text-red-500">Error text</p>
<div class="bg-blue-500 bg-opacity-50">
Semi-transparent blue
</div>
<button class="bg-blue-500 hover:bg-blue-700 transition">
Hover me
</button>
<a class="text-blue-600 hover:text-blue-800 hover:underline">
Hover link
</a>
<input class="border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 outline-none">
<button class="bg-blue-500 active:bg-blue-800 disabled:opacity-50 disabled:cursor-not-allowed">
Button
</button>
<div class="group">
<img class="group-hover:opacity-75" src="image.jpg" />
<p class="group-hover:text-blue-600">Hover the parent</p>
</div>
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<img class="w-full h-48 object-cover" src="image.jpg" alt="Card image" />
<div class="p-6">
<h3 class="text-xl font-bold mb-2">Card Title</h3>
<p class="text-gray-700 mb-4">Card description text goes here.</p>
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Action
</button>
</div>
</div>
<div class="max-w-sm mx-auto bg-white rounded-xl shadow-lg overflow-hidden sm:flex sm:max-w-2xl">
<img class="h-48 w-full object-cover sm:h-auto sm:w-48"
src="profile.jpg"
alt="Profile" />
<div class="p-8">
<div class="uppercase tracking-wide text-sm text-indigo-500 font-semibold">
Product Engineer
</div>
<h2 class="mt-1 text-xl font-semibold text-gray-900">
John Doe
</h2>
<p class="mt-2 text-gray-500">
Building amazing products with modern technology.
</p>
<button class="mt-4 px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
Contact
</button>
</div>
</div>
<nav class="bg-white shadow-lg">
<div class="container mx-auto px-4">
<div class="flex justify-between items-center h-16">
<div class="flex items-center">
<a href="#" class="text-xl font-bold text-gray-800">Logo</a>
</div>
<div class="hidden md:flex space-x-8">
<a href="#" class="text-gray-700 hover:text-blue-600 transition">Home</a>
<a href="#" class="text-gray-700 hover:text-blue-600 transition">About</a>
<a href="#" class="text-gray-700 hover:text-blue-600 transition">Services</a>
<a href="#" class="text-gray-700 hover:text-blue-600 transition">Contact</a>
</div>
<button class="md:hidden">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
</div>
</div>
</nav>
<form class="space-y-6 max-w-md mx-auto">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Email
</label>
<input
type="email"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="you@example.com"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Password
</label>
<input
type="password"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div class="flex items-center">
<input type="checkbox" class="mr-2" />
<label class="text-sm text-gray-600">Remember me</label>
</div>
<button
type="submit"
class="w-full bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg hover:bg-blue-700 transition"
>
Sign In
</button>
</form>
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4">
<div class="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold">Modal Title</h3>
<button class="text-gray-500 hover:text-gray-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
<p class="text-gray-700 mb-6">
Modal content goes here.
</p>
<div class="flex justify-end space-x-4">
<button class="px-4 py-2 text-gray-600 hover:text-gray-800">
Cancel
</button>
<button class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
Confirm
</button>
</div>
</div>
</div>
<div class="container mx-auto px-4">
<!-- Hero 部分 -->
<div class="flex flex-col md:flex-row items-center gap-8 py-12">
<div class="flex-1">
<h1 class="text-3xl md:text-5xl font-bold mb-4">
Welcome to Our Site
</h1>
<p class="text-lg text-gray-600 mb-6">
Build amazing things with Tailwind CSS
</p>
<button class="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700">
Get Started
</button>
</div>
<div class="flex-1">
<img src="hero.jpg" class="w-full rounded-lg shadow-lg" />
</div>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 p-4">
<div class="aspect-square bg-gray-200 rounded-lg overflow-hidden">
<img src="image1.jpg" class="w-full h-full object-cover hover:scale-105 transition" />
</div>
<div class="aspect-square bg-gray-200 rounded-lg overflow-hidden">
<img src="image2.jpg" class="w-full h-full object-cover hover:scale-105 transition" />
</div>
<!-- 更多项目... -->
</div>
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
<h1 class="text-gray-900 dark:text-white">Title</h1>
<p class="text-gray-600 dark:text-gray-400">Description</p>
</div>
在 tailwind.config.js 中启用深色模式:
module.exports = {
darkMode: 'class', // 或 'media'
// ...
}
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300">
Smooth transition
</button>
<div class="transform hover:scale-110 transition duration-300">
Scale on hover
</div>
<img class="transform hover:rotate-6 transition duration-300" />
<div class="animate-spin">Spinning</div>
<div class="animate-pulse">Pulsing</div>
<div class="animate-bounce">Bouncing</div>
为最佳清理配置内容源:
// tailwind.config.js
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx,vue,svelte}",
"./node_modules/@mycompany/ui-lib/**/*.{js,ts,jsx,tsx}",
],
// 启用 JIT 以获得更快的构建速度
jit: true,
}
<!-- 对屏幕外内容使用 content-visibility -->
<div class="content-visibility-auto">
<div>Heavy content that's initially offscreen</div>
</div>
<!-- 使用 aspect-ratio 优化图像 -->
<img class="aspect-video w-full object-cover" src="video.jpg" alt="Video thumbnail" />
<!-- 使用 contain 进行绘制优化 -->
<div class="contain-layout">
Complex layout that doesn't affect outside elements
</div>
/* 在 v4.1 中启用 CSS 优先配置 */
@import "tailwindcss";
@theme {
/* 定义一次,随处使用 */
--color-brand: #3b82f6;
--font-mono: "Fira Code", monospace;
}
/* 针对首屏内容的关键 CSS */
@layer critical {
.hero-title {
@apply text-4xl md:text-6xl font-bold;
}
}
<!-- 符合 WCAG AA 标准的自定义焦点样式 -->
<button class="focus:outline-none focus:ring-4 focus:ring-blue-500 focus:ring-offset-2">
Accessible Button
</button>
<!-- 键盘导航的跳过链接 -->
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4">
Skip to main content
</a>
<!-- 带有 ARIA 标签的语义化按钮 -->
<button aria-label="Close dialog" class="p-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<!-- 描述性链接 -->
<a href="/docs" aria-describedby="docs-description">
Documentation
</a>
<p id="docs-description" class="sr-only">
Learn how to use our API and integration guides
</p>
<!-- 确保足够的对比度 -->
<div class="bg-gray-900 text-white">
High contrast text (WCAG AAA)
</div>
<div class="bg-blue-500 text-blue-100">
Good contrast on colored backgrounds
</div>
<!-- 使用对比度实用程序进行测试 -->
<div class="bg-red-500 text-white contrast-more:bg-red-600 contrast-more:text-red-100">
Adjusts for high contrast mode
</div>
<!-- 尊重 prefers-reduced-motion -->
<div class="transform transition-transform motion-reduce:transition-none">
Doesn't animate when user prefers reduced motion
</div>
<!-- 条件动画 -->
<div class="animate-pulse motion-safe:hover:animate-spin">
Only animates when motion is preferred
</div>
@apply@theme 指令而非 JavaScript 配置@utility 为复杂模式创建可复用的实用程序使用 @theme 指令进行基于 CSS 的配置:
/* src/styles.css */
@import "tailwindcss";
@theme {
/* 自定义颜色 */
--color-brand-50: #f0f9ff;
--color-brand-500: #3b82f6;
--color-brand-900: #1e3a8a;
/* 自定义字体 */
--font-display: "Inter", system-ui, sans-serif;
--font-mono: "Fira Code", monospace;
/* 自定义间距 */
--spacing-128: 32rem;
/* 自定义动画 */
--animate-fade-in: fadeIn 0.5s ease-in-out;
/* 自定义断点 */
--breakpoint-3xl: 1920px;
}
/* 定义自定义动画 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* 自定义实用程序 */
@utility content-auto {
content-visibility: auto;
}
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx,vue,svelte}",
],
theme: {
extend: {
colors: {
primary: {
50: '#f0f9ff',
500: '#3b82f6',
900: '#1e3a8a',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
spacing: {
'128': '32rem',
},
},
},
plugins: [],
}
// vite.config.ts
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
],
})
<div class="bg-[var(--color-brand-500)] text-[var(--color-white)]">
Using CSS custom properties directly
</div>
<!-- 带有自定义轨道的复杂网格 -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
Responsive grid without custom CSS
</div>
<!-- 自定义动画时序 -->
<div class="animate-bounce ease-[cubic-bezier(0.68,-0.55,0.265,1.55)]">
Bounce with custom easing
</div>
<!-- 响应其容器大小的组件 -->
<div class="@container">
<div class="@lg:text-xl @2xl:text-2xl">
Text size based on container, not viewport
</div>
</div>
import { useState } from 'react';
function Button({
variant = 'primary',
size = 'md',
children
}: {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
}) {
const baseClasses = 'font-semibold rounded transition';
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
};
const sizeClasses = {
sm: 'px-3 py-1 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
return (
<button
className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]}`}
>
{children}
</button>
);
}
每周安装量
2.1K
代码仓库
GitHub 星标数
173
首次出现时间
2026年1月20日
安全审计
安装于
opencode1.8K
gemini-cli1.7K
codex1.7K
cursor1.6K
claude-code1.6K
github-copilot1.6K
Expert guide for building modern, responsive user interfaces with Tailwind CSS utility-first framework. Covers v4.1+ features including CSS-first configuration, custom utilities, and enhanced developer experience.
function ProductCard({ product }: { product: Product }) {
return (
<div className="bg-white rounded-lg shadow-lg overflow-hidden
sm:flex sm:max-w-2xl">
<img
className="h-48 w-full object-cover sm:h-auto sm:w-48"
src={product.image}
alt={product.name}
/>
<div className="p-6">
<h3 className="text-lg font-semibold text-gray-900">
{product.name}
</h3>
<p className="mt-2 text-gray-600">
{product.description}
</p>
<button className="mt-4 px-4 py-2 bg-indigo-600 text-white
rounded-lg hover:bg-indigo-700 transition">
Add to Cart
</button>
</div>
</div>
);
}
@apply with complex selectorsApply styles directly in markup using utility classes:
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Click me
</button>
Mobile-first breakpoints with prefixes:
<div class="w-full md:w-1/2 lg:w-1/3">
<!-- Full width on mobile, half on tablet, third on desktop -->
</div>
Breakpoint prefixes:
sm: - 640px and abovemd: - 768px and abovelg: - 1024px and abovexl: - 1280px and above2xl: - 1536px and aboveBasic flex container:
<div class="flex items-center justify-between">
<div>Left</div>
<div>Center</div>
<div>Right</div>
</div>
Responsive flex direction:
<div class="flex flex-col md:flex-row gap-4">
<div class="flex-1">Item 1</div>
<div class="flex-1">Item 2</div>
<div class="flex-1">Item 3</div>
</div>
Common flex patterns:
<!-- Center content -->
<div class="flex items-center justify-center min-h-screen">
<div>Centered Content</div>
</div>
<!-- Space between items -->
<div class="flex justify-between items-center">
<span>Left</span>
<span>Right</span>
</div>
<!-- Vertical stack with gap -->
<div class="flex flex-col gap-4">
<div>Item 1</div>
<div>Item 2</div>
</div>
Basic grid:
<div class="grid grid-cols-3 gap-4">
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>
Responsive grid:
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- 1 column mobile, 2 tablet, 4 desktop -->
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
Auto-fit columns:
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
<!-- Automatically fit columns based on container width -->
</div>
Centered container with max width:
<div class="container mx-auto px-4 max-w-7xl">
<!-- Centered content with padding -->
</div>
Responsive max width:
<div class="w-full max-w-md mx-auto">
<!-- Max 448px width, centered -->
</div>
Uniform spacing:
<div class="p-4">Padding all sides</div>
<div class="m-4">Margin all sides</div>
Individual sides:
<div class="pt-4 pr-8 pb-4 pl-8">
<!-- Top 1rem, Right 2rem, Bottom 1rem, Left 2rem -->
</div>
Axis-based spacing:
<div class="px-4 py-8">
<!-- Horizontal padding 1rem, Vertical padding 2rem -->
</div>
Responsive spacing:
<div class="p-4 md:p-8 lg:p-12">
<!-- Increases padding at larger breakpoints -->
</div>
Space between children:
<div class="space-y-4">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<h1 class="text-4xl font-bold">Large Heading</h1>
<h2 class="text-2xl font-semibold">Subheading</h2>
<p class="text-base font-normal">Body text</p>
<small class="text-sm text-gray-600">Small text</small>
Responsive typography:
<h1 class="text-2xl md:text-4xl lg:text-6xl font-bold">
Responsive Heading
</h1>
<p class="leading-relaxed tracking-wide">
Text with relaxed line height and wide letter spacing
</p>
<p class="text-left md:text-center">
Left aligned on mobile, centered on tablet+
</p>
<div class="bg-blue-500">Blue background</div>
<div class="bg-gray-100">Light gray background</div>
<div class="bg-gradient-to-r from-blue-500 to-purple-600">
Gradient background
</div>
<p class="text-gray-900">Dark text</p>
<p class="text-blue-600">Blue text</p>
<p class="text-red-500">Error text</p>
<div class="bg-blue-500 bg-opacity-50">
Semi-transparent blue
</div>
<button class="bg-blue-500 hover:bg-blue-700 transition">
Hover me
</button>
<a class="text-blue-600 hover:text-blue-800 hover:underline">
Hover link
</a>
<input class="border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 outline-none">
<button class="bg-blue-500 active:bg-blue-800 disabled:opacity-50 disabled:cursor-not-allowed">
Button
</button>
<div class="group">
<img class="group-hover:opacity-75" src="image.jpg" />
<p class="group-hover:text-blue-600">Hover the parent</p>
</div>
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<img class="w-full h-48 object-cover" src="image.jpg" alt="Card image" />
<div class="p-6">
<h3 class="text-xl font-bold mb-2">Card Title</h3>
<p class="text-gray-700 mb-4">Card description text goes here.</p>
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Action
</button>
</div>
</div>
<div class="max-w-sm mx-auto bg-white rounded-xl shadow-lg overflow-hidden sm:flex sm:max-w-2xl">
<img class="h-48 w-full object-cover sm:h-auto sm:w-48"
src="profile.jpg"
alt="Profile" />
<div class="p-8">
<div class="uppercase tracking-wide text-sm text-indigo-500 font-semibold">
Product Engineer
</div>
<h2 class="mt-1 text-xl font-semibold text-gray-900">
John Doe
</h2>
<p class="mt-2 text-gray-500">
Building amazing products with modern technology.
</p>
<button class="mt-4 px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
Contact
</button>
</div>
</div>
<nav class="bg-white shadow-lg">
<div class="container mx-auto px-4">
<div class="flex justify-between items-center h-16">
<div class="flex items-center">
<a href="#" class="text-xl font-bold text-gray-800">Logo</a>
</div>
<div class="hidden md:flex space-x-8">
<a href="#" class="text-gray-700 hover:text-blue-600 transition">Home</a>
<a href="#" class="text-gray-700 hover:text-blue-600 transition">About</a>
<a href="#" class="text-gray-700 hover:text-blue-600 transition">Services</a>
<a href="#" class="text-gray-700 hover:text-blue-600 transition">Contact</a>
</div>
<button class="md:hidden">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
</div>
</div>
</nav>
<form class="space-y-6 max-w-md mx-auto">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Email
</label>
<input
type="email"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="you@example.com"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Password
</label>
<input
type="password"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div class="flex items-center">
<input type="checkbox" class="mr-2" />
<label class="text-sm text-gray-600">Remember me</label>
</div>
<button
type="submit"
class="w-full bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg hover:bg-blue-700 transition"
>
Sign In
</button>
</form>
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4">
<div class="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold">Modal Title</h3>
<button class="text-gray-500 hover:text-gray-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
<p class="text-gray-700 mb-6">
Modal content goes here.
</p>
<div class="flex justify-end space-x-4">
<button class="px-4 py-2 text-gray-600 hover:text-gray-800">
Cancel
</button>
<button class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
Confirm
</button>
</div>
</div>
</div>
<div class="container mx-auto px-4">
<!-- Hero Section -->
<div class="flex flex-col md:flex-row items-center gap-8 py-12">
<div class="flex-1">
<h1 class="text-3xl md:text-5xl font-bold mb-4">
Welcome to Our Site
</h1>
<p class="text-lg text-gray-600 mb-6">
Build amazing things with Tailwind CSS
</p>
<button class="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700">
Get Started
</button>
</div>
<div class="flex-1">
<img src="hero.jpg" class="w-full rounded-lg shadow-lg" />
</div>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 p-4">
<div class="aspect-square bg-gray-200 rounded-lg overflow-hidden">
<img src="image1.jpg" class="w-full h-full object-cover hover:scale-105 transition" />
</div>
<div class="aspect-square bg-gray-200 rounded-lg overflow-hidden">
<img src="image2.jpg" class="w-full h-full object-cover hover:scale-105 transition" />
</div>
<!-- More items... -->
</div>
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
<h1 class="text-gray-900 dark:text-white">Title</h1>
<p class="text-gray-600 dark:text-gray-400">Description</p>
</div>
Enable dark mode in tailwind.config.js:
module.exports = {
darkMode: 'class', // or 'media'
// ...
}
<button class="bg-blue-500 hover:bg-blue-700 transition duration-300">
Smooth transition
</button>
<div class="transform hover:scale-110 transition duration-300">
Scale on hover
</div>
<img class="transform hover:rotate-6 transition duration-300" />
<div class="animate-spin">Spinning</div>
<div class="animate-pulse">Pulsing</div>
<div class="animate-bounce">Bouncing</div>
Configure content sources for optimal purging:
// tailwind.config.js
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx,vue,svelte}",
"./node_modules/@mycompany/ui-lib/**/*.{js,ts,jsx,tsx}",
],
// Enable JIT for faster builds
jit: true,
}
<!-- Use content-visibility for offscreen content -->
<div class="content-visibility-auto">
<div>Heavy content that's initially offscreen</div>
</div>
<!-- Optimize images with aspect-ratio -->
<img class="aspect-video w-full object-cover" src="video.jpg" alt="Video thumbnail" />
<!-- Use contain for paint optimization -->
<div class="contain-layout">
Complex layout that doesn't affect outside elements
</div>
/* Enable CSS-first configuration in v4.1 */
@import "tailwindcss";
@theme {
/* Define once, use everywhere */
--color-brand: #3b82f6;
--font-mono: "Fira Code", monospace;
}
/* Critical CSS for above-the-fold content */
@layer critical {
.hero-title {
@apply text-4xl md:text-6xl font-bold;
}
}
<!-- Custom focus styles that meet WCAG AA -->
<button class="focus:outline-none focus:ring-4 focus:ring-blue-500 focus:ring-offset-2">
Accessible Button
</button>
<!-- Skip links for keyboard navigation -->
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4">
Skip to main content
</a>
<!-- Semantic buttons with ARIA labels -->
<button aria-label="Close dialog" class="p-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<!-- Descriptive links -->
<a href="/docs" aria-describedby="docs-description">
Documentation
</a>
<p id="docs-description" class="sr-only">
Learn how to use our API and integration guides
</p>
<!-- Ensure sufficient contrast ratios -->
<div class="bg-gray-900 text-white">
High contrast text (WCAG AAA)
</div>
<div class="bg-blue-500 text-blue-100">
Good contrast on colored backgrounds
</div>
<!-- Use contrast utilities for testing -->
<div class="bg-red-500 text-white contrast-more:bg-red-600 contrast-more:text-red-100">
Adjusts for high contrast mode
</div>
<!-- Respect prefers-reduced-motion -->
<div class="transform transition-transform motion-reduce:transition-none">
Doesn't animate when user prefers reduced motion
</div>
<!-- Conditional animations -->
<div class="animate-pulse motion-safe:hover:animate-spin">
Only animates when motion is preferred
</div>
@apply for better maintainability@theme directive for v4.1+ instead of JavaScript config@utility for complex patternsUse the @theme directive for CSS-based configuration:
/* src/styles.css */
@import "tailwindcss";
@theme {
/* Custom colors */
--color-brand-50: #f0f9ff;
--color-brand-500: #3b82f6;
--color-brand-900: #1e3a8a;
/* Custom fonts */
--font-display: "Inter", system-ui, sans-serif;
--font-mono: "Fira Code", monospace;
/* Custom spacing */
--spacing-128: 32rem;
/* Custom animations */
--animate-fade-in: fadeIn 0.5s ease-in-out;
/* Custom breakpoints */
--breakpoint-3xl: 1920px;
}
/* Define custom animations */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Custom utilities */
@utility content-auto {
content-visibility: auto;
}
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx,vue,svelte}",
],
theme: {
extend: {
colors: {
primary: {
50: '#f0f9ff',
500: '#3b82f6',
900: '#1e3a8a',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
spacing: {
'128': '32rem',
},
},
},
plugins: [],
}
// vite.config.ts
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
],
})
<div class="bg-[var(--color-brand-500)] text-[var(--color-white)]">
Using CSS custom properties directly
</div>
<!-- Complex grid with custom tracks -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
Responsive grid without custom CSS
</div>
<!-- Custom animation timing -->
<div class="animate-bounce ease-[cubic-bezier(0.68,-0.55,0.265,1.55)]">
Bounce with custom easing
</div>
<!-- Component that responds to its container size -->
<div class="@container">
<div class="@lg:text-xl @2xl:text-2xl">
Text size based on container, not viewport
</div>
</div>
import { useState } from 'react';
function Button({
variant = 'primary',
size = 'md',
children
}: {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
}) {
const baseClasses = 'font-semibold rounded transition';
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
};
const sizeClasses = {
sm: 'px-3 py-1 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
return (
<button
className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]}`}
>
{children}
</button>
);
}
Weekly Installs
2.1K
Repository
GitHub Stars
173
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode1.8K
gemini-cli1.7K
codex1.7K
cursor1.6K
claude-code1.6K
github-copilot1.6K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装