Как изменяется поведение margin у элементов внутри flex-контейнера в CSS?
Что проверяют
Знаете ли вы, чем margin во флексе отличается от обычного блочного потока, и умеете ли пользоваться margin: auto как инструментом выравнивания. Следом часто просят сверстать шапку, где логотип слева, а кнопка входа прижата вправо.
Как отвечать
Главные отличия:
- схлопывания нет: вертикальные margin соседних блоков в обычном потоке схлопываются, а у флекс-элементов всегда складываются.
margin-right: 10pxу одного иmargin-left: 10pxу соседа дают 20px, вflex-direction: columnтоже; - auto забирает свободное место: на главной оси
margin: autoсъедает свободное пространство раньше, чем его распределитjustify-content. Поэтомуmargin-left: auto(лучшеmargin-inline-start: auto) у последнего пункта меню прижимает его к правому краю, аjustify-contentв этом измерении перестаёт действовать; - поперечная ось: auto margin перебивает
align-selfиalign-items. Единственный элемент сmargin: autoв контейнере с заданной высотой встаёт ровно по центру по обеим осям; - margin входит во внешний размер: алгоритм считает свободное место за вычетом margin, поэтому три элемента по
width: 33.33%с отступами не поместятся и начнут сжиматься черезflex-shrink; - проценты: процентный margin, в том числе вертикальный, считается от ширины (inline-размера) контейнера, как и в блочной модели.
Для равных промежутков сегодня берут gap: его поддерживают во флексе все актуальные браузеры, и он не добавляет отступ по краям.
Полезная деталь: центрирование через auto margin «безопасное». Если элемент больше контейнера, auto margin обнуляется и элемент вылезает только в конец, а align-items: center может вытолкнуть его начало за край, откуда скроллом уже не достать.
Где спотыкаются
Говорят, что margin во флексе схлопываются. Это правило блочного потока, во flex и grid его нет.
Путают оси: в flex-direction: column главная ось вертикальная, и margin-top: auto прижимает элемент к низу, что удобно для футера карточки.
Пытаются сдвинуть элемент через justify-self. Во флексе это свойство игнорируется, для одиночного элемента на главной оси работает только auto margin.