Files
code-crispies/lessons/de/01-box-model.json
Michael Czechowski c3f1824059 feat: implement #9 — rewrite colors and box-model task descriptions
Rewrite task text in Colors (4 lessons) and Box Model (8 lessons x 6
locales) to describe visual outcomes instead of giving copy-paste CSS
answers. Colors validations changed from property_value to regex
accepting multiple valid named colors per lesson.
2026-03-28 23:56:55 +01:00

192 lines
10 KiB
JSON

{
"$schema": "../../schemas/code-crispies-module-schema.json",
"id": "box-model",
"title": "CSS Box Model",
"description": "Beherrsche die Grundprinzipien der Raumverwaltung im Webdesign durch das CSS Box-Modell. Dieses Modul erkundet, wie Inhalt, Padding, Rahmen und Margins zusammenwirken, um Layout-Strukturen zu erstellen.",
"difficulty": "beginner",
"lessons": [
{
"id": "box-model-1",
"title": "Padding",
"description": "Jedes Element in CSS ist eine Box mit vier Schichten: Inhalt, Padding, Rahmen und Margin. <strong>Padding</strong> schafft Freiraum zwischen deinem Inhalt und dem Rand der Box.<br><br>Ohne Padding drückt sich Text unangenehm gegen Rahmen. Padding macht Inhalte lesbar und visuell ausgewogen.<br><br><pre>.card {\n padding: 1rem;\n}</pre>",
"task": "Der Text in dieser Profilkarte klebt direkt an den Rändern. Gib ihm etwas inneren Freiraum zum Atmen.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
"codePrefix": ".card {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "padding: 1rem;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
"message": "Welche Eigenschaft fügt Abstand zwischen Inhalt und Elementrand hinzu?"
}
]
},
{
"id": "box-model-2",
"title": "Borders",
"description": "Rahmen erstellen visuelle Grenzen um Elemente. Die <kbd>border</kbd>-Kurzschreibweise akzeptiert drei Werte: Breite, Stil und Farbe.<br><br>Häufige Stile: <kbd>solid</kbd>, <kbd>dashed</kbd>, <kbd>dotted</kbd>, <kbd>none</kbd>",
"task": "Diese Karte könnte eine farbige Akzentlinie an der linken Seite gebrauchen.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
"codePrefix": ".card {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "border-left: 4px solid steelblue;",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
"message": "Verwende die Kurzschreibweise, die einen Rahmen auf nur einer Seite setzt",
"options": { "caseSensitive": false }
}
]
},
{
"id": "box-model-3",
"title": "Margins",
"description": "Margins schaffen Abstand <em>außerhalb</em> des Elements und trennen es von Nachbarn. Während Padding den Inhalt nach innen drückt, drücken Margins andere Elemente weg.",
"task": "Diese beiden Profilkarten berühren sich. Füge etwas Abstand unterhalb jeder Karte hinzu, um sie zu trennen.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article><article class=\"card\"><h3>Alex Rivera</h3><p>UX Designer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; border-left: 4px solid steelblue; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
"codePrefix": ".card {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "margin-bottom: 1rem;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
"message": "Welche Eigenschaft schiebt benachbarte Elemente nach unten weg?"
}
]
},
{
"id": "box-model-4",
"title": "Box Sizing",
"description": "Standardmäßig setzt <kbd>width</kbd> nur die Inhaltsbreite. Padding und Rahmen werden addiert. Das verursacht Layout-Probleme.<br><br><kbd>box-sizing: border-box</kbd> bezieht Padding und Rahmen in die Breite ein, was das Sizing vorhersehbar macht. Die meisten Entwickler wenden dies auf alle Elemente an.",
"task": "Beide Karten haben die gleiche Breite, aber die linke läuft über, weil Padding und Rahmen obendrauf addiert werden. Korrigiere die rechte Karte, damit ihre Größe Padding und Rahmen einschließt.",
"previewHTML": "<div class=\"demo\"><article class=\"card\">Content-box</article><article class=\"card fix\">Border-box</article></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .demo { display: flex; gap: 1rem; } .card { width: 200px; padding: 1rem; border: 4px solid steelblue; background: white; border-radius: 8px; }",
"sandboxCSS": "",
"codePrefix": ".fix {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "box-sizing: border-box;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
"message": "Welcher Größenmodus bezieht Padding und Rahmen in die Breite des Elements ein?"
}
]
},
{
"id": "box-model-5",
"title": "Padding Shorthand",
"description": "Padding akzeptiert 1-4 Werte:<br>• 1 Wert: alle Seiten<br>• 2 Werte: vertikal | horizontal<br>• 4 Werte: oben | rechts | unten | links",
"task": "Dieser Button fühlt sich zu eng an. Gib ihm mehr Platz an den Seiten als oben und unten, mit der Zwei-Werte-Kurzschreibweise.",
"previewHTML": "<button class=\"btn\">Follow</button>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .btn { background: steelblue; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; }",
"sandboxCSS": "",
"codePrefix": ".btn {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "padding: 8px 1rem;",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
"message": "Verwende die Zwei-Werte-Kurzschreibweise: vertikal zuerst, dann horizontal",
"options": { "caseSensitive": false }
}
]
},
{
"id": "box-model-6",
"title": "Margin Shorthand",
"description": "Margin nutzt das gleiche Kurzschreibweisen-Muster wie Padding. Ein häufiges Muster ist das horizontale Zentrieren von Block-Elementen mit <kbd>margin: 0 auto</kbd>.",
"task": "Diese Karte klebt links. Zentriere sie horizontal mit der Margin-Kurzschreibweise und automatischen Seitenabständen.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { width: 250px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; border-left: 4px solid steelblue; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
"codePrefix": ".card {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "margin: 0 auto;",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
"message": "Verwende die Kurzschreibweise, die gleiche horizontale Abstände automatisch berechnet",
"options": { "caseSensitive": false }
}
]
},
{
"id": "box-model-7",
"title": "Border Radius",
"description": "Obwohl nicht Teil des klassischen Box-Modells, rundet <kbd>border-radius</kbd> die Ecken der Rahmen-Box eines Elements. Verwende <kbd>50%</kbd> bei einem quadratischen Element, um einen Kreis zu erstellen.",
"task": "Das quadratische Avatar-Bild soll als perfekter Kreis erscheinen.",
"previewHTML": "<article class=\"card\"><img class=\"avatar\" src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='35' r='25' fill='%23666'/%3E%3Ccircle cx='50' cy='90' r='40' fill='%23666'/%3E%3C/svg%3E\" alt=\"Avatar\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; text-align: center; } .avatar { width: 80px; height: 80px; background: #ddd; margin-bottom: 8px; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
"codePrefix": ".avatar {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "border-radius: 50%;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
"message": "Welche Eigenschaft rundet Ecken? Denke daran, welcher Prozentwert einen Kreis ergibt"
}
]
},
{
"id": "box-model-8",
"title": "Complete Card",
"description": "Kombinieren wir alles. Diese Benachrichtigungskarte braucht Styling, um professionell auszusehen.",
"task": "Diese Benachrichtigung braucht drei Dinge: inneren Abstand damit der Text nicht gedrängt wirkt, einen farbigen Akzent an der linken Kante und leicht abgerundete Ecken.",
"previewHTML": "<div class=\"alert\"><strong>New message</strong><p>You have 3 unread notifications</p></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .alert { background: seashell; } .alert strong { color: coral; } .alert p { margin: 4px 0 0; color: #666; }",
"sandboxCSS": "",
"codePrefix": ".alert {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "padding: 1rem;\n border-left: 4px solid coral;\n border-radius: 4px;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
"message": "Füge inneren Abstand zur Benachrichtigung hinzu"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
"message": "Füge einen farbigen Akzent an der linken Kante hinzu",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
"message": "Runde die Ecken der Benachrichtigung ab"
}
]
}
]
}