Files
code-crispies/lessons/pl/flexbox.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

136 lines
9.0 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"$schema": "../../schemas/code-crispies-module-schema.json",
"id": "flexbox",
"title": "CSS Flexbox",
"description": "Opanuj model elastycznego układu pudełkowego dla nowoczesnych responsywnych projektów",
"difficulty": "intermediate",
"lessons": [
{
"id": "flexbox-1",
"title": "Container",
"description": "Przed flexboxem nawet proste układy wymagały floatów, hacków pozycjonowania lub układów tabelarycznych. Flexbox (Flexible Box Layout) zrewolucjonizował CSS, dostarczając jednowymiarowy system układu zaprojektowany specjalnie do dystrybucji przestrzeni i wyrównywania zawartości.<br><br><strong>Jak to działa:</strong> Gdy ustawisz <kbd>display: flex</kbd> na elemencie, staje się on <em>kontenerem flex</em>. Jego bezpośrednie dzieci automatycznie stają się <em>elementami flex</em>, które płyną wzdłuż osi głównej (domyślnie poziomej). Ta jedna właściwość przekształca ułożone elementy blokowe w poziomy rząd.<br><br><strong>Dwie osie:</strong><br>• <em>Oś główna</em> Główny kierunek przepływu elementów (row = lewo→prawo)<br>• <em>Oś poprzeczna</em> Prostopadła do głównej (row = góra→dół)<br><br><pre>.nav {\n display: flex;\n}</pre>",
"task": "To menu nawigacyjne układa się pionowo. Dodaj <kbd>display: flex</kbd>, aby ułożyć linki poziomo.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">Products</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav>",
"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": "Która właściwość <kbd>display</kbd> tworzy kontener flex?"
}
]
},
{
"id": "flexbox-2",
"title": "Gap",
"description": "Właściwość <kbd>gap</kbd> dodaje równomierne odstępy między elementami flex bez potrzeby używania marginesów. Tworzy przestrzeń tylko między elementami, nie na krawędziach.",
"task": "Dodaj <kbd>gap: 1rem</kbd>, aby równomiernie rozmieścić linki nawigacyjne.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">Products</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav>",
"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": "Sprawdź właściwość <kbd>gap</kbd> — jaki odstęp potrzebują elementy?"
}
]
},
{
"id": "flexbox-3",
"title": "Justify Content",
"description": "<kbd>justify-content</kbd> rozmieszcza elementy wzdłuż osi głównej. Popularne wartości:<br>• <kbd>flex-start</kbd> pakuj elementy na początku<br>• <kbd>flex-end</kbd> pakuj na końcu<br>• <kbd>center</kbd> wyśrodkuj elementy<br>• <kbd>space-between</kbd> równa przestrzeń między elementami<br>• <kbd>space-around</kbd> równa przestrzeń wokół elementów",
"task": "Przesuń przycisk \"Login\" na prawą stronę, ustawiając <kbd>justify-content: space-between</kbd> na nawigacji.",
"previewHTML": "<nav class=\"nav\"><div class=\"links\"><a href=\"#\">Home</a><a href=\"#\">Products</a><a href=\"#\">About</a></div><a href=\"#\" class=\"login\">Login</a></nav>",
"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": "Która wartość <kbd>justify-content</kbd> rozdziela elementy na końce?"
}
]
},
{
"id": "flexbox-4",
"title": "Align Items",
"description": "<kbd>align-items</kbd> kontroluje wyrównanie na osi poprzecznej (pionowo gdy flex-direction to row). Wartości to:<br>• <kbd>stretch</kbd> rozciągnij do wypełnienia (domyślnie)<br>• <kbd>flex-start</kbd> wyrównaj do góry<br>• <kbd>flex-end</kbd> wyrównaj do dołu<br>• <kbd>center</kbd> wyśrodkuj pionowo",
"task": "Logo i linki nawigacyjne mają różne wysokości. Wyśrodkuj je pionowo za pomocą <kbd>align-items: center</kbd>.",
"previewHTML": "<header class=\"header\"><div class=\"logo\">ACME</div><nav><a href=\"#\">Products</a><a href=\"#\">Pricing</a><a href=\"#\">Docs</a></nav></header>",
"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": "Która właściwość kontroluje wyrównanie na osi poprzecznej?"
}
]
},
{
"id": "flexbox-5",
"title": "Flex Wrap",
"description": "Domyślnie elementy flex ściskają się w jednej linii. <kbd>flex-wrap: wrap</kbd> pozwala elementom przenosić się na kolejne linie, gdy zabraknie miejsca.",
"task": "Te karty wychodzą poza kontener. Dodaj <kbd>flex-wrap: wrap</kbd>, aby mogły przenosić się do nowych wierszy.",
"previewHTML": "<div class=\"cards\"><article class=\"card\">Card 1</article><article class=\"card\">Card 2</article><article class=\"card\">Card 3</article><article class=\"card\">Card 4</article><article class=\"card\">Card 5</article><article class=\"card\">Card 6</article></div>",
"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": "Sprawdź właściwość <kbd>flex-wrap</kbd> — jak pozwolić elementom przenosić się na nowe linie?"
}
]
},
{
"id": "flexbox-6",
"title": "Flex Grow",
"description": "Właściwość <kbd>flex</kbd> na elementach kontroluje ich rozrastanie i kurczenie się. <kbd>flex: 1</kbd> sprawia, że element rozrasta się, aby wypełnić dostępną przestrzeń. Wiele elementów z <kbd>flex: 1</kbd> dzieli przestrzeń równomiernie.",
"task": "Spraw, aby pole wyszukiwania rozszerzyło się i wypełniło dostępną przestrzeń, ustawiając <kbd>flex: 1</kbd> na <kbd>.search</kbd>.",
"previewHTML": "<div class=\"toolbar\"><input class=\"search\" type=\"text\" placeholder=\"Search...\"><button class=\"btn\">Search</button><button class=\"btn\">Filters</button></div>",
"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": "Sprawdź właściwość <kbd>flex</kbd> — jak sprawić, by element wypełnił dostępną przestrzeń?"
}
]
}
]
}