{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "units-variables", "title": "CSS Units & Variables", "description": "Understand the variety of CSS measurement units and how to define and use custom properties for maintainable styles.", "difficulty": "beginner", "lessons": [ { "id": "units-1", "title": "Absolute vs. Relative Units", "description": "Learn the difference between px, rem, em, %, and vw/vh for flexible, responsive layouts.", "task": "Set the width of .box to 80% and max-width to 37.5rem.", "previewHTML": "
Resize me!
", "previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .box { background: #f5f5f5; padding: 1rem; }", "sandboxCSS": "", "codePrefix": "/* Set flexible sizing */\n.box {", "initialCode": "", "codeSuffix": "}", "solution": " width: 80%;\n max-width: 37.5rem;", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "width", "message": "Use width property", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "width", "expected": "80%" }, "message": "Set width to 80%" }, { "type": "contains", "value": "max-width", "message": "Use max-width property", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "max-width", "expected": "37.5rem" }, "message": "Set max-width to 37.5rem" } ] }, { "id": "units-2", "title": "CSS Custom Properties", "description": "Define and reuse variables (--custom properties) to centralize your theme values.", "task": "Create a --main-color variable in :root with #6200ee and apply it as the border color on .themed.", "previewHTML": "
Variable Box
", "previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .themed { padding: 1rem; border: 0.125rem solid #ddd; }", "sandboxCSS": "", "codePrefix": "/* Define and use a CSS variable */\n:root {", "initialCode": "", "codeSuffix": "}\n.themed { }", "solution": " --main-color: #6200ee;\n}\n.themed {\n border-color: var(--main-color);", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "--main-color", "message": "Define --main-color in :root", "options": { "caseSensitive": false } }, { "type": "contains", "value": "var(--main-color)", "message": "Use var(--main-color)", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border", "expected": "var(--main-color)" }, "message": "Apply variable to border color", "options": { "exact": false } } ] }, { "id": "units-3", "title": "Unit Calculations (calc)", "description": "Use the calc() function to combine different units in one expression.", "task": "Set the width of .sized to calc(100% - 2rem) and min-height to calc(10vh + 1rem).", "previewHTML": "
Calc Demo
", "previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .sized { background: #e8f5e9; padding: 1rem; }", "sandboxCSS": "", "codePrefix": "/* Use calc for dynamic sizing */\n.sized {", "initialCode": "", "codeSuffix": "}", "solution": " width: calc(100% - 2rem);\n min-height: calc(10vh + 1rem);", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "calc", "message": "Use calc() function", "options": { "caseSensitive": false } }, { "type": "regex", "value": "width:\\s*calc\\(100% - 2rem\\)", "message": "Width should be calc(100% - 2rem)", "options": { "caseSensitive": false } }, { "type": "regex", "value": "min-height:\\s*calc\\(10vh \\+ 1rem\\)", "message": "Min-height should be calc(10vh + 1rem)", "options": { "caseSensitive": false } } ] }, { "id": "units-4", "title": "Viewport & Responsive Units", "description": "Control layouts relative to viewport size with vw, vh, and vmin/vmax units.", "task": "Give .view a width of 50vw and height of 20vh.", "previewHTML": "
Viewport Box
", "previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .view { background: #ffe0b2; }", "sandboxCSS": "", "codePrefix": "/* Use viewport units */\n.view {", "initialCode": "", "codeSuffix": "}", "solution": " width: 50vw;\n height: 20vh;", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "vw", "message": "Use vw unit", "options": { "caseSensitive": false } }, { "type": "contains", "value": "vh", "message": "Use vh unit", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "width", "expected": "50vw" }, "message": "Set width to 50vw" }, { "type": "property_value", "value": { "property": "height", "expected": "20vh" }, "message": "Set height to 20vh" } ] } ] }