- Added 'concept' objects to all 6 Grid lessons - Explanations cover 2D grid system, tracks, and cell placement - ASCII diagrams illustrate grid layouts, spanning, and overlapping - Clear container vs item distinctions for each property - Lessons: grid basics, template areas, spanning, auto-fit, alignment, overlapping - All concepts follow schema (explanation required, diagram and containerVsItem optional) - JSON validated successfully
293 lines
20 KiB
JSON
293 lines
20 KiB
JSON
{
|
|
"$schema": "../schemas/code-crispies-module-schema.json",
|
|
"id": "grid",
|
|
"title": "Grid",
|
|
"description": "Master the grid layout system for complex two-dimensional layouts",
|
|
"difficulty": "intermediate",
|
|
"lessons": [
|
|
{
|
|
"id": "grid-1",
|
|
"title": "Grid Container Basics",
|
|
"description": "Learn how to create a grid container and define basic grid structures.<br><br><pre>.container {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 1rem;\n}</pre>",
|
|
"task": "Create a <kbd>.grid</kbd> with <kbd>display: grid</kbd>, <kbd>grid-template-columns: repeat(3, 1fr)</kbd>, and <kbd>gap: 1rem</kbd>.",
|
|
"previewHTML": "<div class='grid'><div class='item'>1</div><div class='item'>2</div><div class='item'>3</div><div class='item'>4</div><div class='item'>5</div><div class='item'>6</div></div>",
|
|
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .item { background-color: #9b59b6; color: white; padding: 1.25rem; text-align: center; font-weight: bold; }",
|
|
"sandboxCSS": ".grid { border: 0.125rem dashed #ccc; padding: 1rem; }",
|
|
"codePrefix": "/* Create a grid with 3 equal columns and gap */\n",
|
|
"initialCode": "",
|
|
"codeSuffix": "",
|
|
"solution": ".grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 1rem;\n}",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "CSS Grid is a 2D layout system that divides space into rows and columns, called tracks. Unlike Flexbox which flows in one direction, Grid controls both axes simultaneously. The 1fr unit creates flexible tracks that share available space equally, while gap adds spacing between grid cells without affecting the outer edges.",
|
|
"diagram": "Grid with 3 columns (tracks)\n\n┌───────────────────────────────┐\n│ GRID CONTAINER │\n│ ┌───┐ ┌───┐ ┌───┐ │\n│ │ 1 │ │ 2 │ │ 3 │ Row 1 │\n│ └───┘ └───┘ └───┘ │\n│ ↑ ↑ ↑ │\n│ 1fr 1fr 1fr (equal) │\n│ ┌───┐ ┌───┐ ┌───┐ │\n│ │ 4 │ │ 5 │ │ 6 │ Row 2 │\n│ └───┘ └───┘ └───┘ │\n│ ← gap between cells → │\n└───────────────────────────────┘",
|
|
"containerVsItem": "display: grid, grid-template-columns, and gap are all CONTAINER properties. The parent defines the grid structure and spacing, while children automatically flow into grid cells."
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": ".grid",
|
|
"message": "Use the <kbd>.grid</kbd> class selector",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "display",
|
|
"expected": "grid"
|
|
},
|
|
"message": "Set <kbd>display: grid</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "grid-template-columns:\\s*repeat\\(\\s*3\\s*,\\s*1fr\\s*\\)",
|
|
"message": "Set <kbd>grid-template-columns: repeat(3, 1fr)</kbd>",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "gap",
|
|
"expected": "1rem"
|
|
},
|
|
"message": "Set <kbd>gap: 1rem</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "grid-2",
|
|
"title": "Grid Template Areas",
|
|
"description": "Use named grid areas to create visual layouts that are easy to understand.",
|
|
"task": "Add <kbd>grid-template-areas</kbd> to create a layout with <kbd>header</kbd> spanning full width, <kbd>sidebar</kbd> and <kbd>content</kbd> in middle, and <kbd>footer</kbd> spanning full width.",
|
|
"previewHTML": "<div class='page'><div class='header'>Header</div><div class='sidebar'>Sidebar</div><div class='content'>Main Content</div><div class='footer'>Footer</div></div>",
|
|
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .page > div { padding: 1.25rem; color: white; text-align: center; font-weight: bold; } .header { background-color: #e74c3c; } .sidebar { background-color: #3498db; } .content { background-color: #2ecc71; } .footer { background-color: #f39c12; }",
|
|
"sandboxCSS": ".page { border: 0.125rem dashed #ccc; padding: 1rem; height: 25rem; }",
|
|
"codePrefix": "/* Create a layout using grid-template-areas */\n.page {\n display: grid;\n grid-template-columns: 12rem 1fr;\n grid-template-rows: auto 1fr auto;\n gap: 1rem;\n \n /* Add your grid-template-areas code below */\n",
|
|
"initialCode": "",
|
|
"codeSuffix": "\n}\n\n/* Define which element goes in which grid area */\n.header {\n grid-area: header;\n}\n\n.sidebar {\n grid-area: sidebar;\n}\n\n.content {\n grid-area: content;\n}\n\n.footer {\n grid-area: footer;\n}",
|
|
"solution": "grid-template-areas:\n \"header header\"\n \"sidebar content\"\n \"footer footer\";",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "Grid template areas let you create visual ASCII-art layouts that mirror your design. Each string represents a row, and each name represents a column. When the same name appears multiple times in a row or column, that element spans across those cells. This makes complex layouts readable and maintainable.",
|
|
"diagram": "grid-template-areas layout\n\n┌─────────────────────────┐\n│ \"header header\" │\n│ ┌─────────────────────┐ │\n│ │ Header │ │\n│ └─────────────────────┘ │\n│ │\n│ \"sidebar content\" │\n│ ┌──────┐ ┌────────────┐│\n│ │Side- │ │ Main ││\n│ │ bar │ │ Content ││\n│ └──────┘ └────────────┘│\n│ │\n│ \"footer footer\" │\n│ ┌─────────────────────┐ │\n│ │ Footer │ │\n│ └─────────────────────┘ │\n└─────────────────────────┘",
|
|
"containerVsItem": "grid-template-areas is a CONTAINER property that defines named regions. Items use grid-area (an ITEM property) to assign themselves to those regions."
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": "grid-template-areas",
|
|
"message": "Use the <kbd>grid-template-areas</kbd> property",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "grid-template-areas:\\s*['\"]header\\s+header['\"]\\s*['\"]sidebar\\s+content['\"]\\s*['\"]footer\\s+footer['\"]",
|
|
"message": "Create areas: <kbd>\"header header\" \"sidebar content\" \"footer footer\"</kbd>",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "grid-3",
|
|
"title": "Spanning Grid Cells",
|
|
"description": "Make grid items span multiple grid cells horizontally or vertically.",
|
|
"task": "Add <kbd>grid-column: span 2</kbd> and <kbd>grid-row: span 2</kbd> to <kbd>.featured</kbd> to span 2x2 cells.",
|
|
"previewHTML": "<div class='grid'><div class='item'>1</div><div class='item'>2</div><div class='item featured'>Featured</div><div class='item'>4</div><div class='item'>5</div><div class='item'>6</div><div class='item'>7</div><div class='item'>8</div><div class='item'>9</div></div>",
|
|
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .item { background-color: #9b59b6; color: white; padding: 1.25rem; text-align: center; font-weight: bold; } .featured { background-color: #e74c3c; }",
|
|
"sandboxCSS": ".grid { border: 0.125rem dashed #ccc; padding: 1rem; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }",
|
|
"codePrefix": "/* Make the featured item span 2x2 cells */\n",
|
|
"initialCode": "",
|
|
"codeSuffix": "",
|
|
"solution": ".featured {\n grid-column: span 2;\n grid-row: span 2;\n}",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "Grid items can span across multiple cells using grid-column and grid-row with the span keyword. This lets individual items occupy more than one grid track in either direction. The grid automatically adjusts remaining items around the spanning element, flowing them into available cells.",
|
|
"diagram": "Grid with spanning item\n\n┌─────────────────────────┐\n│ ┌───┐ ┌───┐ │\n│ │ 1 │ │ 2 │ │\n│ └───┘ └───┘ │\n│ ┌─────────┐ ┌───┐ │\n│ │Featured │ │ 4 │ │\n│ │ (2x2) │ └───┘ │\n│ │ span 2 │ ┌───┐ │\n│ │ cols & │ │ 5 │ │\n│ │ rows │ └───┘ │\n│ └─────────┘ │\n│ ┌───┐ ┌───┐ ┌───┐ │\n│ │ 6 │ │ 7 │ │ 8 │ │\n│ └───┘ └───┘ └───┘ │\n└─────────────────────────┘",
|
|
"containerVsItem": "grid-column and grid-row are ITEM properties. Individual children control their own spanning behavior, while the container just defines the grid structure."
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": ".featured",
|
|
"message": "Use the <kbd>.featured</kbd> class selector",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "grid-column:\\s*span\\s+2",
|
|
"message": "Set <kbd>grid-column: span 2</kbd>",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "grid-row:\\s*span\\s+2",
|
|
"message": "Set <kbd>grid-row: span 2</kbd>",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "grid-4",
|
|
"title": "Automatic Grid Placement",
|
|
"description": "Learn how to use auto-placement and <kbd>auto-fit</kbd>/<kbd>auto-fill</kbd> for responsive grid layouts.",
|
|
"task": "Add <kbd>display: grid</kbd> and <kbd>grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr))</kbd> to <kbd>.cards</kbd>.",
|
|
"previewHTML": "<div class='cards'><div class='card'>Card 1</div><div class='card'>Card 2</div><div class='card'>Card 3</div><div class='card'>Card 4</div><div class='card'>Card 5</div><div class='card'>Card 6</div></div>",
|
|
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .card { background-color: #3498db; color: white; padding: 1.25rem; text-align: center; font-weight: bold; height: 6rem; display: flex; align-items: center; justify-content: center; }",
|
|
"sandboxCSS": ".cards { border: 0.125rem dashed #ccc; padding: 1rem; }",
|
|
"codePrefix": "/* Create a responsive grid with auto-fit columns */\n",
|
|
"initialCode": "",
|
|
"codeSuffix": "",
|
|
"solution": ".cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));\n}",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "auto-fit with minmax creates responsive grids that automatically adapt to available space without media queries. minmax(10rem, 1fr) sets a minimum column width of 10rem and maximum of 1fr, while auto-fit creates as many columns as will fit. When there's extra space, columns expand to fill it. This creates truly fluid layouts.",
|
|
"diagram": "auto-fit responsive behavior\n\nWide viewport:\n┌──────────────────────────────┐\n│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │\n│ │ C1 │ │ C2 │ │ C3 │ │ C4 │ │\n│ └────┘ └────┘ └────┘ └────┘ │\n│ ┌────┐ ┌────┐ │\n│ │ C5 │ │ C6 │ (expands) │\n│ └────┘ └────┘ │\n└──────────────────────────────┘\n\nNarrow viewport:\n┌──────────┐\n│ ┌──────┐ │\n│ │ C1 │ │\n│ └──────┘ │\n│ ┌──────┐ │\n│ │ C2 │ │ (fewer cols)\n│ └──────┘ │\n└──────────┘",
|
|
"containerVsItem": "grid-template-columns with auto-fit is a CONTAINER property. The container automatically calculates how many columns fit, and children flow into those columns without needing individual sizing."
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": ".cards",
|
|
"message": "Use the <kbd>.cards</kbd> class selector",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "display",
|
|
"expected": "grid"
|
|
},
|
|
"message": "Set <kbd>display: grid</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "grid-template-columns:\\s*repeat\\(\\s*auto-fit\\s*,\\s*minmax\\(\\s*10rem\\s*,\\s*1fr\\s*\\)\\s*\\)",
|
|
"message": "Set <kbd>grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr))</kbd>",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "grid-5",
|
|
"title": "Grid Alignment",
|
|
"description": "Control the alignment of grid items within their cells on both axes.",
|
|
"task": "Add <kbd>justify-items: center</kbd> and <kbd>align-items: center</kbd> to center items within their cells.",
|
|
"previewHTML": "<div class='cells'><div class='item'>1</div><div class='item tall'>2</div><div class='item'>3</div><div class='item'>4</div><div class='item'>5</div><div class='item wide'>6</div></div>",
|
|
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .item { background-color: #9b59b6; color: white; padding: 1.25rem; text-align: center; font-weight: bold; width: 3rem; height: 3rem; } .tall { height: 6rem; } .wide { width: 6rem; }",
|
|
"sandboxCSS": ".cells { border: 0.125rem dashed #ccc; padding: 1rem; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; height: 25rem; }",
|
|
"codePrefix": "/* Center grid items both horizontally and vertically */\n.cells {\n /* Add alignment properties below */\n",
|
|
"initialCode": "",
|
|
"codeSuffix": "\n}",
|
|
"solution": "justify-items: center;\n align-items: center;",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "Grid alignment works on two axes: justify-items controls horizontal positioning (inline axis), while align-items controls vertical positioning (block axis). These are CONTAINER properties that set the default alignment for all items within their assigned grid cells. Items can override this with justify-self and align-self.",
|
|
"diagram": "Grid item alignment\n\n┌─────────┬─────────┬─────────┐\n│ │ │ │\n│ ┌─┐ │ ┌─┐ │ ┌─┐ │\n│ │1│ │ │2│ │ │3│ │ ← centered\n│ └─┘ │ │ │ │ └─┘ │ in cells\n│ │ └─┘ │ │\n├─────────┼─────────┼─────────┤\n│ │ │ │\n│ ┌─┐ │ ┌─┐ │ ┌───┐ │\n│ │4│ │ │5│ │ │ 6 │ │\n│ └─┘ │ └─┘ │ └───┘ │\n│ │ │ │\n└─────────┴─────────┴─────────┘\n ↑ ↑\n justify-items align-items\n (horizontal) (vertical)",
|
|
"containerVsItem": "justify-items and align-items are CONTAINER properties that set default alignment for all children. Individual items can use justify-self and align-self (ITEM properties) to override."
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "justify-items",
|
|
"expected": "center"
|
|
},
|
|
"message": "Set <kbd>justify-items: center</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "align-items",
|
|
"expected": "center"
|
|
},
|
|
"message": "Set <kbd>align-items: center</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "grid-6",
|
|
"title": "Overlapping Grid Items",
|
|
"description": "Learn how to create overlapping layouts by using grid positioning and <kbd>z-index</kbd>.",
|
|
"task": "Add <kbd>grid-column: 1</kbd>, <kbd>grid-row: 1</kbd>, and <kbd>z-index: 1</kbd> to <kbd>.overlay</kbd> to position it above the base.",
|
|
"previewHTML": "<div class='stack'><div class='base'>Base Content</div><div class='overlay'>Overlay</div></div>",
|
|
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .stack { position: relative; height: 15rem; } .base { background-color: #3498db; color: white; padding: 1.25rem; display: flex; align-items: center; justify-content: center; font-weight: bold; } .overlay { background-color: rgba(231, 76, 60, 0.7); color: white; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 1.5rem; }",
|
|
"sandboxCSS": ".stack { border: 0.125rem dashed #ccc; padding: 1rem; display: grid; grid-template-columns: 1fr; grid-template-rows: 1fr; }",
|
|
"codePrefix": "/* Position the overlay to cover the entire grid */\n.base {\n grid-column: 1;\n grid-row: 1;\n}\n\n.overlay {\n /* Add your code below to position the overlay */\n",
|
|
"initialCode": "",
|
|
"codeSuffix": "\n}",
|
|
"solution": "grid-column: 1;\n grid-row: 1;\n z-index: 1;",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "Unlike Flexbox's single-direction flow, Grid's 2D system allows multiple items to occupy the same grid cell by explicitly positioning them with grid-column and grid-row. When items overlap, z-index controls stacking order - higher values appear on top. This enables layered designs like image overlays, card effects, and complex compositions.",
|
|
"diagram": "Overlapping grid items\n\n┌─────────────────────────┐\n│ Grid Cell (1, 1) │\n│ │\n│ ┌──────────────────┐ │\n│ │ Base (z-index:0) │ │\n│ │ ┌────────────┐ │ │\n│ │ │ Overlay │ │ │\n│ └──┤ (z-index:1)├──┘ │\n│ │ (on top) │ │\n│ └────────────┘ │\n│ │\n│ Both items positioned │\n│ at grid-column: 1, │\n│ grid-row: 1 │\n└─────────────────────────┘",
|
|
"containerVsItem": "grid-column, grid-row, and z-index are all ITEM properties. Individual children control their own grid placement and stacking order independently."
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "grid-column",
|
|
"expected": "1"
|
|
},
|
|
"message": "Set <kbd>grid-column: 1</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": {
|
|
"property": "grid-row",
|
|
"expected": "1"
|
|
},
|
|
"message": "Set <kbd>grid-row: 1</kbd>",
|
|
"options": {
|
|
"exact": true
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "z-index:\\s*[1-9]\\d*",
|
|
"message": "Set <kbd>z-index</kbd> to a positive number",
|
|
"options": {
|
|
"caseSensitive": false
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|