{
"$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.
@media (max-width: 600px) {\n .panel {\n background: lightcoral;\n }\n}",
"task": "Write a media query with @media (max-width: 600px) that changes .panel background to lightcoral.",
"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", "concept": { "explanation": "Viewport units (vw, vh, vmin, vmax) scale proportionally with the browser window—1vw equals 1% of viewport width, so 5vw on a 1000px screen equals 50px. As the user resizes, the browser recalculates in real-time: 5vw becomes 30px on a 600px screen or 70px on a 1400px screen, creating truly fluid typography without media query breakpoints. However, pure vw units can become too small on mobile or too large on wide screens. Production sites often use clamp(16px, 5vw, 48px) to set minimum and maximum bounds for readability.", "diagram": "Viewport Width Units (vw)\n\nHow 5vw calculates across screen sizes:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nMobile (375px wide):\n1vw = 375px / 100 = 3.75px\n5vw = 3.75px × 5 = 18.75px\n┌──────────┐\n│ Text │ 18.75px font\n└──────────┘\n 375px\n\nTablet (768px wide):\n1vw = 768px / 100 = 7.68px\n5vw = 7.68px × 5 = 38.4px\n┌─────────────────────┐\n│ Text │ 38.4px font\n└─────────────────────┘\n 768px\n\nDesktop (1440px wide):\n1vw = 1440px / 100 = 14.4px\n5vw = 14.4px × 5 = 72px\n┌───────────────────────────────────────┐\n│ Text │ 72px font\n└───────────────────────────────────────┘\n 1440px\n\nViewport Unit Reference:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nvw = 1% of viewport width\nvh = 1% of viewport height\nvmin = 1% of viewport's smaller dimension\nvmax = 1% of viewport's larger dimension\n\nExample with 800px × 600px viewport:\n 1vw = 8px (1% of 800px)\n 1vh = 6px (1% of 600px)\n 1vmin = 6px (1% of smaller: 600px)\n 1vmax = 8px (1% of larger: 800px)\n\nProblem: Unbounded Scaling\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nPure vw can be too small or too large:\n\nMobile (320px): font-size: 5vw → 16px ✓ OK\nTablet (768px): font-size: 5vw → 38px ✓ OK\nDesktop (2560px): font-size: 5vw → 128px ✗ TOO BIG!\n\nSolution: Combine with clamp() or calc()\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nBetter approach:\nfont-size: clamp(16px, 5vw, 48px);\n ↓ ↓ ↓\n minimum fluid maximum\n\nResult across viewports:\n320px → 5vw = 16px → clamped to 16px (min)\n768px → 5vw = 38px → 38px (in range)\n2560px → 5vw = 128px → clamped to 48px (max)\n\nWhen to Use Fluid Typography:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nGood: Hero headings, banners, display text\nAvoid: Body text, UI elements (use rem instead)", "containerVsItem": "" }, "validations": [ { "type": "property_value", "value": { "property": "font-size", "expected": "5vw" }, "message": "Set font-size: 5vw" } ] }, { "id": "responsive-3", "title": "Responsive Grid", "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": "