{ "$schema": "../schemas/code-crispies-module-schema.json", "id": "flexbox", "title": "CSS Flexbox", "description": "Master the flexible box layout model for modern responsive designs", "difficulty": "intermediate", "lessons": [ { "id": "flexbox-1", "title": "Container", "description": "Before flexbox, creating even simple layouts required floats, positioning hacks, or table-based layouts. Flexbox (Flexible Box Layout) revolutionized CSS by providing a one-dimensional layout system designed specifically for distributing space and aligning content.

How it works: When you set display: flex on an element, it becomes a flex container. Its direct children automatically become flex items that flow along a main axis (horizontal by default). This single property transforms stacked block elements into a horizontal row.

The two axes:
Main axis – The primary direction items flow (row = left→right)
Cross axis – Perpendicular to main (row = top→bottom)

.nav {\n  display: flex;\n}
", "task": "The navigation links are stacking vertically. Make them display side by side in a horizontal row.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; } .nav a:hover { background: rgba(255,255,255,0.1); }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "display: flex;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "display", "expected": "flex" }, "message": "Try changing the display mode to create a flex container" } ] }, { "id": "flexbox-2", "title": "Gap", "description": "The gap property adds consistent spacing between flex items without needing margins. It only creates space between items, not around the edges.", "task": "The navigation links are crammed together with no breathing room. Add 1rem of spacing between them.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; display: flex; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; background: rgba(255,255,255,0.1); }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "gap: 1rem;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "gap", "expected": "1rem" }, "message": "Use the property that adds spacing between flex items" } ] }, { "id": "flexbox-3", "title": "Justify Content", "description": "justify-content distributes items along the main axis. Common values:
flex-start – pack items at the start
flex-end – pack at the end
center – center items
space-between – equal space between items
space-around – equal space around items", "task": "The Login button should sit on the far right, with the other links staying on the left. Distribute the space between them.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; display: flex; } .links { display: flex; gap: 8px; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; } .nav a:hover { background: rgba(255,255,255,0.1); } .login { background: steelblue; }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "justify-content: space-between;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "justify-content", "expected": "space-between" }, "message": "Use the property that distributes items along the main axis" } ] }, { "id": "flexbox-4", "title": "Align Items", "description": "align-items controls alignment on the cross axis (vertical when flex-direction is row). Values include:
stretch – stretch to fill (default)
flex-start – align to top
flex-end – align to bottom
center – center vertically", "task": "The logo and nav links sit at different heights. Center them vertically so they line up.", "previewHTML": "
ACME
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .header { background: white; padding: 1rem 2rem; display: flex; justify-content: space-between; border-bottom: 1px solid #eee; } .logo { font-size: 1.5rem; font-weight: bold; color: steelblue; } nav { display: flex; gap: 1rem; } nav a { color: #333; text-decoration: none; font-size: 0.9rem; }", "sandboxCSS": "", "codePrefix": ".header {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "align-items: center;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "align-items", "expected": "center" }, "message": "Use the property that controls cross-axis alignment" } ] }, { "id": "flexbox-5", "title": "Flex Wrap", "description": "By default, flex items squeeze onto one line. flex-wrap: wrap allows items to flow onto multiple lines when they run out of space.", "task": "The cards overflow the container instead of fitting within it. Allow the items to flow onto new rows when they run out of space.", "previewHTML": "
Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .cards { display: flex; gap: 1rem; } .card { background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); min-width: 120px; text-align: center; }", "sandboxCSS": "", "codePrefix": ".cards {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "flex-wrap: wrap;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "flex-wrap", "expected": "wrap" }, "message": "Use the property that allows flex items to wrap onto new lines" } ] }, { "id": "flexbox-6", "title": "Flex Grow", "description": "The flex property on items controls how they grow and shrink. flex: 1 makes an item grow to fill available space. Multiple items with flex: 1 share space equally.", "task": "The search input is too narrow. Make it stretch to fill all the remaining space in the toolbar.", "previewHTML": "
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .toolbar { display: flex; gap: 8px; padding: 1rem; background: #f5f5f5; border-radius: 8px; } .search { padding: 8px 1rem; border: 1px solid #ddd; border-radius: 4px; font-size: 1rem; } .btn { padding: 8px 1rem; background: steelblue; color: white; border: none; border-radius: 4px; cursor: pointer; }", "sandboxCSS": "", "codePrefix": ".search {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "flex: 1;", "previewContainer": "preview-area", "validations": [ { "type": "regex", "value": "(flex\\s*:\\s*1|flex-grow\\s*:\\s*1)", "message": "Use the property that makes a flex item grow to fill available space" } ] } ] }