{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", "title": "CSS Grundlagen", "description": "Lerne die grundlegenden Bausteine von CSS: Eigenschaften, Werte und Selektoren. Dieses Modul vermittelt dir die Syntaxregeln, denen jede CSS-Deklaration folgt.", "difficulty": "beginner", "lessons": [ { "id": "css-properties", "title": "CSS-Eigenschaften", "description": "CSS gestaltet Elemente mit Deklarationen - Paaren aus Eigenschaften und Werten. Jede Deklaration folgt dem gleichen Muster:

property: value;

Die Eigenschaft ist das, was du ändern möchtest (wie color oder background). Der Wert ist das, worauf du es setzt. Ein Doppelpunkt trennt sie, und ein Semikolon beendet die Zeile.

Werte gibt es in verschiedenen Typen:
Schlüsselwörter: red, bold, center
Zahlen mit Einheiten: 16px, 2rem, 100%
Farben: steelblue, #ff0000", "task": "Vervollständige die Deklaration, indem du color: coral; hinzufügst, um die Textfarbe zu ändern.", "previewHTML": "

This text should turn coral.

", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", "sandboxCSS": "", "codePrefix": ".text {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "color: coral;", "validations": [ { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "Füge color: coral; hinzu" } ] }, { "id": "multiple-properties", "title": "Mehrere Eigenschaften", "description": "Eine Regel kann mehrere Deklarationen enthalten. Jede steht in einer eigenen Zeile und jede benötigt ein Semikolon am Ende:

.box {
background: gold;
color: navy;
padding: 1rem;
}

Die Reihenfolge spielt normalerweise keine Rolle - CSS wendet alle an. Bei Konflikten gewinnt die letzte.", "task": "Füge zwei Deklarationen hinzu: background: lavender; und padding: 1rem;", "previewHTML": "
A styled card with background and padding.
", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", "sandboxCSS": "", "codePrefix": ".card {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "background: lavender;\n padding: 1rem;", "validations": [ { "type": "property_value", "value": { "property": "background", "expected": "lavender" }, "message": "Füge background: lavender; hinzu" }, { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, "message": "Füge padding: 1rem; hinzu" } ] }, { "id": "type-selectors", "title": "Typ-Selektoren", "description": "Ein Selektor sagt dem Browser, welche Elemente gestylt werden sollen. Der einfachste Selektor ist ein Typ-Selektor — einfach der HTML-Tag-Name.

p {
color: steelblue;
}

Diese Regel zielt auf jedes <p>-Element auf der Seite. Typ-Selektoren eignen sich hervorragend für Basis-Styles.", "task": "Style alle Absätze. Schreibe eine Regel mit p als Selektor und setze color: steelblue.", "previewHTML": "
\n

Fresh Roasted Coffee

\n

Our beans are sourced from small farms in Colombia and Ethiopia.

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "p {\n color: steelblue;\n}", "validations": [ { "type": "regex", "value": "p\\s*\\{", "message": "Beginne mit p {, um Absätze auszuwählen" }, { "type": "property_value", "value": { "property": "color", "expected": "steelblue" }, "message": "Setze color: steelblue" } ] }, { "id": "styling-links", "title": "Links stylen", "description": "Typ-Selektoren funktionieren für jedes HTML-Element. Der a-Selektor zielt auf alle Links einer Seite.

Links haben standardmäßig eine blaue Farbe und Unterstreichung. Du kannst beides mit CSS ändern — verwende color für den Text und text-decoration: none, um die Unterstreichung zu entfernen.", "task": "Style die Navigationslinks. Schreibe eine Regel mit a als Selektor und setze color: coral.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "a {\n color: coral;\n}", "validations": [ { "type": "regex", "value": "a\\s*\\{", "message": "Beginne mit a {, um Links auszuwählen" }, { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "Setze color: coral" } ] }, { "id": "class-selectors", "title": "Klassen-Selektoren", "description": "Typ-Selektoren stylen alle Elemente dieses Typs. Aber was, wenn du nur einige davon stylen möchtest?

Klassen-Selektoren zielen auf Elemente mit einem bestimmten class-Attribut. Sie beginnen mit einem Punkt:

.badge {
background: coral;
}

Das stylt nur Elemente mit class=\"badge\".", "task": "Style das Benachrichtigungs-Badge. Schreibe eine Regel mit .badge als Selektor und setze background: tomato.", "previewHTML": "
\n

Dashboard

\n 3\n
\n

You have new notifications waiting.

", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", "value": "\\.badge\\s*\\{", "message": "Beginne mit .badge { (vergiss den Punkt nicht!)" }, { "type": "property_value", "value": { "property": "background", "expected": "tomato" }, "message": "Setze background: tomato" } ] }, { "id": "button-variants", "title": "Button-Varianten", "description": "Elemente können mehrere Klassen haben. Wenn du Klassen-Selektoren ohne Leerzeichen verkettst, zielst du auf Elemente, die alle diese Klassen haben:

.btn.primary {
background: steelblue;
}

Das zielt auf Elemente mit class=\"btn primary\", nicht nur auf .btn oder nur .primary.", "task": "Style den primären Button. Schreibe eine Regel mit .btn.primary als Selektor und setze background: steelblue.", "previewHTML": "
\n \n \n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", "value": "\\.btn\\.primary\\s*\\{", "message": "Verwende .btn.primary { (kein Leerzeichen zwischen den Klassen)" }, { "type": "property_value", "value": { "property": "background", "expected": "steelblue" }, "message": "Setze background: steelblue" } ] }, { "id": "specific-elements", "title": "Spezifische Elemente ansprechen", "description": "Manchmal soll eine Klasse auf verschiedenen Elementen unterschiedlich aussehen. Kombiniere einen Typ-Selektor mit einem Klassen-Selektor (ohne Leerzeichen), um spezifischer zu sein:

a.btn {
text-decoration: none;
}

Das stylt nur <a>-Elemente mit der btn-Klasse, nicht <button>-Elemente mit dieser Klasse.", "task": "Entferne die Unterstreichung von Link-Buttons. Schreibe eine Regel mit a.btn als Selektor und setze text-decoration: none.", "previewHTML": "
\n \n Link Button\n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; align-items: center; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: steelblue; color: white; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "a.btn {\n text-decoration: none;\n}", "validations": [ { "type": "regex", "value": "a\\.btn\\s*\\{", "message": "Verwende a.btn { (Typ + Klasse, kein Leerzeichen)" }, { "type": "property_value", "value": { "property": "text-decoration", "expected": "none" }, "message": "Setze text-decoration: none" } ] }, { "id": "grouping-selectors", "title": "Selektoren gruppieren", "description": "Wenn mehrere Elemente die gleichen Styles brauchen, liste sie durch Kommas getrennt auf. Das hält dein CSS sauber und wartbar.

h1, h2, h3 {
color: steelblue;
}

Das wendet die gleiche Farbe auf alle drei Überschriftenebenen in einer Regel an.", "task": "Style alle Überschriften einheitlich. Füge color: steelblue zum gruppierten h1, h2, h3-Selektor hinzu.", "previewHTML": "

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } p { color: #555; line-height: 1.6; }", "sandboxCSS": "", "codePrefix": "h1, h2, h3 {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "color: steelblue;", "validations": [ { "type": "property_value", "value": { "property": "color", "expected": "steelblue" }, "message": "Setze color: steelblue" } ] }, { "id": "descendant-selectors", "title": "Nachfahren-Selektoren", "description": "Ziele auf Elemente innerhalb anderer Elemente mit einem Leerzeichen zwischen den Selektoren. Das ist eines der nützlichsten Muster in CSS.

.nav a {
color: white;
}

Das stylt nur Links innerhalb von .nav und lässt andere Links unverändert.", "task": "Style Navigationslinks anders. Schreibe eine Regel mit .nav a als Selektor und setze color: white.", "previewHTML": "

Read more in our documentation.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; margin: 0; } .nav { background: steelblue; padding: 1rem; display: flex; gap: 1rem; border-radius: 8px; margin-bottom: 1rem; } .nav a { text-decoration: none; } p a { color: steelblue; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".nav a {\n color: white;\n}", "validations": [ { "type": "regex", "value": "\\.nav\\s+a\\s*\\{", "message": "Verwende .nav a { (Leerzeichen zwischen .nav und a)" }, { "type": "property_value", "value": { "property": "color", "expected": "white" }, "message": "Setze color: white" } ] }, { "id": "nested-styling", "title": "Verschachtelte Styles", "description": "Nachfahren-Selektoren ermöglichen kontextabhängige Styles. Das gleiche Element kann je nach Position unterschiedlich aussehen.

Zum Beispiel könnten Absätze in einer .card kleiner sein als Absätze in einem article.", "task": "Mache Absätze innerhalb der Karte kleiner. Schreibe eine Regel mit .card p als Selektor und setze font-size: 0.9rem.", "previewHTML": "

Article Title

This is a regular article paragraph with normal-sized text for comfortable reading.

Quick Tip

Card paragraphs should be slightly smaller to fit the compact design.

Back to regular article text here.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".card p {\n font-size: 0.9rem;\n}", "validations": [ { "type": "regex", "value": "\\.card\\s+p\\s*\\{", "message": "Verwende .card p { (Leerzeichen zwischen .card und p)" }, { "type": "property_value", "value": { "property": "font-size", "expected": "0.9rem" }, "message": "Setze font-size: 0.9rem" } ] } ] }