</> Praktum

Главная / CSS / CSS display

Урок · CSS

display: как элемент встаёт на страницу

Редакция PraktumОбновлено 17 минут на урок с практикойУровень: новичок

Свойство display решает две вещи: как сам элемент ведёт себя среди соседей (встаёт отдельной строкой или живёт внутри текста) и по каким правилам раскладываются его дети (обычный поток, flex или grid). Значение none полностью убирает элемент со страницы.

Коротко
  • block начинает новую строку и растягивается на всю доступную ширину.
  • inline живёт внутри текста: width, height и вертикальные margin на него не действуют.
  • inline-block стоит в строке, но принимает размеры и отступы как блок.
  • flex и grid меняют раскладку детей, а не самого элемента.
  • display: none убирает элемент из раскладки и от скринридеров.

Зачем этот урок сейчас

Почти каждая «странность» вёрстки начинается с display: ширина ссылки не меняется, отступ сверху у span не работает, justify-content ничего не делает. Во всех трёх случаях у элемента не то значение display, которое ты ожидал. Разберёшься с ним — дальше Flexbox, Grid и адаптивная вёрстка пойдут без сюрпризов.

Минимальный пример

Три элемента с тремя разными значениями. Вставь код в песочницу и сравни, как они встают.

<p class="note">Абзац — блок, занимает строку целиком.</p>
<a class="tag" href="/css/">CSS</a>
<a class="tag" href="/html/">HTML</a>
.note { display: block; background: #eef2ff; }
.tag { display: inline-block; padding: 4px 10px; border-radius: 999px; background: #e0e7ff; }

Абзац растянулся во всю ширину. Ссылки остались в одной строке, но приняли внутренние отступы и скругление: у inline-block это работает, у обычного inline вертикальный padding вылез бы за строку и наехал на соседей.

Основные значения display

Что делает каждое значение
ЗначениеСам элементДетиПример
blockНовая строка, ширина на весь контейнерОбычный потокdiv, p, section
inlineВнутри текста, ширина по содержимомуОбычный потокspan, a, strong
inline-blockВ строке, но с размерами блокаОбычный потоккнопки-ссылки, теги
flexКак блокFlexbox: ряд или колонкаменю, шапка
inline-flexКак inline-blockFlexboxкнопка с иконкой
gridКак блокСетка строк и колоноккаталог карточек
inline-gridКак inline-blockСеткаредко, мини-виджеты
flow-rootКак блокНовый контекст форматированияродитель с float внутри
contentsСобственной рамки нетДети встают на его местообёртка внутри grid
noneНе отображаетсяНе отображаютсяскрытое меню

В спецификации display описан двумя словами: внешнее поведение и внутреннее. display: flex — то же самое, что display: block flex, а inline-flex — inline flex. Двухсловная запись работает в современных браузерах, но в учебных проектах привычнее однословная.

Чем block отличается от inline

Блочный элемент начинает новую строку, принимает width, height и все четыре отступа. Если ширину не задать, он растягивается на всю ширину родителя.

Строчный элемент — часть текста. Его ширина равна ширине содержимого, а width и height игнорируются. Горизонтальные margin и padding раздвигают соседей, вертикальные — рисуются, но строку не сдвигают: фон padding наедет на строку выше.

/* не сработает: span остаётся строчным */
.price { width: 120px; margin-top: 20px; }

/* сработает */
.price { display: inline-block; width: 120px; margin-top: 20px; }

Исключение — заменяемые элементы вроде img и input: они строчные, но размеры принимают, потому что у них есть собственные габариты.

Когда нужен inline-block

inline-block — компромисс: элемент стоит в строке рядом с текстом, но ведёт себя как маленький блок. Подходит для ссылок-кнопок, меток и бейджей внутри абзаца.

У inline-block есть известная ловушка: между элементами появляется зазор шириной в пробел. Это обычный пробел или перенос строки из HTML. Для ряда кнопок удобнее display: flex на родителе с gap — зазор будет точным.

flex и grid меняют детей

Значения flex и grid включают новую раскладку для прямых детей элемента. Сам контейнер при этом остаётся блоком. Поэтому justify-content или gap на обычном блоке ничего не делают: эти свойства работают только внутри flex- или grid-контейнера.

.menu  { display: flex; flex-wrap: wrap; gap: 16px; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }

Подробно — в уроках Flexbox и CSS Grid.

Как спрятать элемент: display, visibility, hidden, opacity

Способы скрыть элемент
СпособМесто в раскладкеСкринридерКлик и Tab
display: noneИсчезаетНе читаетНет
атрибут hiddenИсчезаетНе читаетНет
visibility: hiddenОстаётся пустое местоНе читаетНет
opacity: 0ОстаётсяЧитаетДа — ловушка

Атрибут hidden в HTML работает как display: none, но говорит о смысле: «сейчас этот блок не нужен». Если в CSS задать элементу свой display, атрибут hidden перестанет его прятать — стили победят. Помогает правило [hidden] { display: none !important; }.

Для текста, который нужен только скринридеру (например, подпись у кнопки-иконки), display: none не подходит — используют визуально скрытый класс с clip и размером 1px.

flow-root и contents

display: flow-root создаёт новый контекст блочного форматирования. На практике это лечит две старые проблемы: родитель перестаёт «схлопываться», если внутри только float, и margin первого ребёнка перестаёт вытекать наружу через родителя.

.media { display: flow-root; } /* родитель обнимает плавающую картинку */
.media img { float: left; margin-right: 16px; }

display: contents убирает рамку самого элемента: его дети ведут себя так, будто обёртки нет. Это удобно внутри grid, когда лишний div мешает детям встать в сетку. Осторожно с семантическими элементами: на кнопках, списках и таблицах display: contents в старых версиях браузеров ломал доступность.

Значения по умолчанию и семантика

У каждого HTML-элемента есть display по умолчанию из стилей браузера: div, p, h1–h6, section — block; span, a, em — inline; li — list-item; table — table. CSS меняет только внешний вид. Ссылка с display: block остаётся ссылкой, а div с display: inline не становится частью текста по смыслу.

Поэтому выбирай тег по смыслу, а display — по виду. Не делай кнопку из span с display: inline-block: у неё не будет фокуса и реакции на Enter.

Как проверить display в DevTools

Открой DevTools (F12), выбери элемент и перейди во вкладку Computed. Найди строку display: там итоговое значение после всех правил. Рядом с flex- и grid-контейнерами в панели Elements есть метка flex или grid — клик по ней рисует поверх страницы оси и ячейки.

block или inline-block

block

Отдельная строка, ширина на весь контейнер. Для разделов, карточек, абзацев.

inline-block

Стоит в строке рядом с текстом, ширина по содержимому, но принимает размеры. Для меток и ссылок-кнопок.

Частые ошибки

  • Задают width или margin-top обычному span и a — без inline-block или block не сработает.
  • Пишут justify-content и gap элементу без display: flex или grid.
  • Ставят flex на ребёнка, хотя раскладку детей включают на родителе.
  • Прячут важный текст через opacity: 0: его по-прежнему можно нажать и прочитать скринридером.
  • Задают элементу свой display и удивляются, что атрибут hidden больше не скрывает его.

Доступность

display не меняет смысл элемента, поэтому сначала выбирай правильный тег. display: none и hidden прячут блок и от скринридеров — используй их для того, что сейчас действительно не нужно (закрытое меню, неактивная вкладка). Если элемент скрыт визуально, но должен читаться, применяй визуально скрытый класс. Следи, чтобы порядок в HTML совпадал с порядком на экране: flex и grid умеют переставлять блоки, а клавиатура идёт по HTML.

Поддержка браузерами

Значения block, inline, inline-block, none, flex и grid работают во всех актуальных браузерах. flow-root и contents тоже поддерживаются современными браузерами; двухсловная запись вида display: inline flex появилась позже и работает в свежих версиях. Конкретное значение сверяй на Can I use.

Практика

Сделай строку тегов под заголовком статьи: три ссылки с фоном, скруглением и внутренним отступом 4px 10px. Затем ниже — меню из четырёх ссылок в ряд с промежутком 20px, которое переносится на узком экране. Спрячь пятый пункт меню так, чтобы его не было ни видно, ни слышно скринридеру.

Показать решение
.tags a {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: #e0e7ff;
}
.menu {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.menu .extra {
  display: none; /* или атрибут hidden в HTML */
}

Открыть песочницу

Частые вопросы

Почему width не работает у span?

span по умолчанию строчный (inline), а строчные элементы берут ширину по содержимому. Задай display: inline-block или block, и width начнёт работать.

Чем display: none отличается от visibility: hidden?

display: none убирает элемент вместе с его местом — соседи сдвигаются. visibility: hidden прячет элемент, но оставляет пустое место такого же размера. Оба способа скрывают элемент от скринридера.

Почему не работает justify-content?

Это свойство flex- и grid-контейнера. Проверь, что у родителя стоит display: flex или grid и что ты выравниваешь именно его прямых детей.

Что выбрать для ряда кнопок: inline-block или flex?

Flex на родителе с gap. У inline-block между кнопками появляется зазор от пробела в HTML, а выравнивание по высоте сложнее.

Меняет ли display смысл тега?

Нет. CSS влияет только на отображение. Ссылка с display: block остаётся ссылкой, а поисковик и скринридер по-прежнему видят тег, а не его стиль.

Источники