- Added 'concept' objects to all 5 Tailwind lessons explaining utility-first approach - Lesson 1 (Backgrounds): Explains pre-built utilities vs custom CSS, color scale system - Lesson 2 (Utility-First): Explains utility-first philosophy and problems it solves - Lesson 3 (Text Utilities): Explains naming patterns and color shade system - Lesson 4 (Spacing): Explains base-4 spacing scale and directional shorthands - Lesson 5 (Breakpoints): Explains mobile-first responsive utilities and media queries - All concepts include beginner-friendly explanations and detailed ASCII diagrams - Emphasizes how Tailwind differs from traditional CSS (no naming, no context-switching, no specificity wars) - Diagrams show workflow comparisons, naming patterns, spacing scales, and breakpoint cascades
181 lines
17 KiB
JSON
181 lines
17 KiB
JSON
{
|
||
"$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": "<div class=\"{{USER_CLASSES}} p-8 rounded\">Hello Tailwind!</div>",
|
||
"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: <div class=\"hero-box\">\nCSS: .hero-box { background-color: #3b82f6; }\n ↑ Custom name ↑ Custom color\n\nTailwind Approach:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nHTML: <div class=\"bg-blue-500\">\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 <kbd>bg-blue-500</kbd> 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 <kbd>.card { background: white; padding: 1rem; border-radius: 0.5rem; }</kbd>, Tailwind provides pre-built utilities like <kbd>bg-white</kbd>, <kbd>p-4</kbd>, and <kbd>rounded</kbd>.<br><br>The <kbd>bg-white</kbd> utility sets <kbd>background-color: white</kbd>, <kbd>p-4</kbd> applies <kbd>padding: 1rem</kbd> on all sides, and <kbd>rounded</kbd> adds <kbd>border-radius: 0.25rem</kbd>. 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": "<div class=\"bg-gray-100 h-72 p-6\">\n <div class=\"{{USER_CLASSES}}\">\n <h3 class=\"text-lg font-semibold mb-2\">Card Title</h3>\n <p class=\"text-gray-600\">This is a card component built entirely with utility classes!</p>\n </div>\n</div>",
|
||
"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: <div class=\"card\">\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: <div class=\"bg-white p-4 rounded shadow-sm\">\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 <kbd>bg-white</kbd> to set the background color to white."
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "p-4",
|
||
"message": "Add <kbd>p-4</kbd> to apply 1rem padding on all sides."
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "rounded",
|
||
"message": "Add <kbd>rounded</kbd> to apply border-radius of 0.25rem."
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "shadow-sm",
|
||
"message": "Add <kbd>shadow-sm</kbd> 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 <kbd>text-{color}-{shade}</kbd> where colors include red, blue, green, etc., and shades range from 50 (lightest) to 950 (darkest). For example, <kbd>text-blue-600</kbd> applies a medium blue color.<br><br>Text sizes follow the pattern <kbd>text-{size}</kbd> with options like <kbd>text-sm</kbd> (0.875rem), <kbd>text-base</kbd> (1rem), <kbd>text-lg</kbd> (1.125rem), <kbd>text-xl</kbd> (1.25rem), and larger sizes up to <kbd>text-9xl</kbd>. Font weights use <kbd>font-{weight}</kbd> such as <kbd>font-normal</kbd>, <kbd>font-medium</kbd>, <kbd>font-semibold</kbd>, and <kbd>font-bold</kbd>.",
|
||
"task": "Style the heading with <kbd>text-blue-600</kbd> for color, <kbd>text-2xl</kbd> for size, and <kbd>font-bold</kbd> for weight.",
|
||
"previewHTML": "<div class=\"p-6 bg-gray-50\">\n <h1 class=\"{{USER_CLASSES}} mb-4\">Welcome to Tailwind CSS</h1>\n <p class=\"text-gray-700\">This heading demonstrates text utilities in action.</p>\n</div>",
|
||
"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 <kbd>text-blue-600</kbd> to make the text blue"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "text-2xl",
|
||
"message": "Add <kbd>text-2xl</kbd> to increase the font size to 1.5rem"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "font-bold",
|
||
"message": "Add <kbd>font-bold</kbd> 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 <kbd>p-{size}</kbd> for all sides, <kbd>px-{size}</kbd> for horizontal (left/right), <kbd>py-{size}</kbd> for vertical (top/bottom), or individual sides like <kbd>pt-{size}</kbd>, <kbd>pr-{size}</kbd>, <kbd>pb-{size}</kbd>, <kbd>pl-{size}</kbd>.<br><br>Common sizes include <kbd>p-2</kbd> (0.5rem), <kbd>p-4</kbd> (1rem), <kbd>p-6</kbd> (1.5rem), and <kbd>p-8</kbd> (2rem). Margin follows the same pattern but uses <kbd>m-</kbd> instead of <kbd>p-</kbd>. For example, <kbd>mx-auto</kbd> centers an element horizontally by applying automatic left and right margins.",
|
||
"task": "Style the button with <kbd>px-6</kbd> for horizontal padding, <kbd>py-3</kbd> for vertical padding, and <kbd>mx-auto</kbd> to center it.",
|
||
"previewHTML": "<div class=\"p-6 bg-gray-100\">\n <button class=\"{{USER_CLASSES}} bg-blue-500 text-white rounded block\">\n Centered Button\n </button>\n</div>",
|
||
"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 <kbd>px-6</kbd> for horizontal padding (1.5rem left and right)"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "py-3",
|
||
"message": "Add <kbd>py-3</kbd> for vertical padding (0.75rem top and bottom)"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "mx-auto",
|
||
"message": "Add <kbd>mx-auto</kbd> 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: <kbd>sm:</kbd> (640px+), <kbd>md:</kbd> (768px+), <kbd>lg:</kbd> (1024px+), <kbd>xl:</kbd> (1280px+), and <kbd>2xl:</kbd> (1536px+).<br><br>For example, <kbd>text-base md:text-lg lg:text-xl</kbd> makes text normal size on mobile, larger on tablets (md), and even larger on desktop (lg). Each breakpoint overrides the previous one, so <kbd>p-4 md:p-6 lg:p-8</kbd> means 1rem padding on mobile, 1.5rem on tablets, and 2rem on desktop.<br><br>Width utilities like <kbd>w-full</kbd> (100% width), <kbd>w-1/2</kbd> (50% width), or fixed sizes like <kbd>w-64</kbd> (16rem) can also be made responsive.",
|
||
"task": "Make the box responsive: <kbd>w-full</kbd> on mobile, <kbd>md:w-1/2</kbd> on tablets, and <kbd>lg:w-1/3</kbd> on desktop. Also add responsive text sizing with <kbd>text-lg</kbd>, <kbd>md:text-xl</kbd>, and <kbd>lg:text-2xl</kbd>.",
|
||
"previewHTML": "<div class=\"p-6 bg-gray-100\">\n <div class=\"{{USER_CLASSES}} bg-purple-500 text-white p-6 rounded text-center\">\n <span>Responsive Box</span><br>\n <small class=\"opacity-75\">Resize your browser to see the effect!</small>\n </div>\n</div>",
|
||
"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 <kbd>w-full</kbd> for 100% width on mobile"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "md:w-1/2",
|
||
"message": "Add <kbd>md:w-1/2</kbd> for 50% width on tablet and up"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "lg:w-1/3",
|
||
"message": "Add <kbd>lg:w-1/3</kbd> for 33.33% width on desktop and up"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "text-lg",
|
||
"message": "Add <kbd>text-lg</kbd> for the base text size"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "md:text-xl",
|
||
"message": "Add <kbd>md:text-xl</kbd> for larger text on tablets"
|
||
},
|
||
{
|
||
"type": "contains_class",
|
||
"value": "lg:text-2xl",
|
||
"message": "Add <kbd>lg:text-2xl</kbd> for even larger text on desktop"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|