{ "$schema": "../schemas/code-crispies-module-schema.json", "id": "responsive-design", "title": "Responsive", "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.", "task": "Write a media query with @media (max-width: 600px) that changes .panel background to lightcoral.", "previewHTML": "
Resize the window
", "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 @media (max-width: 600px)", "options": { "caseSensitive": false } }, { "type": "contains", "value": ".panel", "message": "Target .panel inside the media query", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "background", "expected": "lightcoral" }, "message": "Set background: lightcoral", "options": { "exact": false } } ] }, { "id": "responsive-2", "title": "Fluid Type", "description": "Use relative units like vw to make font sizes scale with the viewport width.", "task": "Set font-size: 5vw on .text so it scales as the viewport changes.", "previewHTML": "

Fluid Typography

", "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 font-size: 5vw" } ] }, { "id": "responsive-3", "title": "Flex Grids", "description": "Combine CSS Grid with auto-fit or auto-fill for responsive column layouts.", "task": "Add display: grid, grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)), and gap: 1rem to .cards.", "previewHTML": "
1
2
3
4
", "previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .cards > div { background: #d1c4e9; padding: 1rem; }", "sandboxCSS": "", "codePrefix": "/* Create a responsive grid */\n.cards {", "initialCode": "", "codeSuffix": "}", "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 display: grid" }, { "type": "regex", "value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)", "message": "Use repeat(auto-fit, minmax(200px, 1fr))", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "gap", "expected": "1rem" }, "message": "Set gap: 1rem" } ] }, { "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 @media (min-width: 768px) that sets .sidebar width to 250px.", "previewHTML": "", "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 @media (min-width: 768px)", "options": { "caseSensitive": false } }, { "type": "contains", "value": ".sidebar", "message": "Target .sidebar inside media query", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "width", "expected": "250px" }, "message": "Set width: 250px", "options": { "exact": false } } ] } ] }