Шапка сайта с логотипом слева и кнопкой справа. Карточки товаров в ряд с равными отступами. Кнопка с иконкой и текстом по центру. Всё это решается одним инструментом — Flexbox. До его появления такие задачи требовали хаков с float или inline-block. Сегодня flexbox — стандарт вёрстки.
Flexbox работает на двух уровнях:
display: flex.nav {
display: flex; /* Всё — контейнер flex, дети стали flex-элементами */
}flex-direction: row; /* По умолчанию — горизонтально → */
flex-direction: row-reverse; /* Горизонтально ← */
flex-direction: column; /* Вертикально ↓ */
flex-direction: column-reverse; /* Вертикально ↑ */Main axis (главная ось) — направление flex-direction.
Cross axis (поперечная ось) — перпендикулярна main axis.
justify-content: flex-start; /* По умолчанию — к началу оси */
justify-content: flex-end; /* К концу оси */
justify-content: center; /* По центру */
justify-content: space-between; /* Первый у начала, последний у конца, остальные равномерно */
justify-content: space-around; /* Равные отступы с обеих сторон каждого элемента */
justify-content: space-evenly; /* Абсолютно равные промежутки */Пример из жизни: шапка сайта — логотип слева, меню справа:
.header {
display: flex;
justify-content: space-between;
align-items: center;
}align-items: stretch; /* По умолчанию — растянуть до высоты контейнера */
align-items: flex-start; /* К началу поперечной оси (верху при row) */
align-items: flex-end; /* К концу поперечной оси (низу при row) */
align-items: center; /* По центру поперечной оси */
align-items: baseline; /* По базовой линии текста */Вертикальное центрирование — мечта вёрстки до flexbox, теперь две строки:
.centered {
display: flex;
justify-content: center;
align-items: center;
}flex-wrap: nowrap; /* По умолчанию — всё в одну строку, сжимается */
flex-wrap: wrap; /* Переносит на новую строку, когда не помещается */
flex-wrap: wrap-reverse; /* Перенос в обратном направлении */gap: 16px; /* Одинаковый промежуток во всех направлениях */
gap: 8px 16px; /* Строки: 8px, столбцы: 16px */
row-gap: 8px; /* Только между строками */
column-gap: 16px; /* Только между столбцами */gap — современная замена margin на дочерних элементах. Намного удобнее.
Управляют тем, как элементы растут и сжимаются:
/* flex-grow: насколько элемент растёт относительно других */
.sidebar { flex-grow: 1; } /* Занимает 1 часть свободного места */
.main { flex-grow: 3; } /* Занимает 3 части свободного места */
/* flex-basis: начальный размер элемента */
.col { flex-basis: 200px; } /* Начинает с 200px, потом растёт/сжимается */
/* flex-shrink: насколько сжимается (по умолчанию 1) */
.logo { flex-shrink: 0; } /* Не сжимается при нехватке места */
/* Сокращённая запись flex: grow shrink basis */
.main { flex: 1 1 auto; } /* Растёт, сжимается, auto-размер */
.main { flex: 1; } /* = flex: 1 1 0 */Ошибка 1: Применять flex-свойства к контейнеру вместо детей
/* flex-grow/shrink/basis работают на детях, не на контейнере */
.container { flex-grow: 1; } /* Нет смысла, если .container не flex-item */
.container > .child { flex-grow: 1; } /* Правильно */Ошибка 2: Забыть display: flex у родителя
.parent { } /* Не flex! justify-content и align-items не работают */
.child { align-items: center; } /* Это тоже не поможет — это свойство родителя */
/* Правильно */
.parent { display: flex; align-items: center; }Flexbox — главный инструмент для строк компонентов: навигация, карточки в ряд, форма с лейблом и инпутом, кнопка с иконкой. Когда нужна двумерная сетка (строки И столбцы одновременно) — переходи на CSS Grid. Разделение: Flex = строки/столбцы отдельно, Grid = сетка.
Flexbox навигация и карточки с justify-content и align-items
const style = document.createElement('style')
style.textContent = `
* { box-sizing: border-box; }
body { font-family: Arial, sans-serif; padding: 16px; }
`
document.head.appendChild(style)
// === Шапка с flex: space-between ===
const header = document.createElement('header')
header.style.display = 'flex'
header.style.justifyContent = 'space-between'
header.style.alignItems = 'center'
header.style.padding = '12px 24px'
header.style.backgroundColor = '#1a202c'
header.style.borderRadius = '8px'
header.style.marginBottom = '16px'
document.body.appendChild(header)
const logo = document.createElement('span')
logo.textContent = 'RoadToJS'
logo.style.color = 'white'
logo.style.fontWeight = '700'
logo.style.fontSize = '18px'
header.appendChild(logo)
const nav = document.createElement('nav')
nav.style.display = 'flex'
nav.style.gap = '16px'
;['Уроки', 'Профиль', 'Выйти'].forEach(text => {
const a = document.createElement('a')
a.textContent = text
a.style.color = '#a0aec0'
a.style.textDecoration = 'none'
a.style.cursor = 'pointer'
nav.appendChild(a)
})
header.appendChild(nav)
// === Карточки с flex и gap ===
const grid = document.createElement('div')
grid.style.display = 'flex'
grid.style.gap = '12px'
grid.style.flexWrap = 'wrap'
document.body.appendChild(grid)
const courses = ['HTML', 'CSS', 'JavaScript', 'React']
courses.forEach(course => {
const card = document.createElement('div')
card.style.flex = '1 1 120px' // grow shrink basis
card.style.padding = '16px'
card.style.backgroundColor = '#ebf4ff'
card.style.borderRadius = '8px'
card.style.textAlign = 'center'
card.style.fontWeight = '600'
card.textContent = course
grid.appendChild(card)
})
// === Кнопка с иконкой по центру ===
const btn = document.createElement('button')
btn.style.display = 'flex'
btn.style.alignItems = 'center'
btn.style.gap = '8px'
btn.style.padding = '10px 20px'
btn.style.backgroundColor = '#7b2ff7'
btn.style.color = 'white'
btn.style.border = 'none'
btn.style.borderRadius = '6px'
btn.style.cursor = 'pointer'
btn.style.marginTop = '16px'
btn.innerHTML = '▶ Начать обучение'
document.body.appendChild(btn)
// Читаем стили
const headerStyle = window.getComputedStyle(header)
console.log('Хедер display:', headerStyle.display) // flex
console.log('Хедер justify-content:', headerStyle.justifyContent) // space-between
console.log('Хедер align-items:', headerStyle.alignItems) // center
const gridStyle = window.getComputedStyle(grid)
console.log('Карточки display:', gridStyle.display) // flex
console.log('Карточки gap:', gridStyle.gap) // 12px
console.log('Карточки flex-wrap:', gridStyle.flexWrap) // wrapШапка сайта с логотипом слева и кнопкой справа. Карточки товаров в ряд с равными отступами. Кнопка с иконкой и текстом по центру. Всё это решается одним инструментом — Flexbox. До его появления такие задачи требовали хаков с float или inline-block. Сегодня flexbox — стандарт вёрстки.
Flexbox работает на двух уровнях:
display: flex.nav {
display: flex; /* Всё — контейнер flex, дети стали flex-элементами */
}flex-direction: row; /* По умолчанию — горизонтально → */
flex-direction: row-reverse; /* Горизонтально ← */
flex-direction: column; /* Вертикально ↓ */
flex-direction: column-reverse; /* Вертикально ↑ */Main axis (главная ось) — направление flex-direction.
Cross axis (поперечная ось) — перпендикулярна main axis.
justify-content: flex-start; /* По умолчанию — к началу оси */
justify-content: flex-end; /* К концу оси */
justify-content: center; /* По центру */
justify-content: space-between; /* Первый у начала, последний у конца, остальные равномерно */
justify-content: space-around; /* Равные отступы с обеих сторон каждого элемента */
justify-content: space-evenly; /* Абсолютно равные промежутки */Пример из жизни: шапка сайта — логотип слева, меню справа:
.header {
display: flex;
justify-content: space-between;
align-items: center;
}align-items: stretch; /* По умолчанию — растянуть до высоты контейнера */
align-items: flex-start; /* К началу поперечной оси (верху при row) */
align-items: flex-end; /* К концу поперечной оси (низу при row) */
align-items: center; /* По центру поперечной оси */
align-items: baseline; /* По базовой линии текста */Вертикальное центрирование — мечта вёрстки до flexbox, теперь две строки:
.centered {
display: flex;
justify-content: center;
align-items: center;
}flex-wrap: nowrap; /* По умолчанию — всё в одну строку, сжимается */
flex-wrap: wrap; /* Переносит на новую строку, когда не помещается */
flex-wrap: wrap-reverse; /* Перенос в обратном направлении */gap: 16px; /* Одинаковый промежуток во всех направлениях */
gap: 8px 16px; /* Строки: 8px, столбцы: 16px */
row-gap: 8px; /* Только между строками */
column-gap: 16px; /* Только между столбцами */gap — современная замена margin на дочерних элементах. Намного удобнее.
Управляют тем, как элементы растут и сжимаются:
/* flex-grow: насколько элемент растёт относительно других */
.sidebar { flex-grow: 1; } /* Занимает 1 часть свободного места */
.main { flex-grow: 3; } /* Занимает 3 части свободного места */
/* flex-basis: начальный размер элемента */
.col { flex-basis: 200px; } /* Начинает с 200px, потом растёт/сжимается */
/* flex-shrink: насколько сжимается (по умолчанию 1) */
.logo { flex-shrink: 0; } /* Не сжимается при нехватке места */
/* Сокращённая запись flex: grow shrink basis */
.main { flex: 1 1 auto; } /* Растёт, сжимается, auto-размер */
.main { flex: 1; } /* = flex: 1 1 0 */Ошибка 1: Применять flex-свойства к контейнеру вместо детей
/* flex-grow/shrink/basis работают на детях, не на контейнере */
.container { flex-grow: 1; } /* Нет смысла, если .container не flex-item */
.container > .child { flex-grow: 1; } /* Правильно */Ошибка 2: Забыть display: flex у родителя
.parent { } /* Не flex! justify-content и align-items не работают */
.child { align-items: center; } /* Это тоже не поможет — это свойство родителя */
/* Правильно */
.parent { display: flex; align-items: center; }Flexbox — главный инструмент для строк компонентов: навигация, карточки в ряд, форма с лейблом и инпутом, кнопка с иконкой. Когда нужна двумерная сетка (строки И столбцы одновременно) — переходи на CSS Grid. Разделение: Flex = строки/столбцы отдельно, Grid = сетка.
Flexbox навигация и карточки с justify-content и align-items
const style = document.createElement('style')
style.textContent = `
* { box-sizing: border-box; }
body { font-family: Arial, sans-serif; padding: 16px; }
`
document.head.appendChild(style)
// === Шапка с flex: space-between ===
const header = document.createElement('header')
header.style.display = 'flex'
header.style.justifyContent = 'space-between'
header.style.alignItems = 'center'
header.style.padding = '12px 24px'
header.style.backgroundColor = '#1a202c'
header.style.borderRadius = '8px'
header.style.marginBottom = '16px'
document.body.appendChild(header)
const logo = document.createElement('span')
logo.textContent = 'RoadToJS'
logo.style.color = 'white'
logo.style.fontWeight = '700'
logo.style.fontSize = '18px'
header.appendChild(logo)
const nav = document.createElement('nav')
nav.style.display = 'flex'
nav.style.gap = '16px'
;['Уроки', 'Профиль', 'Выйти'].forEach(text => {
const a = document.createElement('a')
a.textContent = text
a.style.color = '#a0aec0'
a.style.textDecoration = 'none'
a.style.cursor = 'pointer'
nav.appendChild(a)
})
header.appendChild(nav)
// === Карточки с flex и gap ===
const grid = document.createElement('div')
grid.style.display = 'flex'
grid.style.gap = '12px'
grid.style.flexWrap = 'wrap'
document.body.appendChild(grid)
const courses = ['HTML', 'CSS', 'JavaScript', 'React']
courses.forEach(course => {
const card = document.createElement('div')
card.style.flex = '1 1 120px' // grow shrink basis
card.style.padding = '16px'
card.style.backgroundColor = '#ebf4ff'
card.style.borderRadius = '8px'
card.style.textAlign = 'center'
card.style.fontWeight = '600'
card.textContent = course
grid.appendChild(card)
})
// === Кнопка с иконкой по центру ===
const btn = document.createElement('button')
btn.style.display = 'flex'
btn.style.alignItems = 'center'
btn.style.gap = '8px'
btn.style.padding = '10px 20px'
btn.style.backgroundColor = '#7b2ff7'
btn.style.color = 'white'
btn.style.border = 'none'
btn.style.borderRadius = '6px'
btn.style.cursor = 'pointer'
btn.style.marginTop = '16px'
btn.innerHTML = '▶ Начать обучение'
document.body.appendChild(btn)
// Читаем стили
const headerStyle = window.getComputedStyle(header)
console.log('Хедер display:', headerStyle.display) // flex
console.log('Хедер justify-content:', headerStyle.justifyContent) // space-between
console.log('Хедер align-items:', headerStyle.alignItems) // center
const gridStyle = window.getComputedStyle(grid)
console.log('Карточки display:', gridStyle.display) // flex
console.log('Карточки gap:', gridStyle.gap) // 12px
console.log('Карточки flex-wrap:', gridStyle.flexWrap) // wrapСоздай flex-контейнер с тремя карточками. Задай контейнеру `display: flex`, `justify-content: space-between`, `align-items: center` и `gap: 16px`. Каждой карточке задай `flex: 1`, `padding: 16px`, светло-синий фон и скруглённые углы.
`display: flex` активирует Flexbox. `justify-content: space-between` распределяет карточки по ширине. `align-items: center` выравнивает по вертикали. `flex: 1` у карточек означает, что каждая занимает равную долю пространства.