UI Styling

中级 Intermediate 参考型 Reference claude-code
9 min read · 453 lines

shadcn/ui + Tailwind CSS + Canvas design system for beautiful, accessible UIs

UI Styling

Overview

Comprehensive skill combining shadcn/ui components, Tailwind CSS utility-first styling, and Canvas-based visual design systems to create beautiful, accessible user interfaces. Covers the full stack from component libraries to design philosophy.

References

When to Use

  • Building UI with React-based frameworks (Next.js, Vite, Remix, Astro)
  • Implementing accessible components (dialogs, forms, tables, navigation)
  • Utility-first CSS styling
  • Creating responsive, mobile-first layouts
  • Implementing dark mode and theme customization
  • Building design systems with consistent design tokens
  • Generating visual designs, posters, or brand assets
  • Rapid prototyping with instant visual feedback
  • Adding complex UI patterns (data tables, charts, command palettes)

Core Technology Stack

Component Layer: shadcn/ui

  • Pre-built accessible components based on Radix UI primitives
  • Copy-paste distribution model (components live in your codebase)
  • TypeScript-first, fully type-safe
  • Composable primitives for building complex UI
  • CLI-based installation and management

Styling Layer: Tailwind CSS

  • Utility-first CSS framework
  • Build-time processing, zero runtime overhead
  • Mobile-first responsive design
  • Consistent design tokens (colors, spacing, typography)
  • Automatic dead code elimination

Visual Design Layer: Canvas

  • Museum-quality visual composition
  • Design philosophy-driven approach
  • Refined visual communication
  • Minimal text, maximum visual impact
  • Systematic patterns and refined aesthetics

Quick Start

Components + Styling Setup

Install shadcn/ui with Tailwind:

npx shadcn@latest init

The CLI will prompt for framework, TypeScript, paths, and theme preferences. This configures both shadcn/ui and Tailwind CSS.

Add components:

npx shadcn@latest add button card dialog form

Use components with utility styling:

import { Button } from "@/components/ui/button"
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"

export function Dashboard() {
  return (
    <div className="container mx-auto p-6 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
      <Card className="hover:shadow-lg transition-shadow">
        <CardHeader>
          <CardTitle className="text-2xl font-bold">Analytics</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <p className="text-muted-foreground">View your metrics</p>
          <Button variant="default" className="w-full">
            View Details
          </Button>
        </CardContent>
      </Card>
    </div>
  )
}

Alternative: Tailwind Only

Vite project:

npm install -D tailwindcss @tailwindcss/vite
// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
export default { plugins: [tailwindcss()] }
/* src/index.css */
@import "tailwindcss";

Component Library Guide

Forms & Inputs

Button, Input, Select, Checkbox, Date Picker, Form Validation

Layout & Navigation

Card, Tabs, Accordion, Navigation Menu

Overlays & Dialogs

Dialog, Drawer, Popover, Toast, Command Palette

Feedback & Status

Alert, Progress, Skeleton

Display Components

Table, Data Table, Avatar, Badge


Theming & Customization

Dark Mode Setup

Use next-themes for dark mode toggling:

  • CSS variable system
  • Color customization and palettes
  • Component variant customization
  • Theme toggle component implementation

CSS Variable System

shadcn/ui uses CSS variables for theme tokens, enabling seamless light/dark mode switching.


Accessibility Patterns

Built on Radix UI accessibility features:

  • Keyboard Navigation: Full keyboard support for all components
  • Focus Management: Automatic focus trapping and restoration
  • Screen Readers: Proper ARIA attributes and announcements
  • Form Validation Accessibility: Error messages correctly associated with form controls

Tailwind Utilities

Layout Utilities

<!-- Flexbox -->
<div class="flex items-center justify-between gap-4">
  <div class="flex-1">Content</div>
  <div class="flex-shrink-0">Sidebar</div>
</div>

<!-- Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

Spacing System

<!-- Padding -->
<div class="p-4">All sides</div>
<div class="px-4 py-2">Horizontal/Vertical</div>

<!-- Margin -->
<div class="m-4">All sides</div>
<div class="mt-4 mb-2">Top/Bottom</div>

<!-- Gap -->
<div class="flex gap-4">Flex gap</div>

Typography

<h1 class="text-4xl font-bold tracking-tight">Heading</h1>
<p class="text-lg text-muted-foreground leading-relaxed">Body text</p>
<span class="text-sm font-medium">Helper text</span>

Colors & Backgrounds

<div class="bg-primary text-primary-foreground">Primary</div>
<div class="bg-secondary text-secondary-foreground">Secondary</div>
<div class="bg-muted text-muted-foreground">Muted</div>
<div class="bg-destructive text-destructive-foreground">Destructive</div>

Responsive Design

Mobile-First Breakpoint System

Breakpoint Min Width CSS
sm 640px @media (min-width: 640px)
md 768px @media (min-width: 768px)
lg 1024px @media (min-width: 1024px)
xl 1280px @media (min-width: 1280px)
2xl 1536px @media (min-width: 1536px)

Core principle: Start with mobile styles, progressively add larger screen styles via breakpoint prefixes.

<!-- Mobile single column, tablet 2 columns, desktop 3 columns -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <!-- Content -->
</div>

<!-- Responsive spacing -->
<div class="p-4 md:p-6 lg:p-8">
  <!-- Content -->
</div>

<!-- Responsive show/hide -->
<div class="hidden md:block">Desktop only</div>
<div class="block md:hidden">Mobile only</div>

Tailwind Customization

@theme Directive for Custom Tokens

@theme {
  --color-brand: #3b82f6;
  --color-brand-light: #60a5fa;
  --font-display: "Cal Sans", sans-serif;
}

Custom Utilities

@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
}

Component Extraction

@layer components {
  .btn-primary {
    @apply bg-primary text-primary-foreground px-4 py-2 rounded-md font-medium;
  }
}

Layer Organization

@layer base {
  /* Base style resets */
}

@layer components {
  /* Component classes */
}

@layer utilities {
  /* Utility classes */
}

Common Patterns

Form Validation

import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8)
})

export function LoginForm() {
  const form = useForm({
    resolver: zodResolver(schema),
    defaultValues: { email: "", password: "" }
  })

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(console.log)} className="space-y-6">
        <FormField control={form.control} name="email" render={({ field }) => (
          <FormItem>
            <FormLabel>Email</FormLabel>
            <FormControl>
              <Input type="email" {...field} />
            </FormControl>
            <FormMessage />
          </FormItem>
        )} />
        <Button type="submit" className="w-full">Sign In</Button>
      </form>
    </Form>
  )
}

Responsive Layout + Dark Mode

<div className="min-h-screen bg-white dark:bg-gray-900">
  <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">
      <Card className="bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700">
        <CardContent className="p-6">
          <h3 className="text-xl font-semibold text-gray-900 dark:text-white">
            Content
          </h3>
        </CardContent>
      </Card>
    </div>
  </div>
</div>

Canvas Visual Design System

Design Philosophy

  • Visual communication over text: Let composition guide attention
  • Systematic patterns: Consistent color, form, and spatial design
  • Minimal text integration: Text serves design, not dominates
  • Museum-quality execution: Every detail must be refined
  • Multi-page design systems: Consistent visual language across pages

Core Principles

  • Refined visual composition
  • Harmony of color, form, and space
  • Maximum visual impact
  • Systematic design patterns

Utility Scripts

shadcn_add.py - Component Installation

Add shadcn/ui components with dependency handling:

python scripts/shadcn_add.py button card dialog

tailwind_config_gen.py - Configuration Generation

Generate tailwind.config.js with custom themes:

python scripts/tailwind_config_gen.py --colors brand:blue --fonts display:Inter

Best Practices

  1. Component composition: Build complex UI from simple, composable primitives
  2. Utility-first styling: Use Tailwind classes directly; extract components only when truly repetitive
  3. Mobile-first responsive: Start with mobile styles, layer responsive variants
  4. Accessibility first: Leverage Radix UI primitives, add focus states, use semantic HTML
  5. Design tokens: Use consistent spacing scales, color palettes, typography systems
  6. Dark mode consistency: Apply dark variants to all themed elements
  7. Performance: Leverage automatic CSS purging, avoid dynamic class names
  8. TypeScript: Use full type safety for better DX
  9. Visual hierarchy: Let composition guide attention, use spacing and color intentionally
  10. Craftsmanship: Every detail matters -- treat UI as a craft

Reference Navigation

Component Library

  • shadcn component catalog
  • Theming & customization
  • Accessibility patterns

Styling System

  • Tailwind core utilities
  • Responsive design
  • Configuration & extension

Visual Design

  • Canvas design philosophy & workflow

External Resources

相关技能 Related Skills