← назад к разделу

До всякого 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'ами.
  • Блочная модель — предыдущая тема цикла.