关于 modern-ui-designer
面向界面开发者的设计技能,涵盖 Tailwind CSS 与 shadcn/ui 的现代界面实践,并结合极简视觉、8px 间距网格、响应式布局和 WCAG 无障碍指南。
主要功能
- 01Tailwind CSS 与 shadcn/ui 模式
- 02极简视觉层级
- 038px 网格间距指南
- 04移动优先响应式设计
- 05WCAG 无障碍实践
适用场景
- 01设计统一的页面与组件布局
- 02检查色彩对比度和键盘访问
- 03使用 Tailwind CSS 构建响应式界面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sitechfromgeorgia/ georgian-distribution-system --skill modern-ui-designer安装后在 Claude Code 中输入/modern-ui-designer确认已加载。
附带文件SETUP_GUIDE.md
详细介绍
现代 UI 设计师 - 2025 标准
概述
本技能全面介绍如何按照现代 2025 标准创建一流的 UI 设计,涵盖 Tailwind CSS 最佳实践、shadcn/ui 组件模式、简洁极简的设计原则、8px 网格间距系统、移动优先的响应式设计,以及符合 WCAG 的无障碍要求。
核心理念:专业、简约、无障碍且一致。
设计原则(2025)
1. 简洁极简
核心规则:
- 去除不必要的元素:每个元素都必须有明确的用途
- 留白的力量:充足的间距可提升可读性并减轻认知负担
- 内容优先:设计服务于内容,而非反过来
- 视觉层级:利用尺寸、颜色和间距引导注意力
- 含蓄胜过浮夸:专业设计讲求克制
应避免的做法:
- ❌ 彩虹渐变或过多颜色
- ❌ 没有实际作用的装饰元素
- ❌ 复杂的图案或纹理
- ❌ 过于拥挤的界面
- ❌ 不一致的间距
应采用的做法:
- ✅ 中性色调(灰色 + 一种强调色)
- ✅ 充足的留白和舒适的空间
- ✅ 层级清晰的简洁排版
- ✅ 微妙的阴影和边框
- ✅ 统一的 8px 网格系统
2. 视觉层级最佳实践
尺寸:
- 标题与正文之间采用明显的尺寸差异
- 正文至少为 16px(为提高可读性,建议使用 18px)
- 标题字号比例:48px → 32px → 24px → 20px → 18px → 16px
- 使用 Tailwind 的 text-* 工具类:text-6xl、text-4xl、text-2xl、text-xl、text-lg、text-base
颜色:
- 策略性地使用颜色来体现重要性
- 主要操作:强调色
- 次要操作:中性灰色
- 禁用状态:低对比度灰色
- 错误状态:红色(确保对比度符合无障碍要求)
- 成功状态:绿色(确保对比度符合无障碍要求)
字重:
- 标题:font-bold (700) 或 font-semibold (600)
- 正文:font-normal (400) 或 font-medium (500)
- 说明文字:font-light (300),谨慎使用
间距:
- 大间距(32px 及以上)用于分隔主要区域
- 中间距(16-24px)用于组合相关内容
- 小间距(8px)用于紧密关联的元素
- 内部 ≤ 外部原则:元素内部的间距应小于元素之间的间距
8px 网格系统
核心概念
所有间距、尺寸和布局都必须采用 8 的倍数:
- 基本单位:8px、16px、24px、32px、40px、48px、56px、64px、72px、80px
- 半单位:4px(仅用于图标、边框或微调)
- 切勿使用:7px、13px、25px 或其他不符合规范的数值
为什么是 8px?
- 设备兼容性:大多数屏幕分辨率都能被 8 整除
- 缩放:在 @1x、@2x、@3x 显示屏上都能完美适配
- 视觉一致性:便于直观判断并保持节奏
- 开发者友好:减少从设计到代码的转换误差
Tailwind CSS 间距比例
Tailwind 的间距比例与 8px 网格完美吻合:
0 → 0px
0.5 → 2px (exception for borders)
1 → 4px (half unit)
2 → 8px (base)
3 → 12px (1.5 units, use sparingly)
4 → 16px (2 units)
5 → 20px (2.5 units, use sparingly)
6 → 24px (3 units)
8 → 32px (4 units)
10 → 40px (5 units)
12 → 48px (6 units)
16 → 64px (8 units)
20 → 80px (10 units)
24 → 96px (12 units)
32 → 128px (16 units)
推荐的间距取值:
- 内边距:p-2、p-4、p-6、p-8、p-12、p-16
- 外边距:m-2、m-4、m-6、m-8、m-12、m-16
- 间隔:gap-2、gap-4、gap-6、gap-8
间距层级(邻近原则)
紧密关联(8px - 16px):
<div class="space-y-2">
<h3 class="text-xl font-semibold">Heading</h3>
<p class="text-gray-600">Subheading</p>
</div>
相关内容(24px - 32px):
<div class="space-y-6">
<section></section>
<section></section>
</div>
分隔区域(48px - 64px):
<div class="space-y-12 md:space-y-16">
<section></section>
<section></section>
</div>
使用 8px 网格设置组件尺寸
按钮:
- 小号:h-8 (32px),搭配 px-3 py-1.5
- 中号:h-10 (40px),搭配 px-4 py-2
- 大号:h-12 (48px),搭配 px-6 py-3
- 超大号:h-14 (56px),搭配 px-8 py-4
输入框:
- 高度:h-10 (40px) 或 h-12 (48px)
- 内边距:px-3 py-2 或 px-4 py-3
卡片:
- 内边距:根据内容使用 p-4、p-6 或 p-8
- 边框圆角:rounded-md (6px)、rounded-lg (8px)、rounded-xl (12px)
颜色系统(中性色 + 强调色)
中性色板方案
基础策略:灰阶 + 一种强调色
灰阶(Tailwind):
slate-50 → Backgrounds
slate-100 → Subtle backgrounds
slate-200 → Borders, dividers
slate-300 → Disabled text
slate-400 → Placeholder text
slate-500 → Secondary text
slate-600 → Body text
slate-700 → Headings
slate-800 → Emphasis
slate-900 → Maximum contrast
强调色选择:
- 选择一种主要品牌色
- 用于:主要按钮、链接、激活状态、高亮
- 所需色阶:50、100、200、300、400、500、600、700、800、900
- 示例:主要颜色使用 blue-600,悬停时使用 blue-700
语义颜色(尽量少用)
<div class="bg-green-50 text-green-700 border border-green-200">
<div class="bg-yellow-50 text-yellow-800 border border-yellow-200">
<div class="bg-red-50 text-red-700 border border-red-200">
<div class="bg-blue-50 text-blue-700 border border-blue-200">
深色模式支持
<div class="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-50">
<div class="border border-slate-200 dark:border-slate-800">
<div class="bg-slate-50 dark:bg-slate-800">
<button class="bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">
颜色对比度规则(WCAG)
文本对比度:
- 普通文本(< 24px):至少 4.5:1
- 大号文本(≥ 24px):至少 3:1
- UI 组件和图形:至少 3:1
安全搭配:
✅ slate-900 on white → 18.9:1
✅ slate-700 on white → 8.6:1
✅ slate-600 on white → 6.2:1
✅ blue-600 on white → 5.4:1
❌ slate-400 on white → 2.9:1 (fails)
❌ slate-300 on white → 1.7:1 (fails)
Tailwind CSS 最佳实践(2025)
1. 实用优先方法
应该做:
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
transition-colors duration-200">
Click me
</button>
不应该做:
/* ❌ Avoid custom CSS unless absolutely necessary */
.custom-button {
padding: 0.5rem 1rem;
background: #3b82f6;
/* ... */
}
2. 使用 @apply 提取组件(谨慎使用)
仅在以下情况下使用 @apply:
- 使用 10 次以上的组件
- 覆盖第三方库样式
- 打印样式表
/* ✅ Good use of @apply */
@layer components {
.btn-primary {
@apply px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500;
}
}
3. 响应式设计(移动优先)
断点:
sm: 640px → Small tablets
md: 768px → Tablets
lg: 1024px → Desktop
xl: 1280px → Large desktop
2xl: 1536px → Extra large
模式:
<div class="p-4 md:p-6 lg:p-8">
<h1 class="text-2xl md:text-3xl lg:text-4xl">
Responsive Heading
</h1>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6">
</div>
4. 状态变体
悬停、聚焦、激活:
<button class="bg-blue-600 hover:bg-blue-700 active:bg-blue-800
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed">
深色模式:
<div class="bg-white dark:bg-slate-900
text-slate-900 dark:text-slate-50
border border-slate-200 dark:border-slate-800">
5. 类名组织(顺序一致)
标准顺序:
- 布局(display、position、overflow)
- 尺寸(width、height)
- 间距(margin、padding)
- 排版(font、text)
- 视觉效果(background、border)
- 效果(shadow、opacity)
- 过渡效果
- 变体(hover、focus、dark)
<div class="
flex items-center justify-between
w-full max-w-screen-lg
px-4 py-3 my-2
text-lg font-medium text-gray-800
bg-white rounded shadow
hover:shadow-md
transition-shadow
">
6. JIT 模式与清除未使用样式
始终启用 JIT(即时模式):
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx}',
'./components/**/*.{html,js,jsx,ts,tsx}',
],
// ... rest of config
}
优点:
- 更小的 CSS 包
- 任意值:
w-[373px] - 支持所有变体
- 更快的构建时间
shadcn/ui 组件模式
理解架构
shadcn/ui = Radix UI + Tailwind CSS + CVA:
- Radix UI:无样式、可访问的基础组件
- Tailwind CSS:实用优先的样式
- CVA(Class Variance Authority):变体管理
核心模式:复制、拥有、自定义
不是一个包:将组件源代码复制到项目中
- 完全拥有代码
- 不会遇到破坏性更新
- 完全自定义
- 类型安全的变体
组件剖析示例
// Button.tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
// Base styles (always applied)
"inline-flex items-center justify-center rounded-lg font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-slate-900 text-slate-50 hover:bg-slate-800",
outline: "border border-slate-200 bg-transparent hover:bg-slate-100",
ghost: "hover:bg-slate-100",
},
size: {
sm: "h-8 px-3 text-sm",
md: "h-10 px-4",
lg: "h-12 px-6 text-lg",
},
},
defaultVariants: {
variant: "default",
size: "md",
},
}
)
interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
export const Button = ({ className, variant, size, ...props }: ButtonProps) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
)
}
shadcn/ui 最佳实践
1. 使用 cn() 工具合并类名:
import { cn } from "@/lib/utils"
// Allows className override
<Button className={cn("custom-class", conditionalClass && "other-class")} />
2. 设计系统集成:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
// ... more design tokens
},
},
},
}
3. 使用 CSS 变量进行主题设置:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--border: 217.2 32.6% 17.5%;
}
常见模式
带标签的表单字段:
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="[email protected]"
className="w-full"
/>
<p className="text-sm text-slate-500">
We'll never share your email.
</p>
</div>
卡片布局:
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description goes here</CardDescription>
</CardHeader>
<CardContent>
</CardContent>
<CardFooter>
</CardFooter>
</Card>
对话框模式:
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>
Dialog description text
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button variant="outline">Cancel</Button>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>
无障碍访问(符合 WCAG 2.2)
四项原则(POUR)
1. 可感知:
- 为图像提供文本替代内容
- 为视频添加字幕
- 内容结构应可调整
- 颜色对比度应充足
2. 可操作:
- 支持键盘访问
- 不得存在键盘陷阱
- 提供充足的交互时间
- 不包含会诱发癫痫的内容
3. 易理解:
- 文本清晰易读
- 行为可预测
- 提供输入辅助并防止错误
4. 稳健:
- 兼容辅助技术
- 使用有效的 HTML
- 使用正确的 ARIA 属性
关键要求
键盘导航:
<button
class="focus:outline-none focus:ring-2 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-0 focus:left-0">
Skip to main content
</a>
焦点指示器(WCAG 2.2):
- 必须清晰可见
- 厚度至少为 2px
- 相对于背景的对比度至少为 3:1
- 使用
focus:ring-2和focus:ring-offset-2
触控目标:
- 至少为 44x44px(WCAG 2.1)
- 间距至少为 24x24px(WCAG 2.2)
- 对交互元素使用
min-h-[44px] min-w-[44px]
颜色对比度:
<p class="text-slate-700">Body text</p>
<button class="bg-blue-600 text-white">Action</button>
<p class="text-slate-400">Fails WCAG</p>
语义化 HTML:
<header>
<nav aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>Page Title</h1>
<section>
<h2>Section Heading</h2>
</section>
</article>
</main>
<footer>
</footer>
ARIA 标签:
<button aria-label="Close dialog" class="...">
<XIcon className="h-4 w-4" aria-hidden="true" />
</button>
<label for="search" class="sr-only">Search</label>
<input id="search" type="search" />
<div role="status" aria-live="polite" aria-atomic="true">
Loading...
</div>
表单无障碍访问:
<form>
<div>
<label for="email" class="block text-sm font-medium mb-2">
Email
<span class="text-red-600" aria-label="required">*</span>
</label>
<input
id="email"
type="email"
required
aria-required="true"
aria-describedby="email-error"
aria-invalid={hasError ? "true" : "false"}
class="w-full"
/>
{hasError && (
<p id="email-error" class="text-sm text-red-600 mt-1" role="alert">
Please enter a valid email address
</p>
)}
</div>
</form>
移动优先的响应式设计
策略
从移动设备开始(320px - 640px):
- 优先针对最小屏幕进行设计
- 针对触控交互进行优化
- 优先考虑内容层级
- 逐步增强对更大屏幕的支持
响应式模式
容器宽度:
<div class="container mx-auto px-4 md:px-6 lg:px-8 max-w-7xl">
</div>
排版比例:
<h1 class="text-3xl md:text-4xl lg:text-5xl font-bold">
Responsive Heading
</h1>
<p class="text-base md:text-lg leading-relaxed">
Body text with responsive sizing
</p>
网格布局:
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 lg:gap-6">
<div></div>
<div></div>
<div></div>
</div>
响应式 Flexbox:
<div class="flex flex-col md:flex-row gap-4 md:gap-6">
<div class="flex-1"></div>
<div class="flex-1"></div>
</div>
可见性控制:
<div class="hidden md:block">
Desktop only content
</div>
<div class="block md:hidden">
Mobile only content
</div>
导航模式:
<nav>
<button class="md:hidden">
<MenuIcon />
</button>
<ul class="hidden md:flex md:space-x-4">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
排版系统
字体选择
现代专业字体:
- 无衬线字体:Inter, SF Pro, -apple-system, system-ui
- 等宽字体:JetBrains Mono, Fira Code, SF Mono
// tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
},
},
}
字号比例(基于 8px)
text-xs → 12px (line-height: 16px)
text-sm → 14px (line-height: 20px)
text-base → 16px (line-height: 24px) ← Body text default
text-lg → 18px (line-height: 28px)
text-xl → 20px (line-height: 28px)
text-2xl → 24px (line-height: 32px)
text-3xl → 30px (line-height: 36px)
text-4xl → 36px (line-height: 40px)
text-5xl → 48px (line-height: 48px)
text-6xl → 60px (line-height: 60px)
行高
始终使用与 8px 对齐的行高:
<p class="text-base leading-6">
<h2 class="text-3xl leading-9">
文本层级示例
<article class="space-y-6">
<h1 class="text-4xl md:text-5xl font-bold text-slate-900 leading-tight">
Article Title
</h1>
<p class="text-xl text-slate-600 leading-relaxed">
Engaging subtitle or description
</p>
<div class="flex items-center gap-4 text-sm text-slate-500">
<span>By Author Name</span>
<span>•</span>
<time datetime="2025-01-15">Jan 15, 2025</time>
</div>
<div class="prose prose-slate max-w-none">
<p class="text-base leading-relaxed text-slate-700">
Body paragraph with comfortable reading size and spacing...
</p>
</div>
</article>
阴影与层级
阴影系统(低调专业)
<div class="shadow-sm">
<div class="shadow">
<div class="shadow-md">
<div class="shadow-lg">
<div class="shadow-xl">
<div class="shadow-[0_2px_8px_rgba(0,0,0,0.08)]">
现代模式:将阴影与边框结合使用
<div class="border border-slate-200 shadow-sm rounded-lg">
</div>
层级状态
<div class="border border-slate-200 shadow-sm hover:shadow-md
transition-shadow duration-200 rounded-lg">
Hover me
</div>
圆角指南
统一圆角
rounded-none → 0px
rounded-sm → 2px (subtle, modern)
rounded → 4px (default)
rounded-md → 6px (cards)
rounded-lg → 8px (buttons, inputs) ← Preferred
rounded-xl → 12px (large cards)
rounded-2xl → 16px (hero sections)
rounded-full → 9999px (circles, pills)
2025 年趋势:更大、更柔和的圆角(8px - 12px)
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg">
<div class="border border-slate-200 rounded-xl p-6">
<img class="h-10 w-10 rounded-full" />
组件设计示例
现代按钮
<button class="
inline-flex items-center justify-center
h-10 px-4
text-base font-medium
bg-blue-600 text-white
rounded-lg
hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
active:bg-blue-800
disabled:opacity-50 disabled:cursor-not-allowed
transition-colors duration-200
">
Primary Action
</button>
<button class="
inline-flex items-center justify-center
h-10 px-4
text-base font-medium
border border-slate-300 bg-white text-slate-700
rounded-lg
hover:bg-slate-50
focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed
transition-colors duration-200
">
Secondary Action
</button>
<button class="
inline-flex items-center justify-center
h-10 px-4
text-base font-medium text-slate-700
rounded-lg
hover:bg-slate-100
focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2
transition-colors duration-200
">
Ghost Button
</button>
现代输入框
<div class="space-y-2">
<label
for="email"
class="block text-sm font-medium text-slate-700"
>
Email address
</label>
<input
id="email"
type="email"
placeholder="[email protected]"
class="
w-full h-10 px-3
text-base text-slate-900 placeholder:text-slate-400
bg-white
border border-slate-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed
transition-colors duration-200
"
/>
<p class="text-sm text-slate-500">
We'll never share your email with anyone else.
</p>
</div>
现代卡片
<div class="
bg-white
border border-slate-200
rounded-xl
shadow-sm hover:shadow-md
transition-shadow duration-200
overflow-hidden
">
<div class="aspect-video bg-slate-100">
<img
src="..."
alt="..."
class="w-full h-full object-cover"
/>
</div>
<div class="p-6 space-y-4">
<h3 class="text-xl font-semibold text-slate-900">
Card Title
</h3>
<p class="text-base text-slate-600 leading-relaxed">
Card description goes here with comfortable reading spacing.
</p>
<div class="flex items-center gap-3">
<button class="...">Primary</button>
<button class="...">Secondary</button>
</div>
</div>
</div>
现代导航
<header class="sticky top-0 z-50 bg-white border-b border-slate-200">
<nav class="container mx-auto px-4 md:px-6">
<div class="flex items-center justify-between h-16">
<a href="/" class="flex items-center gap-2">
<img src="logo.svg" alt="Logo" class="h-8 w-8" />
<span class="text-xl font-bold text-slate-900">Brand</span>
</a>
<ul class="hidden md:flex items-center gap-8">
<li>
<a href="/" class="text-sm font-medium text-slate-700 hover:text-slate-900">
Home
</a>
</li>
<li>
<a href="/about" class="text-sm font-medium text-slate-700 hover:text-slate-900">
About
</a>
</li>
<li>
<a href="/contact" class="text-sm font-medium text-slate-700 hover:text-slate-900">
Contact
</a>
</li>
</ul>
<button class="hidden md:inline-flex ...">
Get Started
</button>
<button class="md:hidden" aria-label="Open menu">
<MenuIcon class="h-6 w-6" />
</button>
</div>
</nav>
</header>
应避免的反模式
❌ 请勿这样做
1. 间距不一致:
<div class="mt-3 mb-5 px-7">
<div class="my-4 px-6">
2. 颜色对比度不足:
<p class="text-slate-400">Important text</p>
<p class="text-slate-700">Important text</p>
3. 缺少焦点样式:
<button class="outline-none">
<button class="focus:outline-none focus:ring-2 focus:ring-blue-500">
4. 使用非语义化 HTML:
<div onClick="navigate()">Home</div>
<a href="/home">Home</a>
5. 触控目标过小:
<button class="p-1">×</button>
<button class="p-3 min-h-[44px] min-w-[44px]">×</button>
6. 过度设计:
<div class="bg-gradient-to-r from-purple-500 via-pink-500 to-red-500
shadow-2xl border-4 border-yellow-400 rounded-3xl">
<div class="bg-white border border-slate-200 rounded-lg shadow-sm">
7. 固定像素宽度:
<div class="w-[800px]">
<div class="w-full max-w-3xl">
快速检查清单
设计评审(开发前)
视觉设计:
- 使用中性色调色板(灰色 + 1 种强调色)
- 所有间距和尺寸均遵循 8px 网格
- 保持统一的圆角(8px - 12px)
- 使用柔和的阴影(避免厚重的投影)
- 字体层级清晰
- 留白充足且有目的性
响应式设计:
- 采用移动优先的设计方法
- 触控目标最小为 44x44px
- 无需缩放即可清晰阅读文本
- 内容在所有断点下均能正确重排
- 导航在移动设备上正常使用
无障碍性:
- 颜色对比度符合 WCAG 2.2(最低 4.5:1)
- 焦点指示器清晰可见(2px 描边)
- 正确使用语义化 HTML
- 仅含图标的按钮设有 ARIA 标签
- 表单标签与对应控件正确关联
组件:
- 按钮具有悬停、焦点和激活状态
- 表单输入框具有验证状态
- 已设计加载状态
- 错误状态清晰且有帮助
- 空状态友好
开发评审(实现后)
技术:
- Tailwind 类遵循统一顺序
- 已启用 JIT 模式并配置清除功能
- 除非绝对必要,否则不编写自定义 CSS
- 已实现暗色模式支持
- 已优化性能(延迟加载等)
无障碍测试:
- 键盘导航功能完整
- 已使用屏幕阅读器进行测试(NVDA/VoiceOver)
- 已使用工具验证颜色对比度
- 表单完全支持无障碍访问
- 正确使用 ARIA 属性
响应式测试:
- 已在移动设备上测试(375px、414px)
- 已在平板设备上测试(768px、1024px)
- 已在桌面设备上测试(1280px、1920px)
- 触控交互正常
- 所有尺寸下均无水平滚动
高级技巧
1. 使用 Tailwind CSS 变量实现主题
@layer base {
:root {
/* Spacing */
--spacing-xs: 0.5rem; /* 8px */
--spacing-sm: 1rem; /* 16px */
--spacing-md: 1.5rem; /* 24px */
--spacing-lg: 2rem; /* 32px */
/* Colors */
--color-primary: 220 90% 56%;
--color-primary-hover: 220 90% 48%;
/* Border radius */
--radius-sm: 0.5rem; /* 8px */
--radius-md: 0.75rem; /* 12px */
--radius-lg: 1rem; /* 16px */
}
}
2. 自定义实用工具类
@layer utilities {
/* Text balance for headings */
.text-balance {
text-wrap: balance;
}
/* Smooth scroll */
.scroll-smooth {
scroll-behavior: smooth;
}
/* Focus visible only */
.focus-visible-ring {
@apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500;
}
}
3. 组件组合模式
// Compose smaller components into larger ones
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div className="space-y-1">
<CardTitle>Dashboard</CardTitle>
<CardDescription>Welcome back</CardDescription>
</div>
<Button variant="outline" size="sm">
<SettingsIcon className="h-4 w-4" />
</Button>
</div>
</CardHeader>
<CardContent>
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="space-y-4">
{/* Content */}
</TabsContent>
</Tabs>
</CardContent>
</Card>
资源与工具
设计工具
- Figma:主要设计工具
- Tailwind CSS IntelliSense:VS Code 扩展
- Headless UI:无样式的无障碍组件
- Radix UI:用于 shadcn/ui 的基础组件
无障碍测试
- WAVE:用于无障碍测试的浏览器扩展
- axe DevTools:自动化无障碍测试
- Contrast Checker:验证 WCAG 颜色对比度
- NVDA/VoiceOver:屏幕阅读器测试
颜色工具
- Coolors:颜色调色板生成器
- Tailwind Shades:生成 Tailwind 颜色阶
- Contrast Ratio:WebAIM 对比度检查器
字体排版
- Typescale:生成字号比例
- Modular Scale:计算协调的字号
- Google Fonts:免费网页字体
学习资源
- Tailwind CSS 文档:官方文档
- shadcn/ui 文档:组件库文档
- WCAG 指南:W3C 无障碍标准
- Refactoring UI:Tailwind 创作者提供的设计技巧
总结
2025 年的现代 UI 设计意味着:
- 简洁极简:去除不必要的元素,拥抱留白
- 8px 网格系统:保持间距和尺寸一致且可扩展
- 中性色 + 强调色:使用灰色搭配一种主色
- Tailwind CSS:实用优先、支持 JIT、响应式
- shadcn/ui:可复制并自主掌控的无障碍组件
- WCAG 2.2:全面支持键盘操作和颜色对比度标准
- 移动优先:先为小屏幕设计,再逐步扩展
- 专业润色:微妙的阴影、柔和的圆角、流畅的过渡效果
请记住:目标不是用炫目的设计来博人眼球,而是打造美观、实用、无障碍且令人愉悦的界面。
何时使用此技能
在以下情况下启用此技能:
- 设计新的 UI 组件或页面
- 根据现代标准审查现有设计
- 创建设计系统或组件库
- 实施 Tailwind CSS 或 shadcn/ui
- 确保符合无障碍要求
- 优化响应式布局
- 排查视觉设计问题
- 教授或记录 UI 最佳实践
输出格式:始终提供代码示例、解释设计决策,并在适用时引用具体的 Tailwind 实用类或 shadcn/ui 组件。