Agents design-to-tailwind
Convert design specifications from Figma, Sketch, or Penpot to HTML with Tailwind CSS utility classes
install
source · Clone the upstream repo
git clone https://github.com/aRustyDev/agents
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aRustyDev/agents "$T" && mkdir -p ~/.claude/skills && cp -r "$T/content/plugins/frontend/design-to-code/skills/design-to-tailwind" ~/.claude/skills/arustydev-agents-design-to-tailwind && rm -rf "$T"
manifest:
content/plugins/frontend/design-to-code/skills/design-to-tailwind/SKILL.mdsource content
Design to Tailwind
Convert design component specifications to HTML with Tailwind CSS.
Overview
This skill transforms design specifications into semantic HTML with Tailwind utility classes, following utility-first best practices.
This skill covers:
- Converting design frames to HTML structure
- Mapping design properties to Tailwind utilities
- Generating responsive variants
- Creating reusable component patterns
This skill does NOT cover:
- Design token extraction (see
skill)design-tokens-extraction - JavaScript interactivity
- Framework-specific components (React, Vue, etc.)
Quick Reference
Design to Tailwind Mapping
| Design Property | Tailwind Utilities |
|---|---|
| Horizontal layout | |
| Vertical layout | |
| Gap/Spacing | |
| Padding | , , |
| Margin | , , |
| Width | , , |
| Height | , , |
| Background color | |
| Text color | |
| Font size | |
| Font weight | |
| Border radius | |
| Shadow | |
| Opacity | |
Spacing Scale
| Design Value | Tailwind Class |
|---|---|
| 4px | |
| 8px | |
| 12px | |
| 16px | |
| 24px | |
| 32px | |
Workflow: Convert Design Component
Step 1: Analyze Design Structure
Read the design component and identify:
- Container structure and nesting
- Layout direction and alignment
- Spacing values (map to Tailwind scale)
- Color and typography tokens
Step 2: Generate HTML with Tailwind
Basic Card:
<div class="bg-white rounded-lg shadow-md p-4"> <h3 class="text-lg font-semibold text-gray-900">Card Title</h3> <p class="text-sm text-gray-600 mt-1">Supporting text content</p> </div>
With Custom Theme Tokens:
<div class="bg-surface rounded-lg shadow-md p-4"> <h3 class="text-heading-md text-foreground">Card Title</h3> <p class="text-body-sm text-foreground-muted mt-1">Supporting text</p> </div>
Step 3: Add Interactive States
<button class=" bg-primary-500 text-white px-4 py-2 rounded-md font-medium text-sm hover:bg-primary-600 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 active:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150 "> Button Label </button>
Step 4: Add Responsive Variants
<div class=" flex flex-col gap-4 md:flex-row md:gap-6 lg:gap-8 "> <div class="w-full md:w-1/2 lg:w-1/3">Column 1</div> <div class="w-full md:w-1/2 lg:w-2/3">Column 2</div> </div>
Common Patterns
Card Component
<!-- Elevated Card --> <article class="bg-white rounded-xl shadow-lg overflow-hidden"> <img src="image.jpg" alt="Card image" class="w-full h-48 object-cover" /> <div class="p-4 space-y-2"> <h3 class="text-lg font-semibold text-gray-900">Card Title</h3> <p class="text-sm text-gray-600 line-clamp-2"> Description text that may be truncated... </p> <div class="flex items-center justify-between pt-2"> <span class="text-sm font-medium text-primary-600">$29.99</span> <button class="text-sm text-gray-500 hover:text-gray-700"> View details → </button> </div> </div> </article> <!-- Outlined Card --> <article class="border border-gray-200 rounded-lg p-4 hover:border-gray-300 transition-colors"> <h3 class="font-medium text-gray-900">Card Title</h3> <p class="text-sm text-gray-600 mt-1">Description text</p> </article>
Button Variants
<!-- Primary Button --> <button class=" inline-flex items-center justify-center gap-2 bg-primary-500 text-white px-4 py-2 rounded-md font-medium text-sm hover:bg-primary-600 active:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition-colors "> <svg class="w-4 h-4"><!-- icon --></svg> Primary Button </button> <!-- Secondary Button --> <button class=" inline-flex items-center justify-center gap-2 bg-gray-100 text-gray-900 px-4 py-2 rounded-md font-medium text-sm hover:bg-gray-200 active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors "> Secondary </button> <!-- Ghost Button --> <button class=" inline-flex items-center justify-center gap-2 text-primary-600 px-4 py-2 rounded-md font-medium text-sm hover:bg-primary-50 active:bg-primary-100 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition-colors "> Ghost Button </button> <!-- Icon Button --> <button class=" p-2 rounded-full text-gray-500 hover:text-gray-700 hover:bg-gray-100 active:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors "> <svg class="w-5 h-5"><!-- icon --></svg> <span class="sr-only">Action label</span> </button>
List Items
<ul class="divide-y divide-gray-200"> <li class="flex items-center gap-4 p-4 hover:bg-gray-50 transition-colors"> <div class="flex-shrink-0"> <img src="avatar.jpg" alt="" class="w-10 h-10 rounded-full" /> </div> <div class="flex-1 min-w-0"> <p class="text-sm font-medium text-gray-900 truncate">List Item Title</p> <p class="text-sm text-gray-500 truncate">Supporting text</p> </div> <div class="flex-shrink-0"> <svg class="w-5 h-5 text-gray-400"><!-- chevron --></svg> </div> </li> </ul>
Form Input
<div class="space-y-1"> <label for="email" class="block text-sm font-medium text-gray-700"> Email address </label> <input type="email" id="email" class=" block w-full px-3 py-2 border border-gray-300 rounded-md text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 disabled:bg-gray-50 disabled:text-gray-500 sm:text-sm " placeholder="you@example.com" /> <p class="text-sm text-gray-500">We'll never share your email.</p> </div>
Navigation
<nav class="flex items-center gap-1"> <a href="#" class=" px-3 py-2 rounded-md text-sm font-medium text-gray-900 bg-gray-100 "> Home </a> <a href="#" class=" px-3 py-2 rounded-md text-sm font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition-colors "> Products </a> <a href="#" class=" px-3 py-2 rounded-md text-sm font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition-colors "> About </a> </nav>
Responsive Design
Breakpoint Prefixes
| Prefix | Min Width | Usage |
|---|---|---|
| 640px | Small screens |
| 768px | Medium screens |
| 1024px | Large screens |
| 1280px | Extra large |
| 1536px | 2x extra large |
Responsive Layout Example
<div class=" grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 lg:grid-cols-3 lg:gap-8 "> <div class="bg-white rounded-lg shadow p-4">Card 1</div> <div class="bg-white rounded-lg shadow p-4">Card 2</div> <div class="bg-white rounded-lg shadow p-4">Card 3</div> </div>
Dark Mode
<div class=" bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 border border-gray-200 dark:border-gray-700 rounded-lg p-4 "> <h3 class="font-medium">Dark mode compatible</h3> <p class="text-gray-600 dark:text-gray-400 mt-1"> Supporting text with dark mode </p> </div>
Component Extraction with @apply
For repeated patterns, use
@apply in CSS:
/* components.css */ @layer components { .btn { @apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-md font-medium text-sm transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2; } .btn-primary { @apply btn bg-primary-500 text-white hover:bg-primary-600 active:bg-primary-700 focus:ring-primary-500; } .btn-secondary { @apply btn bg-gray-100 text-gray-900 hover:bg-gray-200 active:bg-gray-300 focus:ring-gray-500; } .card { @apply bg-white rounded-lg shadow-md p-4; } .input { @apply block w-full px-3 py-2 border border-gray-300 rounded-md text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 sm:text-sm; } }
Accessibility
Include accessibility utilities:
<!-- Screen reader only text --> <span class="sr-only">Description for screen readers</span> <!-- Focus visible states --> <button class="focus-visible:ring-2 focus-visible:ring-primary-500"> Button </button> <!-- Reduced motion --> <div class="motion-safe:animate-bounce motion-reduce:animate-none"> Animated element </div>
See Also
skill - Extract tokens firstdesign-tokens-extraction
style - Tailwind config generationdesign-token-tailwind
style - Documentation formatcomponent-spec