{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "flexbox", "title": "CSS Flexbox", "description": "Опануйте модель гнучкого блочного макету для сучасних адаптивних дизайнів", "difficulty": "intermediate", "lessons": [ { "id": "flexbox-1", "title": "Container", "description": "До flexbox навіть прості макети вимагали floats, хаків позиціонування або табличних макетів. Flexbox (Flexible Box Layout) революціонізував CSS, надавши одновимірну систему макетування, спеціально розроблену для розподілу простору та вирівнювання вмісту.

Як це працює: Коли ви встановлюєте display: flex на елемент, він стає flex-контейнером. Його прямі нащадки автоматично стають flex-елементами, що розташовуються вздовж головної осі (горизонтально за замовчуванням). Ця одна властивість перетворює вкладені блокові елементи в горизонтальний ряд.

Дві осі:
Головна вісь – Основний напрямок потоку елементів (row = зліва→направо)
Поперечна вісь – Перпендикулярна до головної (row = зверху→вниз)

.nav {\n  display: flex;\n}
", "task": "Це навігаційне меню розташовується вертикально. Додайте display: flex, щоб розташувати посилання горизонтально.", "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": "Встановіть display: flex" } ] }, { "id": "flexbox-2", "title": "Gap", "description": "Властивість gap додає послідовний відступ між flex-елементами без потреби у відступах (margins). Вона створює простір лише між елементами, а не по краях.", "task": "Додайте gap: 1rem, щоб рівномірно розташувати навігаційні посилання.", "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": "Встановіть gap: 1rem" } ] }, { "id": "flexbox-3", "title": "Justify Content", "description": "justify-content розподіляє елементи вздовж головної осі. Поширені значення:
flex-start – групувати на початку
flex-end – групувати в кінці
center – центрувати елементи
space-between – рівний простір між елементами
space-around – рівний простір навколо елементів", "task": "Перемістіть кнопку \"Login\" праворуч, встановивши justify-content: space-between на навігації.", "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": "Встановіть justify-content: space-between" } ] }, { "id": "flexbox-4", "title": "Align Items", "description": "align-items керує вирівнюванням по поперечній осі (вертикально, коли flex-direction це row). Значення включають:
stretch – розтягнути для заповнення (за замовчуванням)
flex-start – вирівняти вгору
flex-end – вирівняти вниз
center – центрувати вертикально", "task": "Логотип та навігаційні посилання мають різну висоту. Відцентруйте їх вертикально за допомогою 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": "Встановіть align-items: center" } ] }, { "id": "flexbox-5", "title": "Flex Wrap", "description": "За замовчуванням flex-елементи стискаються в один рядок. flex-wrap: wrap дозволяє елементам переходити на кілька рядків, коли місця недостатньо.", "task": "Ці картки виходять за межі контейнера. Додайте flex-wrap: wrap, щоб дозволити їм переходити на нові рядки.", "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": "Встановіть flex-wrap: wrap" } ] }, { "id": "flexbox-6", "title": "Flex Grow", "description": "Властивість flex на елементах керує тим, як вони ростуть і зменшуються. flex: 1 змушує елемент рости, щоб заповнити доступний простір. Кілька елементів з flex: 1 ділять простір порівну.", "task": "Зробіть так, щоб поле пошуку розширилось і заповнило доступний простір, встановивши flex: 1 на .search.", "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": "Встановіть flex: 1" } ] } ] }