Files
code-crispies/lessons/13-pseudo-elements.json
Michael Czechowski c560676544 feat: implement #4 — replace answer-revealing validation messages with pedagogical hints
Rewrite ~120 validation error messages across 17 English lesson modules
and their localized variants (ar, de, es, pl, uk) to use concept questions,
property hints, and directional nudges instead of revealing the exact
CSS property-value answers.

Priority modules (flexbox, box-model, colors, positioning) fully rewritten.
All remaining CSS modules updated. Only message strings changed — no
validation logic modifications.
2026-03-28 19:40:28 +01:00

114 lines
5.1 KiB
JSON

{
"$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. <kbd>::before</kbd> creates a virtual element as the first child.<br><br>It requires the <kbd>content</kbd> property to display anything (even if empty).<br><br><pre>.item::before {\n content: \"→ \";\n}</pre>",
"task": "Add a bullet before each list item using <kbd>::before</kbd> with <kbd>content: \"• \"</kbd>.",
"previewHTML": "<ul class=\"list\"><li>First item</li><li>Second item</li><li>Third item</li></ul>",
"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 <kbd>content</kbd> property"
},
{
"type": "contains",
"value": "•",
"message": "Add a bullet character <kbd>•</kbd>"
}
]
},
{
"id": "pseudo-2",
"title": "Styling ::before",
"description": "Pseudo-elements can be styled like any element. Add color, size, margins, and more.<br><br><pre>.item::before {\n content: \"★\";\n color: gold;\n margin-right: 8px;\n}</pre>",
"task": "Style the bullet with <kbd>color: coral</kbd>.",
"previewHTML": "<ul class=\"list\"><li>First item</li><li>Second item</li><li>Third item</li></ul>",
"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": "Which CSS property changes the text color of the bullet? Try a warm, pinkish-orange named color."
}
]
},
{
"id": "pseudo-3",
"title": "The ::after Element",
"description": "<kbd>::after</kbd> works like <kbd>::before</kbd> but inserts content as the last child. Common uses include badges, icons, or decorative elements.<br><br><pre>.new::after {\n content: \" ✓\";\n color: green;\n}</pre>",
"task": "Add a checkmark after completed items with <kbd>content: \" ✓\"</kbd>.",
"previewHTML": "<ul class=\"list\"><li class=\"done\">Buy groceries</li><li class=\"done\">Walk the dog</li><li>Read a book</li></ul>",
"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 <kbd>content</kbd> property"
},
{
"type": "contains",
"value": "✓",
"message": "Add a checkmark <kbd>✓</kbd>"
}
]
},
{
"id": "pseudo-4",
"title": "Decorative Lines",
"description": "Pseudo-elements with <kbd>content: \"\"</kbd> can create decorative shapes when combined with width, height, and background.<br><br><pre>.title::after {\n content: \"\";\n display: block;\n width: 50px;\n height: 3px;\n background: coral;\n}</pre>",
"task": "Create an underline decoration with <kbd>width: 40px</kbd>, <kbd>height: 3px</kbd>, and <kbd>background: steelblue</kbd>.",
"previewHTML": "<h2 class=\"title\">About Us</h2><p>We build great things.</p>",
"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": "How wide should the decorative line be? Check the task for the pixel value."
},
{
"type": "property_value",
"value": { "property": "height", "expected": "3px" },
"message": "Which CSS property controls the thickness of the line? A thin line looks best here."
},
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
"message": "Which CSS property fills the line with color? Use a steel-toned blue named color."
}
]
}
]
}