Files
code-crispies/lessons/12-positioning.json
Michael Czechowski be9c753a0e feat: add new lesson modules and reach 101 total lessons
New CSS Modules:
- Gradients (3 lessons): linear-gradient, radial-gradient, direction
- Filters (4 lessons): blur, grayscale, brightness, drop-shadow
- Positioning (4 lessons): relative, absolute, offset properties
- Pseudo-elements (4 lessons): ::before, ::after, content, decorative

New HTML Module:
- Semantic HTML (3 lessons): article, section, aside

Expanded Existing Modules:
- Typography: +2 lessons (text-decoration, text-shadow)
- Tables: +2 lessons (thead/tbody/tfoot, colspan)

Total lessons: 101 (up from ~66)
- Enables full milestone system (1, 5, 10, 20, 30, 50, 75, 100)
- All modules added to all 6 language stores with EN fallback
2026-01-16 14:17:13 +01:00

99 lines
5.3 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"$schema": "../schemas/code-crispies-module-schema.json",
"id": "css-positioning",
"title": "CSS Positioning",
"description": "Control element placement with CSS positioning properties.",
"difficulty": "intermediate",
"lessons": [
{
"id": "position-1",
"title": "Relative Position",
"description": "The <kbd>position</kbd> property controls how elements are placed. <kbd>relative</kbd> keeps the element in normal flow but allows you to offset it with <kbd>top</kbd>, <kbd>right</kbd>, <kbd>bottom</kbd>, <kbd>left</kbd>.<br><br><pre>.box {\n position: relative;\n top: 10px;\n}</pre>",
"task": "Make the badge position relative so we can offset it.",
"previewHTML": "<div class=\"card\"><span class=\"badge\">NEW</span><h3>Product</h3></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .card { padding: 1rem; background: white; border: 2px solid #eee; border-radius: 8px; } .card h3 { margin: 0; } .badge { display: inline-block; padding: 2px 8px; background: coral; color: white; font-size: 0.7rem; font-weight: bold; border-radius: 4px; }",
"sandboxCSS": "",
"codePrefix": ".badge {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "position: relative;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "position", "expected": "relative" },
"message": "Set <kbd>position: relative</kbd>"
}
]
},
{
"id": "position-2",
"title": "Offset Properties",
"description": "With <kbd>position: relative</kbd>, use offset properties to nudge the element from its original position:<br><br><kbd>top</kbd> - pushes down from top<br><kbd>left</kbd> - pushes right from left<br><br>Negative values move in the opposite direction.",
"task": "Move the badge up with <kbd>top: -8px</kbd>.",
"previewHTML": "<div class=\"card\"><span class=\"badge\">NEW</span><h3>Product</h3></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .card { padding: 1rem; background: white; border: 2px solid #eee; border-radius: 8px; } .card h3 { margin: 0; } .badge { display: inline-block; padding: 2px 8px; background: coral; color: white; font-size: 0.7rem; font-weight: bold; border-radius: 4px; position: relative; }",
"sandboxCSS": "",
"codePrefix": ".badge {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "top: -8px;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "top", "expected": "-8px" },
"message": "Set <kbd>top: -8px</kbd>"
}
]
},
{
"id": "position-3",
"title": "Absolute Position",
"description": "<kbd>position: absolute</kbd> removes the element from normal flow and positions it relative to its nearest positioned ancestor (or the viewport if none exists).<br><br>Always set a parent to <kbd>position: relative</kbd> to contain absolute children.",
"task": "Position the close button absolutely.",
"previewHTML": "<div class=\"modal\"><button class=\"close\">×</button><h3>Modal</h3><p>Content here</p></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .modal { position: relative; padding: 2rem; background: white; border-radius: 12px; box-shadow: 0 4px 24px rgba(0,0,0,0.15); max-width: 250px; } .modal h3 { margin: 0 0 8px; } .modal p { margin: 0; color: #666; } .close { width: 32px; height: 32px; border: none; background: #f5f5f5; border-radius: 50%; font-size: 1.2rem; cursor: pointer; }",
"sandboxCSS": "",
"codePrefix": ".close {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "position: absolute;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "position", "expected": "absolute" },
"message": "Set <kbd>position: absolute</kbd>"
}
]
},
{
"id": "position-4",
"title": "Placing Absolute Elements",
"description": "Combine <kbd>position: absolute</kbd> with offset properties to place elements precisely.<br><br><pre>.close {\n position: absolute;\n top: 8px;\n right: 8px;\n}</pre>",
"task": "Move the close button to the top right corner with <kbd>top: 8px</kbd> and <kbd>right: 8px</kbd>.",
"previewHTML": "<div class=\"modal\"><button class=\"close\">×</button><h3>Modal</h3><p>Content here</p></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .modal { position: relative; padding: 2rem; background: white; border-radius: 12px; box-shadow: 0 4px 24px rgba(0,0,0,0.15); max-width: 250px; } .modal h3 { margin: 0 0 8px; } .modal p { margin: 0; color: #666; } .close { position: absolute; width: 32px; height: 32px; border: none; background: #f5f5f5; border-radius: 50%; font-size: 1.2rem; cursor: pointer; }",
"sandboxCSS": "",
"codePrefix": ".close {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "top: 8px;\n right: 8px;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "top", "expected": "8px" },
"message": "Set <kbd>top: 8px</kbd>"
},
{
"type": "property_value",
"value": { "property": "right", "expected": "8px" },
"message": "Set <kbd>right: 8px</kbd>"
}
]
}
]
}