До всякого flexbox и grid страница уже как-то раскладывается: заголовки друг под другом, ссылки в строку. Это нормальный поток — раскладка по умолчанию, и управляет ею свойство display. Понимать поток нужно даже в мире современных раскладок: 90 % содержимого страницы живёт именно в нём.
Блочные и строчные
Два базовых поведения:
block(div,p,h1,section) — занимает всю доступную ширину, следующий элемент начинается с новой строки. Принимает width/height, все margin и padding.inline(span,a,strong) — течёт внутри строки текста, переносится по словам как текст. Width/height игнорируются, вертикальные margin не работают, вертикальный padding рисуется, но не расталкивает строки.
Промежуточный гибрид — inline-block: элемент стоит в строке, но внутри ведёт себя как блок — размеры и отступы работают полностью. До эпохи flexbox так строили горизонтальные меню; сегодня основное применение — мелкие «значки в тексте»: бейджи, счётчики, кнопки внутри абзаца.
Два подводных камня строчного мира. Первый: пробелы в разметке значимы — между соседними inline-block-элементами виден зазор в «одно пробельное место», который берётся из переноса строки в HTML (одна из причин, почему меню переехали на flex с его честным gap). Второй: картинка <img> — строчный элемент и выравнивается по базовой линии текста, отсюда загадочные 3-4 пикселя под ней; лечится display: block для картинки.
display может превратить кого угодно во что угодно: <a> в блок (кликабельная карточка целиком), <li> в строку. Семантика HTML при этом не меняется — только раскладка. Значения flex и grid из этого же свойства включают соответствующие раскладки для детей элемента — им посвящены отдельные статьи.
Спрятать элемент: три непохожих способа
.a { display: none; } /* элемента НЕТ: места не занимает, потомки скрыты */
.b { visibility: hidden; } /* элемент невидим, но МЕСТО ЗАНИМАЕТ */
.c { opacity: 0; } /* прозрачен, место занимает, ПО НЕМУ МОЖНО КЛИКНУТЬ */
Разница не косметическая:
display: noneвыключает элемент из раскладки полностью — соседи схлопываются на его место. Анимировать появление нельзя (свойство не анимируется).visibility: hiddenоставляет «дырку» нужного размера — вёрстка не дёргается. Любопытная деталь: потомок может «проявиться» обратно собственнымvisibility: visible.opacity: 0— элемент полностью интерактивен: получает клики и фокус. Невидимая кликабельная кнопка — готовая ловушка (и для пользователей, и для тестов); прозрачность сочетают сpointer-events: none.
Для доступности все три означают разное: display: none и visibility: hidden скрывают элемент и от скринридеров, opacity: 0 — нет. Скрыть только визуально, оставив скринридерам, — отдельный паттерн «visually-hidden» (класс из нескольких свойств, режущих размер до 1px).
float: что это было и зачем он сейчас
До flexbox колонки строили из плавающих элементов: float: left выдёргивает элемент из потока и прижимает влево, а следующий контент обтекает его. Колонки из float требовали ритуалов — распорок clear: both и «клирфиксов», потому что родитель переставал видеть высоту плавающих детей и схлопывался.
Знать это стоит по двум причинам. Первая — легаси: в старом проекте float: left у половины блоков означает «это досовременная раскладка», и чинить её точечно нужно осторожно (или мигрировать на flex целиком). Вторая — у float осталась одна легитимная работа, которую не делает больше никто: настоящее обтекание текстом.
.article img.illustration {
float: right;
margin: 0 0 8px 16px; /* текст обтекает картинку слева и снизу */
}
Flexbox и grid раскладывают коробки, но не умеют «пустить текст вокруг картинки» — это по-прежнему float (а форму обтекания может задать shape-outside). Родителя от схлопывания сегодня спасает уже знакомый display: flow-root — без клирфикс-хаков.
Коротко
- Нормальный поток: block — с новой строки на всю ширину; inline — течёт в тексте, размеры игнорирует; inline-block — в строке, но с размерами.
- Пробел между inline-block-элементами и зазор под картинкой — свойства строчного мира, а не баги.
- Скрытие:
display: none— нет в раскладке;visibility: hidden— дырка нужного размера;opacity: 0— невидим, но кликабелен (осторожно). - float — историческая раскладка; сегодня его единственная работа — обтекание картинок текстом. Схлопнувшегося родителя чинит
display: flow-root. display: flex/gridвключают современные раскладки для детей — о них следующие статьи.
Что почитать дальше
- Позиционирование — второй способ вырвать элемент из потока, уже управляемый.
- Flexbox — чем сегодня строят то, что раньше строили float'ами.
- Блочная модель — предыдущая тема цикла.