Claude Code के साथ Tailwind CSS: मजबूत UI बनाने की व्यावहारिक गाइड
Claude Code और Tailwind CSS से बेहतर UI बनाएं: design tokens, responsive layout, dark mode, safelist और visual checks।
Tailwind CSS में आप p-4, grid, text-sm, rounded-lg जैसी छोटी utility classes से UI बनाते हैं। Claude Code इस काम को तेज कर सकता है, क्योंकि वह repository पढ़ सकता है, files edit कर सकता है और checks चला सकता है। लेकिन अगर आप सिर्फ “इस page को अच्छा बना दो” लिखते हैं, तो output में बहुत लंबा className, अलग-अलग नीले रंग, mobile layout टूटना, dark mode में कम contrast, या production build में गायब class जैसी समस्या आ सकती है।
यह guide beginner-friendly तरीके से बताती है कि Claude Code के साथ Tailwind CSS कैसे इस्तेमाल करें। हम design tokens, responsive utilities, component extraction, class soup से बचना, dark mode, forms/buttons/cards, safelist और content scanning, तथा Playwright visual checks कवर करेंगे। Code examples React + TypeScript में हैं, पर process Astro, Next.js, Remix और Vite projects पर भी लागू होती है।
Official references के लिए Tailwind की Theme variables, Responsive design, Dark mode, Detecting classes in source files, और Adding custom styles देखें। React types के लिए React TypeScript guide, Claude Code के लिए Claude Code docs, और screenshot comparison के लिए Playwright Visual comparisons उपयोगी हैं।
अगर prompt लिखना अभी मुश्किल लगता है, तो पहले better prompts tips पढ़ें। Mobile-first app flow पर काम कर रहे हैं, तो PWA development guide भी साथ में देखें।
पहले Audit कराएं
Claude Code से तुरंत files edit न कराएं। पहले उसे project की Tailwind स्थिति समझने दें। इससे पता चलता है कि रंग कहां define हैं, कौन से components दोहर रहे हैं, mobile layout कहां टूट सकता है, और कौन सी dynamic classes production CSS से गायब हो सकती हैं।
इस repository में Tailwind CSS usage inspect करें। अभी files edit न करें।
इन points पर report दें:
- color, spacing, radius, shadow, typography design tokens
- बहुत लंबे className वाले React components
- 375px, 768px, 1440px पर टूटने वाले layouts
- light/dark mode coverage gaps
- forms, buttons, cards, badges में repeated styles
- dynamic Tailwind classes जिनसे production CSS missing हो सकती है
- Playwright, Storybook या manual visual checks
Masa ने ClaudeCodeLab पर एक बार header spacing बदलते समय mobile article CTA और ad area को बहुत तंग कर दिया था। Lesson यह है: Tailwind class छोटी दिखती है, पर revenue path और readability पर बड़ा असर डाल सकती है।
Design Tokens को केंद्र में रखें
Design tokens रंग, spacing, font, radius और shadow जैसे मूल values के नाम हैं। Tailwind CSS v4 में @theme से tokens define करने पर bg-brand-600 और rounded-card जैसी utilities मिलती हैं। पुराने project में यही values tailwind.config.ts के theme.extend में रखी जा सकती हैं।
/* src/styles/app.css */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--font-sans: Inter, system-ui, sans-serif;
--color-brand-50: #eef6ff;
--color-brand-100: #d9ebff;
--color-brand-600: #2563eb;
--color-brand-700: #1d4ed8;
--color-ink: #111827;
--color-muted: #6b7280;
--color-surface: #ffffff;
--color-danger: #dc2626;
--radius-card: 0.75rem;
--shadow-card: 0 16px 40px rgb(15 23 42 / 0.08);
}
Claude Code को साफ बताएं: “existing brand और surface tokens use करो; नया token तभी जोड़ो जब value reuse होगी।” सिर्फ “better blue” कहने से blue, sky, indigo mix हो सकते हैं।
Responsive Layout mobile-first रखें
Tailwind responsive classes mobile-first हैं। Base class mobile पर लागू होती है, फिर sm:, md:, lg: larger screens के लिए changes जोड़ते हैं। Desktop पहले बनाकर mobile बाद में patch करना आम गलती है।
Product grid को Tailwind CSS से improve करें।
Requirements:
- 375px पर 1 column, 640px+ पर 2 columns, 1024px+ पर 3 columns
- images हमेशा square रहें
- cards की height consistent रहे
- CTA button card bottom पर align हो
- Product props type न बदलें
- mobile और desktop screenshot check करें
type Product = {
id: string;
name: string;
price: number;
imageUrl: string;
};
export function ProductGrid({ products }: { products: Product[] }) {
return (
<section className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
{products.map((product) => (
<article
key={product.id}
className="flex h-full flex-col overflow-hidden rounded-card border border-slate-200 bg-surface shadow-card dark:border-slate-800 dark:bg-slate-950"
>
<img
src={product.imageUrl}
alt={product.name}
className="aspect-square w-full object-cover"
/>
<div className="flex flex-1 flex-col p-4">
<h3 className="line-clamp-2 text-base font-semibold text-ink dark:text-white">
{product.name}
</h3>
<p className="mt-2 text-sm text-muted dark:text-slate-400">
₹{product.price.toLocaleString("hi-IN")}
</p>
<button className="mt-auto rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-brand-600 focus:ring-offset-2 dark:focus:ring-offset-slate-950">
विवरण देखें
</button>
</div>
</article>
))}
</section>
);
}
यहां aspect-square image ratio बचाता है, flex h-full flex-col card height stable रखता है, और mt-auto button को bottom पर रखता है।
Class Soup से बचें
Class soup का मतलब है ऐसा लंबा className जिसे पढ़कर समझ न आए कि base style क्या है और state style क्या है। Repeated buttons या cards को component में निकालें, लेकिन हर छोटी चीज को @apply में छिपाना भी सही नहीं।
import type { ButtonHTMLAttributes, ReactNode } from "react";
type ButtonVariant = "primary" | "secondary" | "danger";
const buttonVariants: Record<ButtonVariant, string> = {
primary: "bg-brand-600 text-white hover:bg-brand-700 focus:ring-brand-600",
secondary:
"border border-slate-300 bg-white text-slate-900 hover:bg-slate-50 focus:ring-slate-400 dark:border-slate-700 dark:bg-slate-900 dark:text-white",
danger: "bg-danger text-white hover:bg-red-700 focus:ring-danger",
};
function cn(...classes: Array<string | false | null | undefined>) {
return classes.filter(Boolean).join(" ");
}
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: ButtonVariant;
children: ReactNode;
};
export function Button({ variant = "primary", className, children, ...props }: ButtonProps) {
return (
<button
className={cn(
"inline-flex min-h-10 items-center justify-center rounded-lg px-4 py-2 text-sm font-semibold transition focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-60",
buttonVariants[variant],
className,
)}
{...props}
>
{children}
</button>
);
}
ध्यान रखें कि classes full strings में रहें। bg-${color}-600 जैसा dynamic pattern Tailwind scanner से छूट सकता है।
Dark Mode, Forms और CTA साथ में जांचें
Dark mode सिर्फ background बदलना नहीं है। Text, border, focus ring, disabled state, error message, card shadow और input colors भी देखने पड़ते हैं। Forms और CTA revenue path से जुड़े होते हैं, इसलिए केवल happy path जांचना काफी नहीं।
"use client";
import type { FormEvent } from "react";
type LeadFormProps = {
onSubmit: (values: { email: string; message: string }) => void;
error?: string;
};
export function LeadForm({ onSubmit, error }: LeadFormProps) {
function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
onSubmit({
email: String(formData.get("email") ?? ""),
message: String(formData.get("message") ?? ""),
});
}
return (
<form
onSubmit={handleSubmit}
className="space-y-4 rounded-card border border-slate-200 bg-white p-5 shadow-card dark:border-slate-800 dark:bg-slate-950"
>
<label className="block text-sm font-medium text-slate-900 dark:text-white">
Email
<input
name="email"
type="email"
required
aria-describedby={error ? "lead-form-error" : undefined}
className="mt-1 w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 outline-none focus:border-brand-600 focus:ring-2 focus:ring-brand-600/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white"
placeholder="you@example.com"
/>
</label>
{error ? (
<p id="lead-form-error" className="text-sm font-medium text-danger">
{error}
</p>
) : null}
<button className="w-full rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-brand-600 focus:ring-offset-2 dark:focus:ring-offset-slate-950">
परामर्श भेजें
</button>
</form>
);
}
Accessibility review के लिए Claude Code accessibility guide भी देखें।
Safelist और Content Scanning
Tailwind source files scan करके CSS बनाता है। अगर class dynamically बनी है, तो production CSS में वह missing हो सकती है। Safe तरीका static map है।
type Status = "success" | "warning" | "danger";
const statusClasses: Record<Status, string> = {
success: "bg-emerald-50 text-emerald-700 ring-emerald-600/20",
warning: "bg-amber-50 text-amber-800 ring-amber-600/20",
danger: "bg-red-50 text-red-700 ring-red-600/20",
};
export function StatusBadge({ status, label }: { status: Status; label: string }) {
return (
<span
className={`inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ring-1 ring-inset ${statusClasses[status]}`}
>
{label}
</span>
);
}
External UI package या CMS से classes आती हों, तो @source या @source inline() कम मात्रा में use करें।
@import "tailwindcss";
@source "../node_modules/@acme/ui-kit";
@source inline("bg-emerald-50");
@source inline("text-emerald-700");
@source inline("bg-amber-50");
@source inline("text-amber-800");
Visual Check जरूरी है
Build pass होना UI सही होने की guarantee नहीं है। Playwright हो तो important widths पर screenshot compare करें।
import { expect, test } from "@playwright/test";
const viewports = [
{ name: "mobile", size: { width: 375, height: 812 } },
{ name: "tablet", size: { width: 768, height: 1024 } },
{ name: "desktop", size: { width: 1440, height: 960 } },
];
for (const viewport of viewports) {
test(`pricing page visual check - ${viewport.name}`, async ({ page }) => {
await page.setViewportSize(viewport.size);
await page.goto("/pricing");
await expect(page.getByRole("main")).toHaveScreenshot(
`pricing-${viewport.name}.png`,
{ maxDiffPixelRatio: 0.01 },
);
});
}
Use Cases और Pitfalls
| Use case | Claude Code task | Tailwind focus |
|---|---|---|
| Landing page | hero, CTA, pricing cards साथ में review | spacing, heading scale, CTA visibility |
| SaaS dashboard | table, filter, sidebar, empty state organize | overflow, density, sticky header |
| Lead form | input, error, success, disabled states cover | focus ring, labels, tap target |
| Content site | article, code block, ads, CTA साथ देखें | reading width, code scroll, links |
Common pitfalls हैं dynamic classes, desktop-only review, अधूरा dark mode, @apply का overuse, मिलते-जुलते colors बढ़ाना, form error state भूलना, और screenshot skip करना।
Monetization CTA और नतीजा
Tailwind सुधार का मतलब सिर्फ सुंदर UI नहीं है। Content site में article-end CTA, template product में pricing card, और team service में consultation form को साथ जांचें। ClaudeCodeLab में free Claude Code cheatsheet, practical products and templates, और team training or consultation उपलब्ध हैं।
इस workflow को ClaudeCodeLab pages पर आजमाने के बाद सबसे बड़ा फर्क audit prompt और 375px screenshot check से आया। इससे CTA spacing, form focus और dark mode contrast problems जल्दी पकड़े गए, और बाद में लंबे className खोलकर फिर से सुधारने की जरूरत कम हुई।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code permission safety ladder: access धीरे-धीरे बढ़ाएं
read-only से limited edits, proof commands और deploy checks तक permission बढ़ाने की सुरक्षित ladder.
Claude Code Small PR Proof Pack: छोटे PR को review-ready बनाना
Claude Code PR के लिए diff, checks, public URL, CTA path और rollback वाला practical proof pack.
Claude Code Review Gate Before Commit: diff, test, public URL और CTA जांच
Claude Code से commit से पहले review gate बनाएं: diff, build, public URL, Gumroad, consultation, tests और unrelated files।