{ "$schema": "../schemas/code-crispies-module-schema.json", "id": "css-pseudo-elements", "title": "CSS Pseudo-elements", "description": "Create decorative elements and style specific parts of content with pseudo-elements.", "difficulty": "intermediate", "lessons": [ { "id": "pseudo-1", "title": "The ::before Element", "description": "Pseudo-elements let you style specific parts of an element. ::before creates a virtual element as the first child.

It requires the content property to display anything (even if empty).

.item::before {\n  content: \"→ \";\n}
", "task": "Add a bullet before each list item using ::before with content: \"• \".", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .list { list-style: none; padding: 0; margin: 0; } .list li { padding: 8px 0; }", "sandboxCSS": "", "codePrefix": ".list li::before {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "content: \"• \";", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "content", "message": "Use the content property" }, { "type": "contains", "value": "•", "message": "Add a bullet character " } ] }, { "id": "pseudo-2", "title": "Styling ::before", "description": "Pseudo-elements can be styled like any element. Add color, size, margins, and more.

.item::before {\n  content: \"★\";\n  color: gold;\n  margin-right: 8px;\n}
", "task": "Style the bullet with color: coral.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .list { list-style: none; padding: 0; margin: 0; } .list li { padding: 8px 0; } .list li::before { content: \"• \"; }", "sandboxCSS": "", "codePrefix": ".list li::before {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "color: coral;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "Set color: coral" } ] }, { "id": "pseudo-3", "title": "The ::after Element", "description": "::after works like ::before but inserts content as the last child. Common uses include badges, icons, or decorative elements.

.new::after {\n  content: \" ✓\";\n  color: green;\n}
", "task": "Add a checkmark after completed items with content: \" ✓\".", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .list { list-style: none; padding: 0; margin: 0; } .list li { padding: 8px 0; }", "sandboxCSS": "", "codePrefix": ".done::after {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "content: \" ✓\";", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "content", "message": "Use the content property" }, { "type": "contains", "value": "✓", "message": "Add a checkmark " } ] }, { "id": "pseudo-4", "title": "Decorative Lines", "description": "Pseudo-elements with content: \"\" can create decorative shapes when combined with width, height, and background.

.title::after {\n  content: \"\";\n  display: block;\n  width: 50px;\n  height: 3px;\n  background: coral;\n}
", "task": "Create an underline decoration with width: 40px, height: 3px, and background: steelblue.", "previewHTML": "

About Us

We build great things.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .title { margin: 0 0 1rem; } .title::after { content: \"\"; display: block; margin-top: 8px; } p { margin: 0; color: #666; }", "sandboxCSS": "", "codePrefix": ".title::after {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "width: 40px;\n height: 3px;\n background: steelblue;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "width", "expected": "40px" }, "message": "Set width: 40px" }, { "type": "property_value", "value": { "property": "height", "expected": "3px" }, "message": "Set height: 3px" }, { "type": "property_value", "value": { "property": "background", "expected": "steelblue" }, "message": "Set background: steelblue" } ] } ] }