Files
code-crispies/lessons/08-responsive.json
Michael Czechowski 98d4362706 refactor: rewrite CSS lessons with realistic real-world examples
- Box Model: profile cards, alerts, buttons instead of generic boxes
- Flexbox: navigation bars, headers, toolbars, card layouts
- Grid: photo gallery with SVG images, product cards, dashboard layout
- Colors: notification alerts, buttons, badges with visible changes
- Units/Variables: article width, brand variables, sidebar calc, hero vh
- Responsive: feature cards grid instead of numbered divs
- Added missing solutions to enable "Show Expected" feature
- Fixed barely visible border color change in colors lesson

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-01-13 21:11:41 +01:00

127 lines
5.6 KiB
JSON

{
"$schema": "../schemas/code-crispies-module-schema.json",
"id": "responsive-design",
"title": "CSS Responsive Design",
"description": "Make your layouts adapt to different screen sizes using media queries and fluid design techniques.",
"difficulty": "intermediate",
"lessons": [
{
"id": "responsive-1",
"title": "Media Queries",
"description": "Understand the syntax and use cases for CSS media queries to apply styles conditionally based on viewport characteristics.<br><br><pre>@media (max-width: 600px) {\n .panel {\n background: lightcoral;\n }\n}</pre>",
"task": "Write a media query with <kbd>@media (max-width: 600px)</kbd> that changes <kbd>.panel</kbd> background to <kbd>lightcoral</kbd>.",
"previewHTML": "<div class=\"panel\">Resize the window</div>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .panel { padding: 1rem; background: lightblue; }",
"sandboxCSS": "",
"codePrefix": "/* Add your media query below */\n",
"initialCode": "",
"codeSuffix": "",
"solution": "@media (max-width: 600px) {\n .panel {\n background: lightcoral;\n }\n}",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
"message": "Use <kbd>@media (max-width: 600px)</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": ".panel",
"message": "Target <kbd>.panel</kbd> inside the media query",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
"message": "Set <kbd>background: lightcoral</kbd>",
"options": { "exact": false }
}
]
},
{
"id": "responsive-2",
"title": "Fluid Type",
"description": "Use relative units like <kbd>vw</kbd> to make font sizes scale with the viewport width.",
"task": "Set <kbd>font-size: 5vw</kbd> on <kbd>.text</kbd> so it scales as the viewport changes.",
"previewHTML": "<p class=\"text\">Fluid Typography</p>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; }",
"sandboxCSS": "",
"codePrefix": "/* Apply fluid font sizing */\n.text {",
"initialCode": "",
"codeSuffix": "}",
"solution": " font-size: 5vw;",
"previewContainer": "preview-area",
"validations": [
{ "type": "property_value", "value": { "property": "font-size", "expected": "5vw" }, "message": "Set <kbd>font-size: 5vw</kbd>" }
]
},
{
"id": "responsive-3",
"title": "Responsive Grid",
"description": "Combine CSS Grid with <kbd>auto-fit</kbd> or <kbd>auto-fill</kbd> for responsive column layouts that automatically adjust the number of columns based on available space.",
"task": "Add <kbd>display: grid</kbd>, <kbd>grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))</kbd>, and <kbd>gap: 1rem</kbd> to <kbd>.features</kbd>.",
"previewHTML": "<section class=\"features\"><article class=\"feature\"><h3>Fast</h3><p>Lightning quick load times</p></article><article class=\"feature\"><h3>Secure</h3><p>Enterprise-grade security</p></article><article class=\"feature\"><h3>Reliable</h3><p>99.9% uptime guaranteed</p></article><article class=\"feature\"><h3>Support</h3><p>24/7 customer service</p></article></section>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .feature { background: white; padding: 1rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .feature h3 { margin: 0 0 8px; color: steelblue; } .feature p { margin: 0; color: #666; font-size: 0.9rem; }",
"sandboxCSS": "",
"codePrefix": ".features {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
"message": "Set <kbd>display: grid</kbd>"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
"message": "Use <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
"message": "Set <kbd>gap: 1rem</kbd>"
}
]
},
{
"id": "responsive-4",
"title": "Mobile-First",
"description": "Adopt a mobile-first approach by writing base styles for small screens and enhancing for larger viewports.",
"task": "Write a media query with <kbd>@media (min-width: 768px)</kbd> that sets <kbd>.sidebar</kbd> width to <kbd>250px</kbd>.",
"previewHTML": "<aside class=\"sidebar\">Sidebar</aside>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .sidebar { background: #c8e6c9; padding: 1rem; }",
"sandboxCSS": "",
"codePrefix": "/* Add mobile-first enhancement */\n",
"initialCode": "",
"codeSuffix": "",
"solution": "@media (min-width: 768px) {\n .sidebar {\n width: 250px;\n }\n}",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
"message": "Use <kbd>@media (min-width: 768px)</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": ".sidebar",
"message": "Target <kbd>.sidebar</kbd> inside media query",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
"message": "Set <kbd>width: 250px</kbd>",
"options": { "exact": false }
}
]
}
]
}