Flex и Grid
Вопрос
Когда берут Flexbox, а когда Grid, и почему флекс-элемент не сжимается как ожидалось?
Короткий ответ
Flex — одномерная раскладка вдоль одной оси: ряд кнопок, шапка, центрирование, «прижать футер». Grid — двумерная: и колонки, и ряды задаются вместе, карточки, формы, страничный каркас.
У флекса главная ось задаётся flex-direction, поперечная — перпендикулярна ей. justify-content выравнивает по главной, align-items по поперечной.
Сокращение flex: 1 означает 1 1 0%: элементу можно расти и сжиматься, базовая доля нулевая. min-width: auto у флекс-элемента не даёт сжаться меньше минимального контента. Длинная строка или картинка поэтому выталкивает колонку. Лечится min-width: 0 на том элементе, которому разрешено сжаться.
Разбор
gap работает и во flex, и в grid. Отступы через margin у детей хуже: крайние элементы получают лишний внешний отступ, если не обнулять его отдельно.
В grid grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)) даёт переносящиеся карточки без медиазапроса. auto-fit схлопывает пустые треки, auto-fill оставляет их. Для страницы с сайдбаром удобен grid-template-columns: 16rem 1fr.
fr делит свободное место после фиксированных и auto треков. Абсолютные единицы вперемешку с fr нормальны: сайдбар в rem, контент в 1fr.
На что смотрят на senior
Container queries рядом с grid: компонент сам решает число колонок от ширины своего контейнера. Медиазапрос остаётся для вещей уровня страницы: показ сайдбара, размер шрифта документа.
Subgrid выравнивает внутренняя сетка по трекам родителя, например подписи полей в карточке, которая сама лежит в общей сетке. Поддержка уже достаточная для нового кода, на старом проекте это стоит проверить.
Доступность раскладки: order во flex меняет визуальный порядок и может разъехаться с порядком фокуса. Если порядок для клавиатуры важен, лучше переставить DOM.
Типичные ошибки
- Строить всю страницу только флексами, вкладывая ряд в ряд, хотя это одна сетка.
- Забывать
min-width: 0и искать «баг грида» в тексте, который не переносится. - Центрировать через
positionи отрицательные margin там, где хватаетmargin-inline: autoили gridplace-items: center.
Задача
Колонка во flex-ряду не сжимается, длинная строка без пробелов выталкивает соседа. Какое одно свойство на этой колонке обычно возвращает сжатие?
Показать ответ
min-width: 0 на самой колонке. У flex-элемента минимальная ширина по умолчанию auto, она не даёт стать уже контента.
Дальше строке нужен перенос или overflow, иначе текст всё равно не поместится, но колонка уже сможет занять долю ряда.