{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-advanced-selectors", "title": "CSS: Fortgeschrittene Selektoren", "description": "Meistere fortgeschrittene CSS-Selektor-Techniken einschließlich Attribut-Selektoren, Kombinatoren und Pseudo-Klassen. Dieses Modul baut auf grundlegenden Selektoren auf und gibt dir präzise Kontrolle über die Elementauswahl, was ausgefeilte Styling-Muster und interaktive Effekte ermöglicht.", "difficulty": "intermediate", "lessons": [ { "id": "attribute-selectors", "title": "Attribut-Selektoren: Anvisieren nach HTML-Attributen", "description": "Attribut-Selektoren ermöglichen es dir, Elemente basierend auf ihren HTML-Attributen und Attributwerten anzuvisieren. Sie sind unglaublich mächtig für das Styling von Formularen, Links und anderen Elementen mit spezifischen Attributen. Die grundlegende Syntax verwendet eckige Klammern: [attribute] wählt Elemente mit diesem Attribut, [attribute=\"value\"] wählt Elemente, bei denen das Attribut genau diesem Wert entspricht, und [attribute^=\"value\"] wählt Elemente, bei denen das Attribut mit diesem Wert beginnt. Du kannst diese ausgewählten Elemente mit Eigenschaften wie border stylen, um visuelle Grenzen hinzuzufügen, und background-color, um bestimmte Formularfelder oder Links hervorzuheben.", "task": "Erstelle eine CSS-Regel mit einem Attribut-Selektor, die alle input-Elemente mit type=\"text\" anvisiert. Gib ihnen einen lightblue-Hintergrund und einen 2px solid blue-Rahmen.", "previewHTML": "
\n

\n

\n

\n

\n
", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } form { max-width: 300px; } label { display: block; margin-bottom: 5px; } input, button { padding: 8px; margin-bottom: 10px; border-radius: 4px; }", "sandboxCSS": "", "codePrefix": "/* Visiere input-Elemente mit type=\"text\" mit einem Attribut-Selektor an */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "input[type=\"text\"] {\n background-color: lightblue;\n border: 2px solid blue\n}", "validations": [ { "type": "regex", "value": "^input\\[type=\"text\"\\]\\s*{", "message": "Verwende input[type=\"text\"] { … } als deinen Attribut-Selektor", "options": { "caseSensitive": true } }, { "type": "contains", "value": "background-color:", "message": "Füge die background-color-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "background-color", "expected": "lightblue" }, "message": "Setze die Hintergrundfarbe auf lightblue" }, { "type": "regex", "value": "background-color:\\s*[^;]*;", "message": "Vergiss nicht, die background-color-Deklaration mit einem Semikolon ; zu beenden" }, { "type": "contains", "value": "border:", "message": "Füge die border-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "border", "expected": "2px solid blue" }, "message": "Setze den Rahmen auf 2px solid blue" }, { "type": "regex", "value": "input\\[type=\"text\"\\]\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "attribute-partial-matching", "title": "Teilweises Attribut-Matching", "description": "Attribut-Selektoren unterstützen teilweise Matching-Muster, die es dir ermöglichen, Elemente basierend auf Teilen von Attributwerten anzuvisieren. Der [attribute^=\"value\"]-Selektor passt auf Elemente, bei denen das Attribut mit dem angegebenen Wert beginnt, [attribute$=\"value\"] passt, wenn es mit dem Wert endet, und [attribute*=\"value\"] passt, wenn der Wert irgendwo innerhalb des Attributs erscheint. Diese Muster sind besonders nützlich für das Styling externer Links, Dateitypen oder Elemente mit Klassennamen, die Namenskonventionen folgen. Beim Stylen dieser gematchten Elemente kannst du Eigenschaften wie color verwenden, um die Textfarbe zu ändern, und text-decoration, um visuelle Betonung wie Unterstreichungen hinzuzufügen.", "task": "Erstelle eine CSS-Regel, die alle Anker-Elemente (a) mit href-Attributen, die mit \"https\" beginnen, anvisiert. Style sie mit green-Textfarbe und underline-Textdekoration.", "previewHTML": "

Verschiedene Arten von Links

\n", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } ul { list-style-type: none; padding: 0; } li { margin-bottom: 8px; } a { text-decoration: none; }", "sandboxCSS": "", "codePrefix": "/* Visiere Anker-Elemente an, deren href mit \"https\" beginnt */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "a[href^=\"https\"] {\n color: green;\n text-decoration: underline;\n}", "validations": [ { "type": "regex", "value": "^a\\[href\\^=\"https\"\\]\\s*{", "message": "Verwende a[href^=\"https\"] { … } als deinen Attribut-Selektor, um HTTPS-Links anzuvisieren", "options": { "caseSensitive": true } }, { "type": "contains", "value": "color:", "message": "Füge die color-Eigenschaft hinzu, um die Textfarbe zu setzen" }, { "type": "property_value", "value": { "property": "color", "expected": "green" }, "message": "Setze die Textfarbe auf green" }, { "type": "contains", "value": "text-decoration:", "message": "Füge die text-decoration-Eigenschaft hinzu, um das Link-Erscheinungsbild zu stylen" }, { "type": "property_value", "value": { "property": "text-decoration", "expected": "underline" }, "message": "Setze text-decoration auf underline, um HTTPS-Links zu unterstreichen" }, { "type": "regex", "value": "a\\[href\\^=\"https\"\\]\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "child-combinator", "title": "Kind-Kombinator: Nur direkte Kinder", "description": "Der Kind-Kombinator (>) wählt Elemente aus, die direkte Kinder eines anderen Elements sind, keine Enkel oder tiefere Nachfahren. Dies ist entscheidend, wenn du verschachtelte Strukturen hast, bei denen du nur die äußere Ebene stylen möchtest. Zum Beispiel könntest du in einem Navigationsmenü mit Dropdowns möchten, dass Hauptmenüpunkte anders gestylt werden als Untermenüpunkte. Der Kind-Kombinator (>) gibt dir chirurgische Präzision – ul > li visiert nur direkte Listenelemente an, während ul li ALLE Listenelemente einschließlich verschachtelter anvisieren würde. Dies verhindert Stil-Vererbungschaos in komplexen Layouts.", "task": "Verwende den Kind-Kombinator, um nur die direkten li-Kinder von .main-nav anzuvisieren. Gib ihnen einen cornflowerblue-Hintergrund und white-Textfarbe. Beachte, wie die verschachtelten Untermenü-Elemente völlig ungestylt bleiben!", "previewHTML": "", "previewBaseCSS": "body { font-family: sans-serif; padding: 20px; background: #f5f5f5; } .main-nav { background: white; border-radius: 8px; padding: 0; margin: 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1); list-style: none; } .main-nav li { padding: 12px 16px; margin: 2px 0; cursor: pointer; transition: all 0.2s; } .main-nav ul { margin: 8px 0 0 20px; padding: 0; list-style: none; }", "sandboxCSS": "", "codePrefix": "/* Visiere nur die direkten li-Kinder von .main-nav an (nicht verschachtelte Untermenü-Elemente) */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".main-nav > li {\n background-color: cornflowerblue;\n color: white;\n}", "validations": [ { "type": "regex", "value": "^\\.main-nav\\s*>\\s*li\\s*{", "message": "Verwende .main-nav > li { … } mit dem Kind-Kombinator, um nur direkte Kinder anzuvisieren", "options": { "caseSensitive": true } }, { "type": "contains", "value": "background-color:", "message": "Füge die background-color-Eigenschaft hinzu, um Hauptmenüpunkte hervorzuheben" }, { "type": "property_value", "value": { "property": "background-color", "expected": "cornflowerblue" }, "message": "Setze background-color auf cornflowerblue für das Hauptmenü-Styling" }, { "type": "contains", "value": "color:", "message": "Füge die color-Eigenschaft hinzu, um die Textfarbe zu setzen" }, { "type": "property_value", "value": { "property": "color", "expected": "white" }, "message": "Setze die Textfarbe auf white für Kontrast gegen den blauen Hintergrund" }, { "type": "regex", "value": "\\.main-nav\\s*>\\s*li\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "descendant-combinator", "title": "Nachfahren-Kombinator: Alle verschachtelten Elemente", "description": "Der Nachfahren-Kombinator verwendet ein Leerzeichen zwischen Selektoren, um Elemente anzuvisieren, die irgendwo in anderen Elementen verschachtelt sind, unabhängig davon, wie tief verschachtelt sie sind. Zum Beispiel wählt nav a alle Anker-Elemente innerhalb von Navigations-Elementen aus, ob sie direkte Kinder oder mehrere Ebenen tief verschachtelt sind. Dies ist breiter als der Kind-Kombinator und nützlich für das Anwenden einheitlichen Stylings auf alle Elemente eines bestimmten Typs innerhalb eines Containers. Beim Stylen von Nachfahren kannst du Eigenschaften wie text-decoration verwenden, um das Link-Erscheinungsbild zu kontrollieren, und color, um einheitliche Textfarben in einem Abschnitt zu setzen. Der Nachfahren-Kombinator ist einer der am häufigsten verwendeten Kombinatoren in CSS.", "task": "Verwende den Nachfahren-Kombinator, um alle Anker-Elemente (a) innerhalb des nav-Elements anzuvisieren. Entferne ihre Unterstreichungen mit text-decoration: none und mache sie blue.", "previewHTML": "\n

Dieser Link außerhalb von nav sollte nicht betroffen sein.

", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } nav { border: 2px solid navy; padding: 15px; background-color: aliceblue; margin-bottom: 15px; } ul { list-style-type: none; padding-left: 20px; } li { margin-bottom: 5px; }", "sandboxCSS": "", "codePrefix": "/* Visiere alle Anker-Elemente innerhalb von nav mit dem Nachfahren-Kombinator an */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "nav a {\n text-decoration: none;\n color: blue;\n}", "validations": [ { "type": "regex", "value": "^nav\\s+a\\s*{", "message": "Verwende nav a mit einem Leerzeichen zwischen nav und a", "options": { "caseSensitive": true } }, { "type": "contains", "value": "text-decoration:", "message": "Füge die text-decoration-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "text-decoration", "expected": "none" }, "message": "Setze text-decoration auf none" }, { "type": "contains", "value": "color:", "message": "Füge die color-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "color", "expected": "blue" }, "message": "Setze color auf blue" }, { "type": "regex", "value": "nav\\s+a\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "adjacent-sibling-combinator", "title": "Benachbarter-Geschwister-Kombinator: Das nächste Element", "description": "Der benachbarte-Geschwister-Kombinator (+) wählt ein Element aus, das einem anderen Element auf derselben Ebene in der HTML-Struktur unmittelbar folgt. Beide Elemente müssen denselben Elternteil haben, und es dürfen keine anderen Elemente zwischen ihnen sein. Zum Beispiel wählt h1 + p Absatz-Elemente aus, die direkt nach h1-Überschriften kommen. Dieser Kombinator ist besonders nützlich für das Styling von Elementen, die besondere Beziehungen haben, wie der erste Absatz nach einer Überschrift oder Labels, die Formulareingaben folgen. Beim Stylen benachbarter Geschwister kannst du Eigenschaften wie margin-top verwenden, um Abstände anzupassen, und font-style, um Betonung wie Kursivschrift hinzuzufügen, um visuelle Hierarchie zu schaffen.", "task": "Verwende den benachbarten-Geschwister-Kombinator, um Absätze anzuvisieren, die unmittelbar auf h2-Überschriften folgen. Entferne ihren oberen Rand mit margin-top: 0 und mache sie kursiv.", "previewHTML": "

Erste Überschrift

\n

Dieser Absatz folgt direkt auf h2 (sollte betroffen sein).

\n

Dieser Absatz kommt nach einem anderen Absatz (sollte NICHT betroffen sein).

\n

Zweite Überschrift

\n

Dieser Absatz folgt auch direkt auf h2 (sollte betroffen sein).

\n
Dieses div kommt nach h2, ist aber kein Absatz.
\n

Dieser Absatz kommt nach einem div (sollte NICHT betroffen sein).

", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } h2, p, div { margin: 15px 0; padding: 8px; border: 1px dashed #ccc; }", "sandboxCSS": "", "codePrefix": "/* Visiere Absätze an, die unmittelbar auf h2-Überschriften folgen */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "h2 + p {\n margin-top: 0;\n font-style: italic;\n}", "validations": [ { "type": "regex", "value": "^h2\\s*\\+\\s*p\\s*{", "message": "Verwende h2 + p mit dem benachbarten-Geschwister-Kombinator (+)", "options": { "caseSensitive": true } }, { "type": "contains", "value": "margin-top:", "message": "Füge die margin-top-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "margin-top", "expected": "0" }, "message": "Setze margin-top auf 0" }, { "type": "contains", "value": "font-style:", "message": "Füge die font-style-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "font-style", "expected": "italic" }, "message": "Setze font-style auf italic" }, { "type": "regex", "value": "h2\\s*\\+\\s*p\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "general-sibling-combinator", "title": "Allgemeiner-Geschwister-Kombinator: Alle folgenden Geschwister", "description": "Der allgemeine-Geschwister-Kombinator (~) wählt alle Elemente aus, die einem anderen Element auf derselben Ebene folgen, nicht nur das unmittelbar benachbarte. Im Gegensatz zum benachbarten-Geschwister-Kombinator können andere Elemente zwischen den Zielelementen sein, solange sie alle denselben Elternteil haben und die ausgewählten Elemente nach dem Referenzelement kommen. Zum Beispiel wählt h2 ~ p alle Absatz-Elemente aus, die nach einer h2-Überschrift auf derselben Ebene erscheinen. Beim Stylen allgemeiner Geschwister kannst du Eigenschaften wie color verwenden, um die Textfarbe zu ändern, und padding-left, um visuelle Einrückung zu schaffen, was hilft, die Beziehung zwischen verwandten Inhaltsabschnitten zu zeigen.", "task": "Verwende den allgemeinen-Geschwister-Kombinator, um alle Absätze anzuvisieren, die nach der h3-Überschrift kommen (auf derselben Ebene). Gib ihnen eine gray-Farbe und 20px linkes Padding.", "previewHTML": "
\n

Dieser Absatz kommt vor h3 (sollte NICHT betroffen sein).

\n

Abschnittstitel

\n

Erster Absatz nach h3 (sollte betroffen sein).

\n
Etwas anderer Inhalt dazwischen
\n

Zweiter Absatz nach h3 (sollte auch betroffen sein).

\n Mehr Inhalt\n

Dritter Absatz nach h3 (sollte auch betroffen sein).

\n
", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } h3, p, div, span { margin: 10px 0; padding: 8px; border: 1px dashed #ccc; }", "sandboxCSS": "", "codePrefix": "/* Visiere alle Absätze an, die h3 folgen, mit dem allgemeinen-Geschwister-Kombinator */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "h3 ~ p {\n color: gray;\n padding-left: 20px;\n}", "validations": [ { "type": "regex", "value": "^h3\\s*~\\s*p\\s*{", "message": "Verwende h3 ~ p mit dem allgemeinen-Geschwister-Kombinator (~)", "options": { "caseSensitive": true } }, { "type": "contains", "value": "color:", "message": "Füge die color-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "color", "expected": "gray" }, "message": "Setze color auf gray" }, { "type": "contains", "value": "padding-left:", "message": "Füge die padding-left-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "padding-left", "expected": "20px" }, "message": "Setze padding-left auf 20px" }, { "type": "regex", "value": "h3\\s*~\\s*p\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "hover-pseudo-class", "title": "Die :hover Pseudo-Klasse", "description": "Die :hover Pseudo-Klasse wendet Stile an, wenn ein Benutzer mit der Maus über ein Element fährt. Dies schafft interaktives Feedback, das die Benutzererfahrung verbessert, indem es visuelle Hinweise über klickbare oder interaktive Elemente gibt. Hover-Effekte werden häufig bei Links, Buttons und anderen interaktiven Elementen verwendet, um ihre interaktive Natur anzuzeigen. Beim Erstellen von Hover-Effekten kannst du Eigenschaften wie background-color verwenden, um den Hintergrund beim Hover zu ändern, und color, um die Textfarbe zu ändern, was klares visuelles Feedback schafft. Die :hover Pseudo-Klasse gilt nur, während der Mauszeiger über dem Element positioniert ist, und kehrt zum normalen Zustand zurück, wenn der Zeiger sich entfernt.", "task": "Erstelle einen Hover-Effekt für das Button-Element. Beim Hover ändere den Hintergrund auf darkblue und die Textfarbe auf white.", "previewHTML": "

Interaktiver Button

\n

Fahre mit der Maus über den Button unten, um den Effekt zu sehen:

\n\n

Der Button sollte seine Farben ändern, wenn du mit der Maus darüber fährst.

", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } button { padding: 12px 24px; font-size: 16px; border: 2px solid darkblue; background-color: lightblue; color: darkblue; border-radius: 5px; cursor: pointer; }", "sandboxCSS": "", "codePrefix": "/* Erstelle einen Hover-Effekt für den Button */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "button:hover {\n background-color: darkblue;\n color: white;\n}", "validations": [ { "type": "regex", "value": "^button:hover\\s*{", "message": "Verwende button:hover, um Buttons beim Hover anzuvisieren", "options": { "caseSensitive": true } }, { "type": "contains", "value": "background-color:", "message": "Füge die background-color-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "background-color", "expected": "darkblue" }, "message": "Setze background-color auf darkblue" }, { "type": "contains", "value": "color:", "message": "Füge die color-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "color", "expected": "white" }, "message": "Setze color auf white" }, { "type": "regex", "value": "button:hover\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] }, { "id": "first-child-pseudo-class", "title": "Die :first-child Pseudo-Klasse", "description": "Die :first-child Pseudo-Klasse wählt Elemente aus, die das erste Kind ihres Elternelements sind. Dies ist nützlich für das Anwenden spezieller Stile auf das erste Element in Listen, den ersten Absatz in Artikeln oder das erste Element in einem beliebigen Container. Zum Beispiel wählt li:first-child das erste Listenelement in jeder Liste aus, während p:first-child Absätze auswählt, die das erste Kind-Element ihres Containers sind. Beim Stylen erster Kinder kannst du Eigenschaften wie font-weight verwenden, um das erste Element fett zu machen, und margin-top, um Abstände anzupassen, was hilft, visuelle Hierarchie zu schaffen und das Layout deines Inhalts zu verbessern.", "task": "Verwende die :first-child Pseudo-Klasse, um das erste Listenelement in jeder Liste anzuvisieren. Mache es bold und entferne seinen oberen Rand.", "previewHTML": "

Mehrere Listen

\n

Früchte

\n\n

Farben

\n", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } li { margin: 8px 0; padding: 5px; border: 1px solid #ddd; border-radius: 3px; }", "sandboxCSS": "", "codePrefix": "/* Visiere das erste Listenelement in jeder Liste an */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "li:first-child {\n font-weight: bold;\n margin-top: 0;\n}", "validations": [ { "type": "regex", "value": "^li:first-child\\s*{", "message": "Verwende li:first-child, um erste Listenelemente anzuvisieren", "options": { "caseSensitive": true } }, { "type": "contains", "value": "font-weight:", "message": "Füge die font-weight-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "font-weight", "expected": "bold" }, "message": "Setze font-weight auf bold" }, { "type": "contains", "value": "margin-top:", "message": "Füge die margin-top-Eigenschaft hinzu" }, { "type": "property_value", "value": { "property": "margin-top", "expected": "0" }, "message": "Setze margin-top auf 0" }, { "type": "regex", "value": "li:first-child\\s*{[^}]*}", "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", "options": { "caseSensitive": true } } ] } ] }