Tailwind CSS 综合实战
我们要做什么
本篇把前面学过的知识串起来,从零搭一个小型页面,包含:
- 顶部导航栏(Flex 布局、hover 态)
- 卡片列表(Grid 响应式、gap 间距)
- 按钮(用
@apply复用、带 hover 态) - 一个表单(focus 态、状态变体)
- 深色模式切换(基于
@custom-variant)
设计令牌
先在 CSS 里用 @theme 定好品牌色与字体,再用 @custom-variant 定义手动深色模式。
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--color-brand: #4f46e5;
--color-brand-hover: #4338ca;
--font-display: "Inter", "PingFang SC", sans-serif;
}
@layer components {
.btn {
@apply px-4 py-2 rounded bg-brand text-white font-medium transition-colors;
}
.btn:hover {
@apply bg-brand-hover;
}
.card {
@apply rounded-lg border border-gray-200 p-4 shadow-sm bg-white dark:bg-gray-800 dark:border-gray-700;
}
}
这里深色模式靠在 <html> 上切换 dark 类触发,dark: 前缀就能生效。
页面结构
下面是完整 HTML,所有样式都来自工具类或上面定义的组件类。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>综合实战示例</title>
<link rel="stylesheet" href="./style.css">
</head>
<body class="font-display bg-gray-50 text-gray-900 dark:bg-gray-900 dark:text-gray-100 min-h-screen">
<nav class="flex items-center justify-between px-6 py-4 bg-white dark:bg-gray-800 shadow">
<span class="text-xl font-bold text-brand">MyApp</span>
<div class="flex gap-4 items-center">
<a href="#" class="hover:text-brand transition-colors">首页</a>
<a href="#" class="hover:text-brand transition-colors">文档</a>
<button onclick="document.documentElement.classList.toggle('dark')" class="btn">
切换深色
</button>
</div>
</nav>
<main class="max-w-5xl mx-auto px-6 py-8">
<h1 class="text-3xl font-bold mb-6">卡片列表</h1>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="card">
<h2 class="font-semibold mb-2">卡片一</h2>
<p class="text-sm text-gray-600 dark:text-gray-300">这是一段说明文字。</p>
<button class="btn mt-4">查看</button>
</div>
<div class="card">
<h2 class="font-semibold mb-2">卡片二</h2>
<p class="text-sm text-gray-600 dark:text-gray-300">这是一段说明文字。</p>
<button class="btn mt-4">查看</button>
</div>
<div class="card">
<h2 class="font-semibold mb-2">卡片三</h2>
<p class="text-sm text-gray-600 dark:text-gray-300">这是一段说明文字。</p>
<button class="btn mt-4">查看</button>
</div>
</div>
<h2 class="text-2xl font-bold mt-10 mb-4">订阅表单</h2>
<form class="card max-w-md space-y-4">
<input
type="email"
placeholder="输入邮箱"
class="w-full px-3 py-2 rounded border border-gray-300 focus:outline-none focus:ring-2 focus:ring-brand dark:bg-gray-700 dark:border-gray-600"
>
<button class="btn w-full">提交</button>
</form>
</main>
</body>
</html>
关键点拆解
导航栏
用 flex items-center justify-between 实现左右分布,hover:text-brand 提供悬停反馈。切换深色的按钮直接调用一小段内联 JS 切换 dark 类。
卡片列表
grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 实现响应式列数,gap-4 控制间距。卡片外观交给 .card 组件类,HTML 保持干净。
表单状态
输入框用 focus:ring-2 focus:ring-brand 在聚焦时显示品牌色描边,focus:outline-none 去掉默认轮廓。深色模式下通过 dark:bg-gray-700 适配背景。
深色模式
@custom-variant dark (&:where(.dark, .dark *)) 让 dark: 前缀绑定到 .dark 类,再用按钮切换该类,无需依赖系统偏好即可手动切换。
小结
这一页用到了前 10 篇与本文系列的核心能力:@theme 管令牌、@apply 做复用、@custom-variant 管深色、flex/grid 布局、响应式与状态变体。把它们组合起来就能覆盖大部分真实页面需求。