{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "box-model", "title": "CSS Box Model", "description": "Opanuj podstawowe zasady zarządzania przestrzenią w projektowaniu stron poprzez model pudełkowy CSS. Ten moduł bada, jak treść, padding, ramki i marginesy łączą się, tworząc struktury układu.", "difficulty": "beginner", "lessons": [ { "id": "box-model-1", "title": "Padding", "description": "Każdy element w CSS to pudełko z czterema warstwami: treść, padding, ramka i margines. Padding tworzy przestrzeń między treścią a krawędzią pudełka.

Bez paddingu tekst przylega niezręcznie do ramek. Padding sprawia, że treść jest czytelna i wizualnie zbalansowana.

.card {\n  padding: 1rem;\n}
", "task": "Tekst wewnątrz tej karty profilu jest przyciśnięty do krawędzi. Daj mu trochę wewnętrznej przestrzeni do oddychania.", "previewHTML": "

Sarah Chen

Frontend Developer

", "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": "Która właściwość dodaje przestrzeń między treścią a krawędzią elementu?" } ] }, { "id": "box-model-2", "title": "Borders", "description": "Ramki tworzą wizualne granice wokół elementów. Skrót border przyjmuje trzy wartości: szerokość, styl i kolor.

Popularne style: solid, dashed, dotted, none", "task": "Ta karta mogłaby mieć kolorową linię akcentową wzdłuż lewej krawędzi.", "previewHTML": "

Sarah Chen

Frontend Developer

", "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": "Użyj skrótu, który ustawia ramkę tylko po jednej stronie", "options": { "caseSensitive": false } } ] }, { "id": "box-model-3", "title": "Margins", "description": "Marginesy tworzą przestrzeń na zewnątrz elementu, oddzielając go od sąsiadów. Podczas gdy padding przesuwa treść do wewnątrz, marginesy odpychają inne elementy.", "task": "Te dwie karty profilu stykają się ze sobą. Dodaj trochę przestrzeni pod każdą kartą, aby je rozdzielić.", "previewHTML": "

Sarah Chen

Frontend Developer

Alex Rivera

UX Designer

", "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": "Która właściwość odpycha sąsiednie elementy w dół?" } ] }, { "id": "box-model-4", "title": "Box Sizing", "description": "Domyślnie width ustawia tylko szerokość treści. Padding i ramki są dodawane. To powoduje problemy z układem.

box-sizing: border-box włącza padding i ramkę do szerokości, czyniąc rozmiary przewidywalnymi. Większość programistów stosuje to do wszystkich elementów.", "task": "Obie karty mają tę samą szerokość, ale lewa wychodzi poza, bo padding i ramka są dodawane na wierzch. Napraw prawą kartę, aby jej rozmiar obejmował padding i ramkę.", "previewHTML": "
Content-box
Border-box
", "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": "Który tryb rozmiaru uwzględnia padding i ramkę w szerokości elementu?" } ] }, { "id": "box-model-5", "title": "Padding Shorthand", "description": "Padding przyjmuje 1-4 wartości:
• 1 wartość: wszystkie strony
• 2 wartości: pionowo | poziomo
• 4 wartości: góra | prawo | dół | lewo", "task": "Ten przycisk jest zbyt ciasny. Daj mu więcej przestrzeni po bokach niż na górze i dole, używając skrótu dwuwartościowego.", "previewHTML": "", "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": "Użyj skrótu dwuwartościowego: najpierw pionowo, potem poziomo", "options": { "caseSensitive": false } } ] }, { "id": "box-model-6", "title": "Margin Shorthand", "description": "Margines używa tego samego wzorca skrótu co padding. Typowym wzorcem jest poziome centrowanie elementów blokowych za pomocą margin: 0 auto.", "task": "Ta karta jest przyklejona do lewej. Wycentruj ją poziomo, używając skrótu marginesu z automatycznymi marginesami bocznymi.", "previewHTML": "

Sarah Chen

Frontend Developer

", "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": "Użyj skrótu, który automatycznie oblicza równe marginesy poziome", "options": { "caseSensitive": false } } ] }, { "id": "box-model-7", "title": "Border Radius", "description": "Chociaż nie jest częścią klasycznego modelu pudełkowego, border-radius zaokrągla rogi ramki elementu. Użyj 50% na kwadratowym elemencie, aby utworzyć koło.", "task": "Kwadratowy obrazek awatara powinien wyglądać jak idealne koło.", "previewHTML": "
\"Avatar\"

Sarah Chen

Frontend Developer

", "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": "Która właściwość zaokrągla rogi? Pomyśl, jaki procent tworzy koło" } ] }, { "id": "box-model-8", "title": "Complete Card", "description": "Połączmy wszystko razem. Ta karta powiadomienia potrzebuje stylowania, żeby wyglądać profesjonalnie.", "task": "To powiadomienie potrzebuje trzech rzeczy: wewnętrznej przestrzeni, żeby tekst nie był ściśnięty, kolorowego akcentu na lewej krawędzi i lekko zaokrąglonych rogów.", "previewHTML": "
New message

You have 3 unread notifications

", "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": "Dodaj wewnętrzny odstęp do powiadomienia" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", "message": "Dodaj kolorowy akcent na lewej krawędzi", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, "message": "Wygładź rogi powiadomienia" } ] } ] }