mcpField
V
v0

v0

github.com/headline-design设计与 UI1354 次安装24 周前更新
代码仓库

关于 v0

面向 Web 应用设计与开发的指南型技能,涵盖界面视觉、组件组织、Tailwind CSS、无障碍与性能实践。适合需要一致设计规范和实现建议的 Web 项目。

主要功能

  1. 01色彩与排版规范
  2. 02布局和响应式设计指导
  3. 03组件架构与代码组织
  4. 04Tailwind CSS 模式
  5. 05无障碍与性能实践

适用场景

  1. 01规划 Web 应用界面
  2. 02组织可复用 UI 组件
  3. 03检查响应式和无障碍设计

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/headline-design/design-craft --skill v0

安装后在 Claude Code 中输入/v0确认已加载。

附带文件README.md

详细介绍

v0 设计与开发技能

创建专业级、视觉出众且拥有卓越 UI/UX 的 Web 应用的完整指南。


目录

  1. 设计理念
  2. 配色系统
  3. 排版
  4. 布局与间距
  5. 组件架构
  6. Tailwind CSS 模式
  7. 无障碍访问
  8. 性能
  9. 代码组织
  10. UI/UX 原则
  11. 常见模式
  12. 应避免的反模式

设计理念

核心原则
  1. 克制胜于堆砌 — 优秀的设计重在删去什么,而非添加什么
  2. 清晰胜于巧妙 — 用户应该能够立即理解界面
  3. 一致胜于新奇 — 可预测的模式可以降低认知负担
  4. 目的胜于装饰 — 每个元素都必须有存在的理由
  5. 交付有趣的作品,绝不交付丑陋的作品 — 在创意与精致之间取得平衡
v0 美学
  • 简洁、现代的界面,留白充足
  • 微妙的阴影和边框,营造层次感而不分散注意力
  • 流畅且目的明确的动画,引导注意力
  • 协调统一、观感专业的配色方案
  • 层级清晰的排版

配色系统

3–5 色规则

始终将颜色总数严格控制在 3–5 种。 这一限制有助于保持整体协调。

必需结构
1 Primary Brand Color     → CTAs, key actions, brand identity
2-3 Neutrals              → Backgrounds, text, borders
1-2 Accent Colors         → Status indicators, highlights, secondary actions
颜色选择指南
用途建议
主要操作高饱和度且无障碍易用的品牌色
背景米白色、柔和的灰色(大面积区域绝不使用纯白)
文本接近黑色(#0a0a0a 至 #1a1a1a),而非纯黑色
边框/分隔线极浅的灰色(透明度 10-20%)
成功状态青绿色系中的绿色
错误状态暖红色,避免过于刺眼
警告状态琥珀色/橙色调
色温规则
  • 应 使用类似色:蓝色→青色、紫色→粉色、橙色→红色
  • 不应 混用色温相反的颜色:粉色→绿色、橙色→蓝色、红色→青色
渐变规则
  • 除非明确要求,否则应避免使用渐变 — 纯色更简洁
  • 如果必须使用渐变:
    • 仅用作微妙的点缀,绝不用在主要元素上
    • 颜色节点最多 2–3 个
    • 仅使用类似色
    • 考虑渐变方向(通常为自上而下或对角线)
设计令牌结构

始终在 CSS 变量中使用语义化设计令牌:

:root {
  /* Backgrounds */
  --background: 0 0% 100%;
  --foreground: 0 0% 3.9%;

  /* Cards & Surfaces */
  --card: 0 0% 100%;
  --card-foreground: 0 0% 3.9%;

  /* Primary Actions */
  --primary: 0 0% 9%;
  --primary-foreground: 0 0% 98%;

  /* Secondary Actions */
  --secondary: 0 0% 96.1%;
  --secondary-foreground: 0 0% 9%;

  /* Muted Elements */
  --muted: 0 0% 96.1%;
  --muted-foreground: 0 0% 45.1%;

  /* Accents */
  --accent: 0 0% 96.1%;
  --accent-foreground: 0 0% 9%;

  /* Destructive Actions */
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 0 0% 98%;

  /* Borders & Inputs */
  --border: 0 0% 89.8%;
  --input: 0 0% 89.8%;
  --ring: 0 0% 3.9%;

  /* Radius */
  --radius: 0.5rem;
}

重要规则: 绝不要直接使用 text-white、bg-black 这类颜色。所有内容都必须通过令牌进行主题化。


排版

字体最多 2 种规则

始终将字体系列限制在最多 2 种。 字体过多会造成视觉混乱。

字体搭配策略
Headings: Display or Sans-serif with personality (multiple weights)
Body: Highly readable sans-serif or serif
推荐搭配
风格标题正文
现代科技Inter、GeistInter、Geist
编辑风格Playfair DisplaySource Sans Pro
初创企业Cal Sans、ManropeInter
企业风格OutfitSystem UI
创意风格Space GroteskDM Sans
排版比例

使用一致的比例,确保层级清晰:

/* Recommended Tailwind Classes */
text-xs    → 12px  → Fine print, labels
text-sm    → 14px  → Secondary text, captions
text-base  → 16px  → Body text (minimum for readability)
text-lg    → 18px  → Lead paragraphs
text-xl    → 20px  → Section headers
text-2xl   → 24px  → Card titles
text-3xl   → 30px  → Page sections
text-4xl   → 36px  → Hero subheadings
text-5xl   → 48px  → Hero headings
text-6xl+  → 60px+ → Display headings (use sparingly)
行高规则
  • 正文文本: leading-relaxed(1.625),或 leading-6 至 leading-7
  • 标题: leading-tight(1.25)或 leading-snug(1.375)
  • 正文文本绝不要使用默认行高 — 这会过于紧凑
文本换行
  • 为标题添加 text-balance,以优化换行效果
  • 对重要文案使用 text-pretty
  • 设置 max-w-prose 或 max-w-2xl,确保行长易于阅读
在 Next.js 中实现字体
// layout.tsx
import { Inter, Playfair_Display } from 'next/font/google'

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-sans'
})

const playfair = Playfair_Display({
  subsets: ['latin'],
  variable: '--font-serif'
})

export default function RootLayout({ children }) {
  return (
    <html className={`${inter.variable} ${playfair.variable}`}>
      <body className="font-sans">{children}</body>
    </html>
  )
}
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-sans)'],
        serif: ['var(--font-serif)'],
      },
    },
  },
}

布局与间距

移动优先设计

始终先设计移动端,再针对更大的屏幕进行增强。

// ✅ Mobile-first approach
<div className="px-4 md:px-6 lg:px-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">

// ❌ Desktop-first (avoid)
<div className="px-8 md:px-6 sm:px-4">
布局方法优先级

布局决策遵循以下优先级:

  1. Flexbox — 适用于大多数布局(导航栏、卡片、简单网格)
  2. CSS Grid — 适用于复杂的二维布局、便当网格、仪表板
  3. 绝对定位 — 仅在必要时使用(模态框、工具提示)
  4. 切勿使用浮动
间距比例

统一使用 Tailwind 的间距比例:

4px  = p-1   → Tiny gaps (icon padding)
8px  = p-2   → Small gaps (button padding)
12px = p-3   → Compact spacing
16px = p-4   → Standard spacing (most common)
24px = p-6   → Comfortable spacing
32px = p-8   → Section spacing
48px = p-12  → Large section gaps
64px = p-16  → Hero spacing
96px = p-24  → Major section dividers
间距规则
// ✅ Use gap for flex/grid spacing
<div className="flex gap-4">
<div className="grid gap-6">

// ✅ Use padding for container spacing
<section className="px-4 py-12 md:px-6 lg:py-24">

// ❌ Avoid space-* utilities
<div className="space-y-4">  // Less flexible

// ❌ Never mix gap and margin on same element
<div className="flex gap-4 mb-4">  // Pick one approach
容器模式
// Standard content container
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">

// Narrow content (articles, forms)
<div className="mx-auto max-w-2xl px-4">

// Full-bleed with contained content
<section className="w-full bg-muted">
  <div className="mx-auto max-w-7xl px-4 py-16">
响应式断点
sm:  640px   → Large phones, small tablets
md:  768px   → Tablets
lg:  1024px  → Small laptops, tablets landscape
xl:  1280px  → Desktops
2xl: 1536px  → Large desktops

组件架构

文件结构
components/
├── ui/                    # Base shadcn components (don't modify)
│   ├── button.tsx
│   ├── card.tsx
│   └── ...
├── [feature]/             # Feature-specific components
│   ├── feature-header.tsx
│   ├── feature-card.tsx
│   └── feature-list.tsx
├── layout/                # Layout components
│   ├── header.tsx
│   ├── footer.tsx
│   └── sidebar.tsx
└── shared/                # Shared/common components
    ├── logo.tsx
    ├── theme-toggle.tsx
    └── loading-state.tsx
组件设计原则
  1. 单一职责 — 每个组件都做好一件事
  2. 组合优于配置 — 用简单部分构建复杂 UI
  3. 使用 Props 进行自定义 — 使用 props,而不是硬编码值
  4. 合理的默认值 — 开箱即用,并在需要时支持自定义
组件模板
import { cn } from "@/lib/utils"

interface FeatureCardProps {
  title: string
  description: string
  icon?: React.ReactNode
  className?: string
  variant?: "default" | "highlighted"
}

export function FeatureCard({
  title,
  description,
  icon,
  className,
  variant = "default"
}: FeatureCardProps) {
  return (
    <div
      className={cn(
        "rounded-lg border p-6 transition-colors",
        variant === "default" && "bg-card hover:bg-accent",
        variant === "highlighted" && "bg-primary text-primary-foreground",
        className
      )}
    >
      {icon && (
        <div className="mb-4 text-muted-foreground">
          {icon}
        </div>
      )}
      <h3 className="font-semibold text-lg">{title}</h3>
      <p className="mt-2 text-sm text-muted-foreground">
        {description}
      </p>
    </div>
  )
}
页面结构
// app/feature/page.tsx
import { FeatureHero } from "@/components/feature/feature-hero"
import { FeatureGrid } from "@/components/feature/feature-grid"
import { FeatureCTA } from "@/components/feature/feature-cta"

export default function FeaturePage() {
  return (
    <main>
      <FeatureHero />
      <FeatureGrid />
      <FeatureCTA />
    </main>
  )
}

切勿创建臃肿的页面文件。 应拆分为逻辑清晰的组件。


Tailwind CSS 模式

类名组织

统一类名顺序:

className={cn(
  // 1. Layout (display, position, sizing)
  "flex items-center justify-between",
  "relative w-full max-w-md",

  // 2. Spacing (margin, padding, gap)
  "p-4 gap-2",

  // 3. Typography
  "text-sm font-medium",

  // 4. Colors & Backgrounds
  "bg-background text-foreground",

  // 5. Borders & Shadows
  "rounded-lg border shadow-sm",

  // 6. Transitions & Animations
  "transition-colors duration-200",

  // 7. States (hover, focus, active)
  "hover:bg-accent focus:ring-2",

  // 8. Responsive overrides
  "md:p-6 lg:flex-row"
)}
常用工具类模式
// Centering
"flex items-center justify-center"
"grid place-items-center"

// Card pattern
"rounded-lg border bg-card p-6 shadow-sm"

// Interactive element
"cursor-pointer transition-colors hover:bg-accent"

// Focus ring (accessibility)
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"

// Truncation
"truncate"                    // Single line
"line-clamp-2"               // Multi-line (2 lines)

// Aspect ratios
"aspect-video"               // 16:9
"aspect-square"              // 1:1

// Backdrop blur (modals, overlays)
"bg-background/80 backdrop-blur-sm"

// Dividers
"divide-y divide-border"

// Screen reader only
"sr-only"
响应式设计模式
// Stack to row
<div className="flex flex-col gap-4 md:flex-row">

// Grid columns
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">

// Hide/show
<div className="hidden md:block">    // Show on md+
<div className="md:hidden">          // Hide on md+

// Responsive text
<h1 className="text-3xl md:text-4xl lg:text-5xl">

// Responsive spacing
<section className="py-12 md:py-16 lg:py-24">
动画模式
// Subtle hover lift
"transition-transform hover:-translate-y-1"

// Fade in on hover
"opacity-0 group-hover:opacity-100 transition-opacity"

// Scale on hover
"transition-transform hover:scale-105"

// Color transition
"transition-colors hover:bg-accent"

// Combined
"transition-all duration-200 hover:shadow-lg hover:-translate-y-0.5"

无障碍访问

必需实践
语义化 HTML
// ✅ Correct
<main>
  <header>
    <nav aria-label="Main navigation">
  </header>
  <article>
    <h1>Page Title</h1>
    <section aria-labelledby="section-heading">
      <h2 id="section-heading">Section</h2>
    </section>
  </article>
  <footer>
</main>

// ❌ Avoid
<div className="header">
<div className="nav">
<div className="main">
焦点管理
// Visible focus states
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"

// Focus within (for form groups)
"focus-within:ring-2 focus-within:ring-ring"

// Skip link
<a
  href="#main-content"
  className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4"
>
  Skip to content
</a>
屏幕阅读器支持
// Hidden but accessible text
<span className="sr-only">Open menu</span>

// Aria labels
<button aria-label="Close dialog">
  <XIcon className="h-4 w-4" />
</button>

// Live regions for dynamic content
<div aria-live="polite" aria-atomic="true">
  {statusMessage}
</div>
图像无障碍访问
// Informative images
<img src="/chart.png" alt="Sales increased 25% in Q4 2024" />

// Decorative images
<img src="/decoration.png" alt="" role="presentation" />

// Complex images
<figure>
  <img src="/diagram.png" alt="System architecture diagram" />
  <figcaption>
    Detailed description of the architecture...
  </figcaption>
</figure>
颜色对比度
  • 文本: 对比度至少为 4.5:1(WCAG AA)
  • 大号文本: 对比度至少为 3:1
  • 交互元素: 具有清晰的视觉区分
  • 切勿仅依赖颜色来传达信息
键盘导航
// Interactive elements must be keyboard accessible
<button>Clickable</button>       // ✅ Naturally focusable
<div onClick={...}>Clickable</div>  // ❌ Not keyboard accessible

// If you must use a div:
<div
  role="button"
  tabIndex={0}
  onClick={handleClick}
  onKeyDown={(e) => e.key === 'Enter' && handleClick()}
>
  Clickable
</div>

性能

图像优化
import Image from 'next/image'

// Always use Next.js Image component
<Image
  src="/hero.jpg"
  alt="Hero image description"
  width={1200}
  height={600}
  priority              // Above-the-fold images
  className="object-cover"
/>

// Responsive images
<Image
  src="/photo.jpg"
  alt="Description"
  fill
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  className="object-cover"
/>
代码拆分
// Dynamic imports for heavy components
import dynamic from 'next/dynamic'

const HeavyChart = dynamic(() => import('@/components/heavy-chart'), {
  loading: () => <ChartSkeleton />,
  ssr: false  // If client-only
})
加载状态
// Skeleton loading (preferred)
<div className="animate-pulse">
  <div className="h-4 w-3/4 rounded bg-muted" />
  <div className="mt-2 h-4 w-1/2 rounded bg-muted" />
</div>

// Spinner for actions
<Button disabled>
  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
  Loading...
</Button>
数据获取
// ✅ Server Components for static data
async function ProductList() {
  const products = await getProducts()
  return <ProductGrid products={products} />
}

// ✅ SWR for client-side data
import useSWR from 'swr'

function UserProfile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)

  if (isLoading) return <ProfileSkeleton />
  if (error) return <ErrorState />
  return <Profile user={data} />
}

// ❌ Never fetch in useEffect
useEffect(() => {
  fetch('/api/data').then(...)  // Anti-pattern
}, [])

代码组织

项目结构
app/
├── (marketing)/          # Route groups for layouts
│   ├── page.tsx
│   ├── about/
│   └── pricing/
├── (dashboard)/
│   ├── layout.tsx
│   └── dashboard/
├── api/
│   └── [feature]/
│       └── route.ts
├── layout.tsx
└── globals.css

components/
├── ui/                   # shadcn components
├── [feature]/            # Feature components
├── layout/               # Layout components
└── shared/               # Shared components

lib/
├── utils.ts              # Utility functions
├── validations.ts        # Zod schemas
└── constants.ts          # App constants

hooks/
├── use-[feature].ts
└── use-media-query.ts

types/
└── index.ts
命名约定
类型约定示例
组件PascalCaseFeatureCard.tsx
文件kebab-casefeature-card.tsx
HookscamelCase,使用 use 前缀useFeature.ts
工具函数camelCaseformatDate.ts
类型PascalCaseFeatureProps
常量SCREAMING_SNAKE_CASEMAX_FILE_SIZE
CSS 变量kebab-case--primary-color
导入组织
// 1. React/Next.js
import { useState, useEffect } from 'react'
import Image from 'next/image'
import Link from 'next/link'

// 2. Third-party libraries
import { motion } from 'framer-motion'
import { z } from 'zod'

// 3. Internal components
import { Button } from '@/components/ui/button'
import { FeatureCard } from '@/components/feature/feature-card'

// 4. Internal utilities/hooks
import { cn } from '@/lib/utils'
import { useFeature } from '@/hooks/use-feature'

// 5. Types
import type { Feature } from '@/types'

UI/UX 原则

视觉层次
  1. 大小 — 较大的元素会优先吸引注意力
  2. 颜色 — 高饱和度颜色在中性色背景下更醒目
  3. 对比度 — 高对比度可形成视觉焦点
  4. 间距 — 留白可突出重要元素
  5. 位置 — 按从左上到右下的顺序阅读
交互状态

每个交互元素都需要具备以下状态:

// Button example
<button className={cn(
  // Default
  "bg-primary text-primary-foreground",
  // Hover
  "hover:bg-primary/90",
  // Focus
  "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
  // Active/Pressed
  "active:scale-[0.98]",
  // Disabled
  "disabled:pointer-events-none disabled:opacity-50"
)}>
反馈模式
// Loading feedback
<Button disabled={isLoading}>
  {isLoading ? (
    <>
      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
      Saving...
    </>
  ) : (
    'Save Changes'
  )}
</Button>

// Success feedback
<div className="flex items-center gap-2 text-green-600">
  <CheckCircle className="h-4 w-4" />
  <span>Changes saved successfully</span>
</div>

// Error feedback
<div className="rounded-md bg-destructive/10 p-4 text-destructive">
  <p className="text-sm font-medium">Error occurred</p>
  <p className="mt-1 text-sm opacity-90">{error.message}</p>
</div>
空状态

切勿显示空白屏幕。始终提供有帮助的空状态:

<div className="flex flex-col items-center justify-center py-12 text-center">
  <InboxIcon className="h-12 w-12 text-muted-foreground/50" />
  <h3 className="mt-4 text-lg font-semibold">No messages yet</h3>
  <p className="mt-2 text-sm text-muted-foreground">
    When you receive messages, they&apos;ll appear here.
  </p>
  <Button className="mt-4">
    Send your first message
  </Button>
</div>
微交互

增强 UX 的细微动画:

// Hover lift effect
"transition-transform duration-200 hover:-translate-y-1 hover:shadow-lg"

// Button press effect
"active:scale-[0.98] transition-transform"

// Smooth reveals
"animate-in fade-in slide-in-from-bottom-4 duration-300"

// Skeleton pulse
"animate-pulse"

常见模式

主视觉区域
<section className="relative overflow-hidden py-24 md:py-32 lg:py-40">
  <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
    <div className="mx-auto max-w-3xl text-center">
      <h1 className="text-balance text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl">
        Your compelling headline here
      </h1>
      <p className="mt-6 text-pretty text-lg text-muted-foreground md:text-xl">
        Supporting text that elaborates on the headline and provides context.
      </p>
      <div className="mt-8 flex flex-col gap-4 sm:flex-row sm:justify-center">
        <Button size="lg">Primary Action</Button>
        <Button size="lg" variant="outline">Secondary Action</Button>
      </div>
    </div>
  </div>
</section>
功能网格
<section className="py-16 md:py-24">
  <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
    <div className="mx-auto max-w-2xl text-center">
      <h2 className="text-3xl font-bold md:text-4xl">Features</h2>
      <p className="mt-4 text-muted-foreground">
        Everything you need to succeed.
      </p>
    </div>
    <div className="mt-12 grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
      {features.map((feature) => (
        <FeatureCard key={feature.id} {...feature} />
      ))}
    </div>
  </div>
</section>
卡片网格
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
  {items.map((item) => (
    <Card key={item.id} className="group overflow-hidden">
      <div className="aspect-video overflow-hidden">
        <Image
          src={item.image}
          alt={item.title}
          fill
          className="object-cover transition-transform group-hover:scale-105"
        />
      </div>
      <CardHeader>
        <CardTitle>{item.title}</CardTitle>
        <CardDescription>{item.description}</CardDescription>
      </CardHeader>
      <CardFooter>
        <Button variant="ghost" className="ml-auto">
          Learn more <ArrowRight className="ml-2 h-4 w-4" />
        </Button>
      </CardFooter>
    </Card>
  ))}
</div>
便当网格
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
  {/* Large feature - spans 2 columns */}
  <div className="md:col-span-2 lg:row-span-2 rounded-xl border bg-card p-6">
    <h3 className="text-2xl font-bold">Main Feature</h3>
  </div>

  {/* Regular items */}
  <div className="rounded-xl border bg-card p-6">
    <h3 className="font-semibold">Feature 2</h3>
  </div>

  <div className="rounded-xl border bg-card p-6">
    <h3 className="font-semibold">Feature 3</h3>
  </div>

  {/* Wide item - spans 2 columns */}
  <div className="md:col-span-2 rounded-xl border bg-card p-6">
    <h3 className="font-semibold">Wide Feature</h3>
  </div>
</div>
表单布局
<form className="space-y-6">
  <div className="grid gap-4 sm:grid-cols-2">
    <div className="space-y-2">
      <Label htmlFor="firstName">First name</Label>
      <Input id="firstName" placeholder="John" />
    </div>
    <div className="space-y-2">
      <Label htmlFor="lastName">Last name</Label>
      <Input id="lastName" placeholder="Doe" />
    </div>
  </div>

  <div className="space-y-2">
    <Label htmlFor="email">Email</Label>
    <Input id="email" type="email" placeholder="[email protected]" />
    <p className="text-sm text-muted-foreground">
      We&apos;ll never share your email.
    </p>
  </div>

  <Button type="submit" className="w-full sm:w-auto">
    Submit
  </Button>
</form>
导航
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
  <div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8">
    <Link href="/" className="flex items-center gap-2">
      <Logo className="h-8 w-8" />
      <span className="font-bold">Brand</span>
    </Link>

    <nav className="hidden items-center gap-6 md:flex">
      <Link href="/features" className="text-sm font-medium text-muted-foreground transition-colors hover:text-foreground">
        Features
      </Link>
      <Link href="/pricing" className="text-sm font-medium text-muted-foreground transition-colors hover:text-foreground">
        Pricing
      </Link>
    </nav>

    <div className="flex items-center gap-4">
      <Button variant="ghost" size="sm" className="hidden sm:flex">
        Sign in
      </Button>
      <Button size="sm">Get Started</Button>
    </div>
  </div>
</header>

应避免的反模式

颜色误用
// ❌ Too many colors
className="bg-purple-500 text-pink-400 border-blue-300 shadow-green-200"

// ❌ Direct colors instead of tokens
className="bg-white text-black"

// ❌ Purple/violet as primary (unless explicitly requested)
className="bg-violet-600"

// ❌ Clashing temperature gradients
className="bg-gradient-to-r from-pink-500 to-green-500"

// ✅ Semantic tokens
className="bg-background text-foreground"
排版误用
// ❌ Too many fonts
<h1 className="font-display">
<p className="font-body">
<span className="font-accent">
<code className="font-mono">   // 4 fonts!

// ❌ Tiny text
className="text-xs"  // Avoid for body text

// ❌ No line-height consideration
className="text-base"  // Missing leading-*

// ✅ Proper typography
className="text-base leading-relaxed"
布局误用
// ❌ Desktop-first responsive
className="w-1/3 sm:w-1/2 xs:w-full"

// ❌ Using space-* utilities
className="space-y-4"

// ❌ Floats
className="float-left"

// ❌ Mixing gap and margin
className="flex gap-4 mb-4"

// ✅ Mobile-first with gap
className="flex flex-col gap-4 md:flex-row"
组件误用
// ❌ Monolithic page files (500+ lines)
// ❌ Hardcoded values instead of props
// ❌ Inline styles
// ❌ Non-semantic HTML (div for everything)
// ❌ Missing key props in lists
// ❌ Fetching in useEffect

// ✅ Split into components
// ✅ Use props for customization
// ✅ Tailwind classes
// ✅ Semantic HTML
// ✅ Proper key props
// ✅ Server Components or SWR
无障碍访问问题
// ❌ Click handler on div
<div onClick={handleClick}>Click me</div>

// ❌ Missing alt text
<img src="/photo.jpg" />

// ❌ Color-only indication
<span className="text-red-500">Error</span>

// ❌ Missing focus states
<button className="hover:bg-accent">

// ✅ Use button element
<button onClick={handleClick}>Click me</button>

// ✅ Descriptive alt text
<img src="/photo.jpg" alt="Team meeting in conference room" />

// ✅ Icon + color for errors
<span className="flex items-center gap-2 text-destructive">
  <AlertCircle className="h-4 w-4" />
  Error message
</span>

// ✅ Focus states
<button className="hover:bg-accent focus:ring-2 focus:ring-ring">
视觉问题
// ❌ Abstract decorative shapes
<div className="absolute -top-20 -right-20 h-40 w-40 rounded-full bg-gradient-to-r from-purple-400 to-pink-400 blur-3xl" />

// ❌ Placeholder images left in production
<img src="/placeholder.jpg" />

// ❌ Emojis as icons
<span>📧 Email</span>

// ❌ Hand-drawn SVG maps
<svg><path d="M100,200 L300,400..." /></svg>

// ✅ Real images or GenerateImage tool
// ✅ Proper icon libraries (Lucide, etc.)
// ✅ Mapping libraries for geographic data

快速参考清单

发布前,请确认:

  • 颜色: 最多 3-5 种,使用语义化令牌
  • 排版: 最多 2 种字体,层次清晰
  • 间距: 保持一致,使用 Tailwind 比例
  • 移动端: 在 375px 宽度下显示良好
  • 无障碍访问: 键盘导航、焦点状态、替代文本
  • 性能: 图像已优化,代码已拆分
  • 组件: 按逻辑拆分,避免臃肿
  • 加载: 为异步内容提供骨架屏状态
  • 空状态: 无数据时显示有帮助的提示
  • 错误: 提供清晰的错误提示和恢复方式
  • 交互: 定义悬停、焦点、激活状态

总结

v0 方案可以概括为:

克制而优雅,交互有的放矢。

每项设计决策都应通过以下检验:

  1. 是否提升了清晰度?
  2. 是否保持了一致性?
  3. 是否有助于实现用户目标?
  4. 如果删掉它,设计是否会变差?

如果无法对这四项都回答“是”,请重新考虑这一选择。

评论

支持 Markdown