Remix Tailwind CSS #
一、Tailwind概述 #
Tailwind CSS 是一个功能类优先的 CSS 框架,提供原子化的 CSS 类,让你快速构建用户界面。
二、安装配置 #
2.1 安装依赖 #
bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
2.2 配置Tailwind #
编辑 tailwind.config.js:
javascript
/** @type {import('tailwindcss').Config} */
export default {
content: ["./app/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
},
},
},
},
plugins: [],
};
2.3 创建CSS文件 #
创建 app/tailwind.css:
css
@tailwind base;
@tailwind components;
@tailwind utilities;
2.4 在根组件中导入 #
编辑 app/root.tsx:
tsx
import type { LinksFunction } from "@remix-run/node";
import stylesheet from "~/tailwind.css?url";
export const links: LinksFunction = () => [
{ rel: "stylesheet", href: stylesheet },
];
三、基本使用 #
3.1 布局 #
tsx
export default function Page() {
return (
<div className="min-h-screen bg-gray-100">
<div className="container mx-auto px-4 py-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* 卡片 */}
</div>
</div>
</div>
);
}
3.2 排版 #
tsx
export default function Article({ post }) {
return (
<article className="prose prose-lg max-w-none">
<h1 className="text-3xl font-bold text-gray-900 mb-4">
{post.title}
</h1>
<p className="text-gray-600 mb-6">{post.excerpt}</p>
<div className="prose">
{post.content}
</div>
</article>
);
}
3.3 表单 #
tsx
export default function ContactForm() {
return (
<form className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
姓名
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<button
type="submit"
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
提交
</button>
</form>
);
}
四、自定义配置 #
4.1 扩展主题 #
javascript
export default {
theme: {
extend: {
colors: {
brand: {
light: '#3fbaeb',
DEFAULT: '#0fa9e6',
dark: '#0c87b8',
},
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
mono: ['Fira Code', 'monospace'],
},
spacing: {
'128': '32rem',
'144': '36rem',
},
},
},
};
4.2 添加插件 #
bash
npm install -D @tailwindcss/forms @tailwindcss/typography
javascript
import forms from '@tailwindcss/forms';
import typography from '@tailwindcss/typography';
export default {
plugins: [
forms,
typography,
],
};
4.3 自定义组件类 #
css
/* app/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn {
@apply px-4 py-2 rounded-md font-medium transition-colors;
}
.btn-primary {
@apply btn bg-blue-600 text-white hover:bg-blue-700;
}
.btn-secondary {
@apply btn bg-gray-200 text-gray-800 hover:bg-gray-300;
}
.card {
@apply bg-white rounded-lg shadow-md p-6;
}
}
五、响应式设计 #
5.1 断点 #
| 断点 | 最小宽度 |
|---|---|
sm |
640px |
md |
768px |
lg |
1024px |
xl |
1280px |
2xl |
1536px |
5.2 响应式组件 #
tsx
export default function Navbar() {
return (
<nav className="bg-white shadow">
<div className="container mx-auto px-4">
<div className="flex justify-between items-center h-16">
<div className="flex-shrink-0">
<span className="text-xl font-bold">Logo</span>
</div>
{/* 移动端隐藏,桌面端显示 */}
<div className="hidden md:flex space-x-4">
<a href="#" className="text-gray-700 hover:text-blue-600">
首页
</a>
<a href="#" className="text-gray-700 hover:text-blue-600">
关于
</a>
</div>
{/* 移动端菜单按钮 */}
<button className="md:hidden">
<span>菜单</span>
</button>
</div>
</div>
</nav>
);
}
六、深色模式 #
6.1 配置 #
javascript
export default {
darkMode: 'class',
// ...
};
6.2 使用 #
tsx
export default function Card() {
return (
<div className="bg-white dark:bg-gray-800 text-gray-900 dark:text-white p-6 rounded-lg shadow">
<h2 className="text-xl font-bold mb-2">标题</h2>
<p className="text-gray-600 dark:text-gray-300">内容</p>
</div>
);
}
6.3 切换主题 #
tsx
import { useState, useEffect } from "react";
export function ThemeToggle() {
const [isDark, setIsDark] = useState(false);
useEffect(() => {
if (isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}, [isDark]);
return (
<button
onClick={() => setIsDark(!isDark)}
className="p-2 rounded-lg bg-gray-200 dark:bg-gray-700"
>
{isDark ? '🌙' : '☀️'}
</button>
);
}
七、动画 #
7.1 内置动画 #
tsx
<button className="animate-pulse">脉冲</button>
<button className="animate-spin">旋转</button>
<button className="animate-bounce">弹跳</button>
7.2 自定义动画 #
javascript
export default {
theme: {
extend: {
animation: {
'fade-in': 'fadeIn 0.3s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
},
},
},
};
八、最佳实践 #
8.1 提取组件 #
tsx
function Button({ variant = 'primary', children }) {
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
danger: 'bg-red-600 text-white hover:bg-red-700',
};
return (
<button className={`px-4 py-2 rounded-md font-medium ${variants[variant]}`}>
{children}
</button>
);
}
8.2 使用clsx #
tsx
import clsx from 'clsx';
function Card({ highlighted, children }) {
return (
<div
className={clsx(
'p-6 rounded-lg shadow-md',
highlighted ? 'bg-blue-50 border-blue-200' : 'bg-white'
)}
>
{children}
</div>
);
}
8.3 组织样式 #
tsx
const styles = {
container: 'min-h-screen bg-gray-100',
header: 'bg-white shadow',
main: 'container mx-auto px-4 py-8',
footer: 'bg-gray-800 text-white',
};
export default function Layout() {
return (
<div className={styles.container}>
<header className={styles.header}>...</header>
<main className={styles.main}>...</main>
<footer className={styles.footer}>...</footer>
</div>
);
}
九、总结 #
本章我们学习了:
- 安装配置:设置Tailwind CSS
- 基本使用:布局、排版、表单
- 自定义配置:主题、插件、组件类
- 响应式:断点和响应式组件
- 深色模式:配置和使用
核心要点:
- 使用原子类快速构建UI
- 提取可复用组件
- 使用clsx组合类名
- 配置主题保持一致性
最后更新:2026-03-28