{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "flexbox", "title": "CSS Flexbox", "description": "Beherrsche das flexible Box-Layout-Modell für moderne responsive Designs", "difficulty": "intermediate", "lessons": [ { "id": "flexbox-1", "title": "Container", "description": "Vor Flexbox erforderten selbst einfache Layouts Floats, Positionierungs-Hacks oder tabellenbasierte Layouts. Flexbox (Flexible Box Layout) revolutionierte CSS, indem es ein eindimensionales Layout-System speziell für Platzverteilung und Inhaltsausrichtung bereitstellte.

So funktioniert es: Wenn du display: flex auf ein Element setzt, wird es zum Flex-Container. Seine direkten Kinder werden automatisch zu Flex-Items, die entlang einer Hauptachse fließen (standardmäßig horizontal). Diese eine Eigenschaft verwandelt gestapelte Block-Elemente in eine horizontale Reihe.

Die zwei Achsen:
Hauptachse – Die primäre Richtung, in der Items fließen (row = links→rechts)
Querachse – Senkrecht zur Hauptachse (row = oben→unten)

.nav {\n  display: flex;\n}
", "task": "Dieses Navigationsmenü stapelt sich vertikal. Füge display: flex hinzu, um die Links horizontal anzuordnen.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; } .nav a:hover { background: rgba(255,255,255,0.1); }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "display: flex;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "display", "expected": "flex" }, "message": "Setze display: flex" } ] }, { "id": "flexbox-2", "title": "Gap", "description": "Die gap-Eigenschaft fügt konsistenten Abstand zwischen Flex-Items hinzu, ohne dass Margins nötig sind. Sie erzeugt nur Platz zwischen Items, nicht an den Rändern.", "task": "Füge gap: 1rem hinzu, um die Navigationslinks gleichmäßig zu verteilen.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; display: flex; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; background: rgba(255,255,255,0.1); }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "gap: 1rem;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "gap", "expected": "1rem" }, "message": "Setze gap: 1rem" } ] }, { "id": "flexbox-3", "title": "Justify Content", "description": "justify-content verteilt Items entlang der Hauptachse. Häufige Werte:
flex-start – Items am Anfang
flex-end – Items am Ende
center – Items zentrieren
space-between – Gleicher Abstand zwischen Items
space-around – Gleicher Abstand um Items", "task": "Schiebe den \"Login\"-Button nach rechts, indem du justify-content: space-between auf die Navigation setzt.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; display: flex; } .links { display: flex; gap: 8px; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; } .nav a:hover { background: rgba(255,255,255,0.1); } .login { background: steelblue; }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "justify-content: space-between;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "justify-content", "expected": "space-between" }, "message": "Setze justify-content: space-between" } ] }, { "id": "flexbox-4", "title": "Align Items", "description": "align-items steuert die Ausrichtung auf der Querachse (vertikal bei flex-direction: row). Werte sind:
stretch – Ausdehnen zum Füllen (Standard)
flex-start – Oben ausrichten
flex-end – Unten ausrichten
center – Vertikal zentrieren", "task": "Das Logo und die Nav-Links haben unterschiedliche Höhen. Zentriere sie vertikal mit align-items: center.", "previewHTML": "
ACME
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .header { background: white; padding: 1rem 2rem; display: flex; justify-content: space-between; border-bottom: 1px solid #eee; } .logo { font-size: 1.5rem; font-weight: bold; color: steelblue; } nav { display: flex; gap: 1rem; } nav a { color: #333; text-decoration: none; font-size: 0.9rem; }", "sandboxCSS": "", "codePrefix": ".header {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "align-items: center;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "align-items", "expected": "center" }, "message": "Setze align-items: center" } ] }, { "id": "flexbox-5", "title": "Flex Wrap", "description": "Standardmäßig quetschen sich Flex-Items in eine Zeile. flex-wrap: wrap erlaubt Items, auf mehrere Zeilen umzubrechen, wenn der Platz nicht reicht.", "task": "Diese Karten laufen über den Container hinaus. Füge flex-wrap: wrap hinzu, damit sie in neue Zeilen umbrechen können.", "previewHTML": "
Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .cards { display: flex; gap: 1rem; } .card { background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); min-width: 120px; text-align: center; }", "sandboxCSS": "", "codePrefix": ".cards {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "flex-wrap: wrap;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "flex-wrap", "expected": "wrap" }, "message": "Setze flex-wrap: wrap" } ] }, { "id": "flexbox-6", "title": "Flex Grow", "description": "Die flex-Eigenschaft auf Items steuert, wie sie wachsen und schrumpfen. flex: 1 lässt ein Item wachsen, um verfügbaren Platz zu füllen. Mehrere Items mit flex: 1 teilen sich den Platz gleichmäßig.", "task": "Lass das Suchfeld den verfügbaren Platz ausfüllen, indem du flex: 1 auf .search setzt.", "previewHTML": "
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .toolbar { display: flex; gap: 8px; padding: 1rem; background: #f5f5f5; border-radius: 8px; } .search { padding: 8px 1rem; border: 1px solid #ddd; border-radius: 4px; font-size: 1rem; } .btn { padding: 8px 1rem; background: steelblue; color: white; border: none; border-radius: 4px; cursor: pointer; }", "sandboxCSS": "", "codePrefix": ".search {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "flex: 1;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "flex", "expected": "1" }, "message": "Setze flex: 1" } ] } ] }