{ "$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 position property controls how elements are placed. relative keeps the element in normal flow but allows you to offset it with top, right, bottom, left.

.box {\n  position: relative;\n  top: 10px;\n}
", "task": "Make the badge position relative so we can offset it.", "previewHTML": "
NEW

Product

", "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 position: relative" } ] }, { "id": "position-2", "title": "Offset Properties", "description": "With position: relative, use offset properties to nudge the element from its original position:

top - pushes down from top
left - pushes right from left

Negative values move in the opposite direction.", "task": "Move the badge up with top: -8px.", "previewHTML": "
NEW

Product

", "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 top: -8px" } ] }, { "id": "position-3", "title": "Absolute Position", "description": "position: absolute removes the element from normal flow and positions it relative to its nearest positioned ancestor (or the viewport if none exists).

Always set a parent to position: relative to contain absolute children.", "task": "Position the close button absolutely.", "previewHTML": "

Modal

Content here

", "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 position: absolute" } ] }, { "id": "position-4", "title": "Placing Absolute Elements", "description": "Combine position: absolute with offset properties to place elements precisely.

.close {\n  position: absolute;\n  top: 8px;\n  right: 8px;\n}
", "task": "Move the close button to the top right corner with top: 8px and right: 8px.", "previewHTML": "

Modal

Content here

", "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 top: 8px" }, { "type": "property_value", "value": { "property": "right", "expected": "8px" }, "message": "Set right: 8px" } ] } ] }