{
"$schema": "../schemas/code-crispies-module-schema.json",
"id": "tailwind-basics",
"title": "Tailwind",
"description": "Learn how Tailwind CSS revolutionizes styling by replacing traditional CSS selectors with utility-first classes. Understand the philosophy behind utility classes and how they solve common CSS problems like specificity conflicts and maintenance complexity.",
"mode": "tailwind",
"difficulty": "beginner",
"lessons": [
{
"id": "bg-colors",
"title": "Backgrounds",
"description": "Learn to apply background colors using Tailwind utilities.",
"task": "Add a blue background to the div using Tailwind classes.",
"previewHTML": "
Hello Tailwind!
",
"previewBaseCSS": "body { padding: 20px; font-family: sans-serif; }",
"sandboxCSS": "",
"initialCode": "",
"previewContainer": "preview-area",
"concept": {
"explanation": "Tailwind replaces custom CSS classes with pre-built utility classes that apply single CSS properties. Instead of writing .my-box { background-color: #3b82f6; } in a CSS file, you apply bg-blue-500 directly in HTML. The class name bg-blue-500 maps to a specific hex color (#3b82f6) from Tailwind's design system, ensuring consistent colors across your project. This eliminates the need to name things and context-switch between HTML and CSS files.",
"diagram": "Traditional CSS vs Tailwind\n\nTraditional CSS Approach:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nHTML:
\n ↑ Pre-built utility (no CSS file needed)\n\nColor Scale (50-950):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nbg-blue-50 ░░░ Lightest\nbg-blue-500 ███ Medium (default)\nbg-blue-950 ███ Darkest\n\nBenefit: No naming, no context-switching"
},
"validations": [
{
"type": "contains_class",
"value": "bg-blue-500",
"message": "Add the bg-blue-500 class for a blue background."
}
]
},
{
"id": "utility-first-philosophy",
"title": "Utility-First",
"description": "Tailwind CSS follows a utility-first approach where instead of writing custom CSS classes, you compose designs using small, single-purpose utility classes. Unlike traditional CSS where you might write .card { background: white; padding: 1rem; border-radius: 0.5rem; }, Tailwind provides pre-built utilities like bg-white, p-4, and rounded.
The bg-white utility sets background-color: white, p-4 applies padding: 1rem on all sides, and rounded adds border-radius: 0.25rem. This approach eliminates the need to context-switch between HTML and CSS files.",
"task": "Create a white card-like container with a small drop-shadow, 1rem padding and rounded corners.",
"previewHTML": "
\n
\n
Card Title
\n
This is a card component built entirely with utility classes!
\n
\n
",
"previewBaseCSS": "body { font-family: sans-serif; margin: 0; }",
"sandboxCSS": "/* Traditional CSS approach:\n.card {\n background-color: white;\n padding: 1rem;\n border-radius: 0.25rem;\n}\n*/",
"initialCode": "",
"previewContainer": "preview-area",
"concept": {
"explanation": "Utility-first CSS inverts traditional workflow: instead of semantic class names (.card, .button) that group multiple properties in separate CSS files, you compose components by combining single-purpose utilities directly in markup. This eliminates three major CSS problems: (1) naming things (no more .primary-btn vs .btn-primary debates), (2) specificity wars (utilities have equal specificity), and (3) unused CSS (only utilities you use get included). The tradeoff is longer HTML class lists, but Tailwind argues this is outweighed by no context-switching and automatic consistency.",
"diagram": "Traditional vs Utility-First Workflow\n\nTraditional Semantic CSS:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n1. Write HTML:
\n2. Switch to CSS: .card { ... }\n3. Name component: .card, .primary-card?\n4. Fight cascade: .card.special vs .special.card\n5. Dead CSS grows: Old .card variants pile up\n\nUtility-First Approach:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n1. Compose in HTML:
\n2. No CSS file needed (utilities pre-defined)\n3. No naming required (describe what it looks like)\n4. No specificity issues (all utilities = 0,0,1,0)\n5. PurgeCSS removes unused utilities automatically\n\nProblems Solved:\n✓ Naming: bg-white (descriptive, not semantic)\n✓ Specificity: All utilities equal weight\n✓ Dead CSS: Tree-shaking removes unused\n✓ Consistency: Design system baked in\n\nTradeoff:\n✗ Longer class lists in HTML\n✓ But: No CSS file, no context-switching"
},
"validations": [
{
"type": "contains_class",
"value": "bg-white",
"message": "Add bg-white to set the background color to white."
},
{
"type": "contains_class",
"value": "p-4",
"message": "Add p-4 to apply 1rem padding on all sides."
},
{
"type": "contains_class",
"value": "rounded",
"message": "Add rounded to apply border-radius of 0.25rem."
},
{
"type": "contains_class",
"value": "shadow-sm",
"message": "Add shadow-sm to apply small drop-shadow."
}
]
},
{
"id": "text-utilities",
"title": "Text Utilities",
"description": "Tailwind provides comprehensive text utilities for styling typography. Text colors use the pattern text-{color}-{shade} where colors include red, blue, green, etc., and shades range from 50 (lightest) to 950 (darkest). For example, text-blue-600 applies a medium blue color.
Text sizes follow the pattern text-{size} with options like text-sm (0.875rem), text-base (1rem), text-lg (1.125rem), text-xl (1.25rem), and larger sizes up to text-9xl. Font weights use font-{weight} such as font-normal, font-medium, font-semibold, and font-bold.",
"task": "Style the heading with text-blue-600 for color, text-2xl for size, and font-bold for weight.",
"previewHTML": "
\n
Welcome to Tailwind CSS
\n
This heading demonstrates text utilities in action.
\n
",
"previewBaseCSS": "body { font-family: sans-serif; margin: 0; }",
"sandboxCSS": "/* Traditional CSS would be:\nh1 {\n color: #2563eb;\n font-size: 1.5rem;\n font-weight: 700;\n}\n*/",
"initialCode": "",
"previewContainer": "preview-area",
"concept": {
"explanation": "Tailwind's text utilities follow a predictable naming convention that maps directly to CSS properties, making them easy to learn and remember. The pattern property-value (like text-blue-600 for color, text-2xl for size) creates a consistent mental model across all utilities. The color shade system (50-950) ensures accessible contrast ratios: lighter shades (50-300) for backgrounds, medium shades (400-600) for UI elements, darker shades (700-950) for text. This built-in design system prevents arbitrary color choices and maintains visual consistency across your entire application.",
"diagram": "Text Utility Naming Patterns\n\nColor Pattern: text-{color}-{shade}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\ntext-blue-600 → color: #2563eb\n ↑ ↑ ↑\n prop color shade\n\nShade Scale (contrast-optimized):\n50-300 ░░░ Light (backgrounds)\n400-600 ███ Medium (UI elements)\n700-950 ███ Dark (text, WCAG compliant)\n\nSize Pattern: text-{size}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\ntext-sm → font-size: 0.875rem (14px)\ntext-base → font-size: 1rem (16px)\ntext-2xl → font-size: 1.5rem (24px)\ntext-9xl → font-size: 8rem (128px)\n\nWeight Pattern: font-{weight}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nfont-normal → font-weight: 400\nfont-semibold → font-weight: 600\nfont-bold → font-weight: 700\n\nBenefit: Predictable, consistent system"
},
"validations": [
{
"type": "contains_class",
"value": "text-blue-600",
"message": "Add text-blue-600 to make the text blue"
},
{
"type": "contains_class",
"value": "text-2xl",
"message": "Add text-2xl to increase the font size to 1.5rem"
},
{
"type": "contains_class",
"value": "font-bold",
"message": "Add font-bold to make the text bold (font-weight: 700)"
}
]
},
{
"id": "spacing-utilities",
"title": "Spacing",
"description": "Tailwind's spacing utilities follow a consistent pattern using a spacing scale where each unit represents 0.25rem (4px). Padding utilities use p-{size} for all sides, px-{size} for horizontal (left/right), py-{size} for vertical (top/bottom), or individual sides like pt-{size}, pr-{size}, pb-{size}, pl-{size}.
Common sizes include p-2 (0.5rem), p-4 (1rem), p-6 (1.5rem), and p-8 (2rem). Margin follows the same pattern but uses m- instead of p-. For example, mx-auto centers an element horizontally by applying automatic left and right margins.",
"task": "Style the button with px-6 for horizontal padding, py-3 for vertical padding, and mx-auto to center it.",
"previewHTML": "
\n \n
",
"previewBaseCSS": "body { font-family: sans-serif; margin: 0; }",
"sandboxCSS": "/* Traditional CSS equivalent:\nbutton {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n margin-left: auto;\n margin-right: auto;\n}\n*/",
"initialCode": "",
"previewContainer": "preview-area",
"concept": {
"explanation": "Tailwind's spacing scale uses base-4 (0.25rem = 4px increments) because it creates harmonious visual rhythm and aligns with the 8pt grid system used by most design tools. The directional shorthands (px for horizontal, py for vertical) map to common CSS patterns but use intuitive abbreviations: p for padding, m for margin, x for horizontal axis, y for vertical axis. This system is more concise than CSS (px-6 vs padding-left: 1.5rem; padding-right: 1.5rem;) while being completely predictable: p-4 is always 1rem (4 × 0.25rem), regardless of context.",
"diagram": "Spacing Scale & Directional Shorthands\n\nBase-4 Scale (n × 0.25rem):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\np-1 0.25rem 4px ▏\np-2 0.5rem 8px ▎\np-4 1rem 16px ▌ ← Common default\np-6 1.5rem 24px ▊\np-8 2rem 32px █\np-12 3rem 48px ██\np-16 4rem 64px ████\n\nDirectional Shorthands:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ┌─── pt-4 ───┐\n │ │\npl-4 ────►┤ p-4 / px-6├◄──── pr-4\n │ py-3 │\n │ │\n └─── pb-4 ───┘\n\np-4 All sides (shorthand)\npx-6 Horizontal (x-axis: left + right)\npy-3 Vertical (y-axis: top + bottom)\npt/pr/pb/pl Individual sides\n\nmx-auto Horizontal centering\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n←auto→ [element] ←auto→\n\nBenefit: Consistent rhythm, predictable values"
},
"validations": [
{
"type": "contains_class",
"value": "px-6",
"message": "Add px-6 for horizontal padding (1.5rem left and right)"
},
{
"type": "contains_class",
"value": "py-3",
"message": "Add py-3 for vertical padding (0.75rem top and bottom)"
},
{
"type": "contains_class",
"value": "mx-auto",
"message": "Add mx-auto to center the button horizontally"
}
]
},
{
"id": "responsive-design",
"title": "Breakpoints",
"description": "Tailwind uses a mobile-first responsive design approach with breakpoint prefixes. The base utilities apply to all screen sizes, then you add prefixes for larger screens: sm: (640px+), md: (768px+), lg: (1024px+), xl: (1280px+), and 2xl: (1536px+).
For example, text-base md:text-lg lg:text-xl makes text normal size on mobile, larger on tablets (md), and even larger on desktop (lg). Each breakpoint overrides the previous one, so p-4 md:p-6 lg:p-8 means 1rem padding on mobile, 1.5rem on tablets, and 2rem on desktop.
Width utilities like w-full (100% width), w-1/2 (50% width), or fixed sizes like w-64 (16rem) can also be made responsive.",
"task": "Make the box responsive: w-full on mobile, md:w-1/2 on tablets, and lg:w-1/3 on desktop. Also add responsive text sizing with text-lg, md:text-xl, and lg:text-2xl.",
"previewHTML": "
\n
\n Responsive Box \n Resize your browser to see the effect!\n
\n
",
"previewBaseCSS": "body { font-family: sans-serif; margin: 0; }",
"sandboxCSS": "/* Traditional CSS would require media queries:\n.responsive-box {\n width: 100%;\n font-size: 1.125rem;\n}\n@media (min-width: 768px) {\n .responsive-box {\n width: 50%;\n font-size: 1.25rem;\n }\n}\n@media (min-width: 1024px) {\n .responsive-box {\n width: 33.333333%;\n font-size: 1.5rem;\n }\n}\n*/",
"initialCode": "",
"previewContainer": "preview-area",
"concept": {
"explanation": "Tailwind's responsive utilities eliminate the need to write media queries by using breakpoint prefixes that compile to min-width media queries. The mobile-first approach means base utilities apply to all screen sizes, then prefixed utilities (md:, lg:) override them at larger breakpoints. This inverts traditional CSS where you write desktop styles first, then override for mobile. Writing w-full md:w-1/2 lg:w-1/3 in HTML is more maintainable than context-switching to a CSS file and writing three separate media query blocks, especially when each breakpoint change is visible right where the element is defined.",
"diagram": "Responsive Breakpoint System\n\nMobile-First Cascade:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nw-full md:w-1/2 lg:w-1/3\n ↓ ↓ ↓\nBase @768px+ @1024px+\n\nBreakpoint Scale:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nsm: 640px Mobile landscape\nmd: 768px Tablet portrait\nlg: 1024px Tablet landscape / Desktop\nxl: 1280px Large desktop\n2xl: 1536px Extra large desktop\n\nCompiled CSS (Tailwind generates):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n.w-full { width: 100%; }\n\n@media (min-width: 768px) {\n .md\\:w-1\\/2 { width: 50%; }\n}\n\n@media (min-width: 1024px) {\n .lg\\:w-1\\/3 { width: 33.333%; }\n}\n\nVisual Effect:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nMobile (<768px): [████████████] 100%\nTablet (768-1024): [██████] 50%\nDesktop (1024px+): [████] 33%\n\nBenefit: No media queries, inline responsive logic"
},
"validations": [
{
"type": "contains_class",
"value": "w-full",
"message": "Add w-full for 100% width on mobile"
},
{
"type": "contains_class",
"value": "md:w-1/2",
"message": "Add md:w-1/2 for 50% width on tablet and up"
},
{
"type": "contains_class",
"value": "lg:w-1/3",
"message": "Add lg:w-1/3 for 33.33% width on desktop and up"
},
{
"type": "contains_class",
"value": "text-lg",
"message": "Add text-lg for the base text size"
},
{
"type": "contains_class",
"value": "md:text-xl",
"message": "Add md:text-xl for larger text on tablets"
},
{
"type": "contains_class",
"value": "lg:text-2xl",
"message": "Add lg:text-2xl for even larger text on desktop"
}
]
}
]
}