CSS свойство display

Источник: «Exploring the CSS :display property: A deep dive»
Понимание CSS свойства display и его значений важно для создания правильно организованных и привлекательных сайтов.

HTML элементы обычно следуют стандартному потоку — также называемому нормальным потоком — и естественным образом располагаются на странице. При таком расположении некоторые элементы расширяются, заполняя весь родительский контейнер, и располагаются вертикально, один над другим. Другие занимают только необходимое для их содержимого пространство.

Эти различия обусловлены свойством display, назначаемым этим элементам по умолчанию. В этой статье мы погрузимся в CSS свойство display. Подробно рассмотрим его различные значения, а также примеры и фрагменты кода, иллюстрирующие использование каждого значения.

Что такое CSS свойство display

CSS свойство display определяет внешние и внутренние значения отображения элемента:

Свойство display также управляет тем, генерирует ли элемент вообще какой-либо бокс.

Синтаксис display

Синтаксис CSS свойства display следующий:

element {
display: value;
}

Можно использовать различные значения для настройки внешнего и внутреннего поведения отображения. Ключевые слова, влияющие на внешнее отображение, включают:

Между тем, ключевые слова, влияющие на внутреннее отображение, включают:

В следующих разделах мы рассмотрим различные доступные значения display и способы их стратегического использования в веб-проектах. Также рассмотрим использование нескольких значений свойства display для задания внешнего и внутреннего значения отображения.

Значения display по умолчанию: block и inline

Прежде чем начать явно применять значения display к элементам, в CodePen ниже показано, как некоторые элементы отображаются по умолчанию. Для того чтобы элементы примера выделялись индивидуально, были добавлены фоновые цвета:

See the Pen

На этом примере более подробно рассмотрим значения block и inline.

Блочные элементы

В приведённом выше примере CodePen видно, что элементы <section>, <div>, <p> и <footer> заполняют всю ширину своего контейнера, каждый из них появляется на новой строке. Такие элементы называются блочными элементами и по умолчанию имеют значение display равное block:

element {
display: block;
}

Другие блочные элементы включают <article>, <aside>, <table>, <form> и другие.

Установив значение свойства display в block, можно превратить не блочный элемент в блочный.

Кроме того, блочные элементы могут вмещать в себя другие блочные и инлайн элементы. Можно настраивать различные свойства блочных элементов, включая их высоту, ширину, поля и отступы. Они часто используются для структурирования макетов веб-страниц, создания текстового содержимого, списков и так далее.

Инлайн элементы

Такие элементы, как <span> и <a>, которые также можно увидеть в CodePen выше, занимают только то пространство, которое требуется для их контента, и не вытесняют другие элементы. Такие элементы называются инлайн элементами, и по умолчанию они имеют значение display: inline:

element {
display: inline;
}

К другим инлайн элементам относятся <img>, <button>, <strong>, <input>, <textarea> и другие. Они удобны, когда необходимо, чтобы элементы отображались в строке с текстом, не вызывая разрывов строк.

Установка значения свойства display в inline превращает не инлайн элемент в инлайн элемент. Инлайн элементы не могут содержать элементы блочного уровня, но могут вмещать другие инлайн элементы.

Хотя инлайн элементы обычно не принимают свойства height и width, существуют исключения, например элемент <img>. Применение padding к инлайн элементам не отталкивает другие элементы, как показано в примере CodePen, а margin влияет только на горизонтальное смещение.

Можно выбрать любой из этих элементов в потоке макета и использовать свойство display, чтобы изменить их значение отображения по умолчанию.

Использование нескольких значений CSS свойства display

Как уже говорилось, CSS свойство display элемента определяет его внешний и внутренний типы отображения. Ранее можно было использовать только одно ключевое слово для значения этого свойства, как показано выше. Однако в большинстве случаев этот синтаксис не имеет явного описания своей функциональности.

Например, display: block; или display: inline; определяет только внешний тип отображения элемента — то есть, занимает ли элемент всю ширину контейнера или его размер зависит от содержимого. Он не определяет внутренний тип отображения, хотя поведение макета по умолчанию для дочерних элементов подразумевается, то есть они следуют нормальному потоку.

После выхода Level 3 Specification для свойства display можно использовать два ключевых слова для указания внешнего и внутреннего значений отображения. Синтаксис выглядит следующим образом:

element {
display: outer-value inner-value;
}

Во многих случаях использование значения из нескольких ключевых слов приводит к такому же поведению, как и одно значение. Значения с несколькими ключевыми словами просто обеспечивают ясность, определяя как внешние, так и внутренние значения отображения.

Например, в более ранней спецификации CSS можно было использовать одно ключевое слово block в свойстве display:

element {
display: block;
}

Однако теперь рекомендуется использовать значение с несколькими ключевыми словами block flow, чтобы быть более конкретным:

element {
display: block flow;
}

Это позволит более чётко передать фактическое значение значения display, хотя и не изменит ожидаемого поведения.

Вот таблица, показывающая, как взять одно свойство display, используемое в старых спецификациях CSS, и переписать его, используя более явный синтаксис, рекомендованный в спецификации Level 3:

Старый синтаксисНовый синтаксис
display: block;display: block flow;
display: inline;display: inline flow;
display: flexdisplay: block flex;
display: grid;display: block grid;
display: flow-root;display: block flow-root;
display: table;display: block table;
display: inline-flex;display: inline flex;
display: inline-grid;display: inline grid;
display: inline-block;display: inline flow-root;

Аналогично, inline-block — это единственное ключевое слово, создающее контекст форматирования блока (BFC) для инлайн элемента. Теперь оно называется inline flow-root, позволяя использовать внутреннего display значение flow-root для создания BFC на инлайн блоке.

Использование обоих типов значений — внешнего и внутреннего — позволяет сразу понять роль элемента в обычном потоке и макет, используемый для его дочерних элементов. Давайте рассмотрим несколько примеров применения значений с несколькими ключевыми словами к CSS свойству display.

Переключение на блочный элемент

Если работая с инлайн элементом, установить для его свойства display значение block flow, можно превратить его в блочный элемент. Дочерние элементы этого элемента будут следовать нормальному макету flow, ведя себя как блочные или инлайн боксы.

Например, вот результат преобразования элементов <span> и <a> из предыдущего примера в блочные элементы:

See the Pen

Это может быть полезно, если необходимо, чтобы инлайн элемент занимал всю ширину родительского контейнера, отображался на собственной строке или использовал стилевые свойства блочного уровня.

Переключение на инлайн элемент

Также можно превратить блочный элемент в инлайн элемент с помощью значений нескольких ключевых слов в свойстве display. Дочерние элементы этого элемента будут следовать обычному расположению flow, ведя себя как блочные или инлайн боксы.

Вот результат преобразования блочных элементов <li> в инлайн списки:

See the Pen

display: block flex; и display: inline flex;

Установка свойства display в flex определяет элемент как flex контейнер. Это устанавливает новый контекст форматирования flex для содержимого элемента. Прямые дочерние элементы элемента также становятся flex элементами и размещаются с использованием модели flex макета, а не нормального потока.

Приведённый ниже CodePen демонстрирует, как ведут себя элементы в нормальном потоке, когда применяется block flex к свойству display:

See the Pen

Как видите, есть инлайн элемент-контейнер span с дочерними элементами span и a. Также есть блочный элемент-контейнер article с двумя дочерними элементами div. Все они ведут себя так, как и ожидалось в нормальном потоке в их естественном состоянии.

Если мы переключим отображение со значения default на flex или block-flex с помощью выпадающего списка select, элемент инлайн контейнера станет блочным. При этом элемент блочного контейнера остаётся неизменным, но его содержимое меняет своё поведение по мере того, как оно размещается с помощью модели макета flex.

Предположим, вместо этого необходимо превратить элементы контейнера в инлайн элементы, используя модель макета flex. Это можно сделать, применив ключевое слово inline-flex — или, что ещё лучше, применив обновлённый, более явный синтаксис и применив значение inline flex с двумя ключевыми словами:

See the Pen

Помните, что значение inline-flex с одним ключевым словом и значение inline flex с несколькими ключевыми словами приводят к одинаковому поведению. Использование обоих ключевых слов внешнего и внутреннего в свойстве display позволяет добиться большей ясности.

Переключение отображения на inline flex превращает блочный элемент контейнер в инлайн элемент. Содержимое контейнера также размещается с использованием модели макета flex.

Исходя из этого, можно понять роль flex элемента при создании макета с flexbox.

display: block grid; и display: inline grid;

Установка значения внутреннего свойства display в значение grid определяет элемент как grid-контейнер. Это устанавливает контекст форматирования grid для его содержимого, гарантирует, что прямые дочерние элементы станут grid-элементами, и выстраивает дочерние элементы в соответствии с CSS спецификацией grid.

Как и Flexbox, grid также помогает решить некоторые проблемы с вёрсткой. Приведённый ниже CodePen демонстрирует, как ведут себя элементы в нормальном потоке, когда применяется ключевое слово grid к свойству display:

See the Pen

Если переключить select выпадающего списка со значения по умолчанию на grid или block grid, то контейнерный инлайн элемент станет блочным, заполняя весь родительский контейнер, а блочный контейнерный элемент останется неизменным. Содержимое контейнеров также выстраивается в сетку/grid — можно увидеть, как это меняет внешний вид элементов span и a.

При применении значения grid внешний тип отображения элемента по умолчанию становится block. Таким образом, значение с одним ключевым словом grid и значение с несколькими ключевыми словами block grid дадут одинаковый результат.

Но что, если нужно определить элемент как инлайн элемент в контейнере сетки? Это можно сделать с помощью значения с несколькими ключевыми словами inline grid, ранее использовавшегося как одно ключевое слово inline-grid. Посмотрите на обновлённый пример:

See the Pen

Если переключить отображение с default на inline-grid или inline grid, блочный элемент-контейнер станет элементом инлайн. Содержимое контейнеров также выстроится в сетку.

display: block flow-root;

Установка значения свойства display в flow-root помогает удерживать элементы внутри их родителя. flow-root создаёт "блочный" элемент со своим собственным BFC. Это означает, что элемент будет вести себя как display: block flow; но с новым корнем в качестве контекста форматирования, в котором содержится всё, что находится внутри.

Если вы понимаете CSS-концепцию схлопывания margin, то знаете, что вертикальные поля соседних элементов на уровне блока сворачиваются в одно поле. Наглядным примером является схлопывание полей между родственными элементами, например, параграфами в CodePen ниже:

See the Pen

Каждый параграф имеет 16px поля сверху и снизу. Однако из-за схлопывания полей между параграфами не будет отступа 32px. Вместо этого результирующим отступом будет больший из индивидуальных отступов — но в нашем случае значения равны, поэтому отступ составит всего 16px.

Хотя схлопывание полей между родственными элементами предотвращает появление лишних интервалов, поля также могут схлопываться между родителями и детьми, что может привести к нежелательным результатам.

Приведённый ниже пример CodePen демонстрирует проблему. Попробуйте использовать выпадающий список, чтобы применить margin-top к элементу заголовка, создавая свободное пространство внутри родительского элемента. При этом margin-top дочернего элемента не содержится внутри родительского, а проваливается за его пределы:

See the Pen

Даже если margin не содержится в родительском элементе, он всё равно содержится в области просмотра. Это происходит потому, что корневой элемент <html> сам создаёт контекст форматирования блока.

Чтобы удержать margin внутри родительского элемента, можно сделать родителя новым корнем потока. Синтаксис нескольких ключевых слов явно описывает значения следующим образом:

element {
display: block flow-root;
}

В приведённом ниже примере CodePen применение display: block flow-root; гарантирует, что margin-top дочернего элемента будет находиться внутри родительского блочного элемента:

See the Pen

Применение некоторых других CSS свойств к родителю — таких, как padding, border или overflow — также может гарантировать, что margin будет находиться в пределах своего родителя.

display: inline flow-root;

Аналогично тому, как display: block flow-root; создаёт BFC на блочном блоке, можно создать BFC на инлайн боксе. Таким образом, всё, что находится внутри инлайн бокса, будет содержаться в нем. Например, применение padding и margin к инлайн элементам теперь может оттеснить другие элементы. Аналогичным образом будут применяться значения width и height.

Раньше для этого приходилось использовать значение, состоящее из одного ключевого слова, примерно так:

display: inline-block;

Теперь, когда можно использовать значения из нескольких ключевых слов, можно написать свойство display более конкретно для большей ясности:

display: inline flow-root;

Обновим исходный пример CodePen, чтобы продемонстрировать это поведение:

See the Pen

Элементы <span> и <a> размещены в строке, как и положено инлайн элементам. Однако всё, что находится внутри бокса, теперь содержится в нем. Как видим, теперь можно применить свойства width, height, margin и padding.

display: block table;

Добавление значения table к свойству display элемента блочного уровня заставляет его вести себя как HTML элемент <table>. Раньше это значение помогало при создании сложных макетов страниц. Сейчас его редко используют, так как можно воспользоваться CSS системами разметки flexbox и grid, обеспечивающими большую гибкость.

Рассмотрим следующую структуру HTML таблицы в её простейшем виде:

<table>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
{/* ... */}
</table>

Приведённый ниже CodePen демонстрирует, как мы можем воспроизвести HTML таблицу в CSS с помощью display: block table и других display утилит:

See the Pen

В коде вложенные элементы отображающиеся как table-row и table-cell.

Справочная таблица: Использование нескольких значений CSS свойства display

Приведённую ниже таблицу можно использовать в качестве справочника по комбинации значений свойств внутреннего и внешнего отображения для достижения различных эффектов:

Тип внутреннего отображенияТип внешнего отображения: blockТип внешнего отображения: inline
flowdisplay: block flow;
Ведёт себя как блочный элемент, размещённый в документе с использованием нормального потока. По сути, это то же самое, что и display: block, так как блочные элементы по умолчанию используют стандартный поток макета.
display: inline flow;
Ведёт себя как инлайн элемент, размещённый в документе с использованием нормального потока. По сути, это то же самое, что и display: inline, так как инлайн элементы по умолчанию используют стандартный макет потока.
flow-rootdisplay: block flow-root;
Ведёт себя как блочный элемент с новым контекстом форматирования блока, заставляя его дочерние элементы располагаться с использованием нормального потока и предотвращая схлопывание margin с другими элементами. По сути, то же самое, что и display: flow-root.
display: inline flow-root;
Ведёт себя как инлайн элемент с новым контекстом форматирования блока, заставляя его дочерние элементы располагаться с использованием нормального потока и предотвращая схлопывание margin с другими элементами. По сути, то же самое, что и inline-block.
flexdisplay: block flex;
Ведёт себя как блочный элемент, но его дочерние элементы размещаются с использованием макета flexbox. По сути, то же самое, что и display: flex, но с явным внешним блочным поведением.
display: inline flex;
Ведёт себя как инлайн элемент, но его дочерние элементы размещаются с использованием макета flexbox. По сути, то же самое, что и display: inline-flex, но с явным внешним инлайн поведением.
griddisplay: block grid;
Ведёт себя как блочный элемент, но его дочерние элементы располагаются с использованием макета grid. По сути, то же самое, что и display: grid, но с явным внешним блочным поведением.
display: inline grid;
Ведёт себя как инлайн элемент, но его дочерние элементы располагаются с использованием макета grid. По сути, то же самое, что и display: inline-grid, но с явным внешним инлайн поведением.
tabledisplay: block table;
Ведёт себя как блочный элемент таблицы, заставляя элемент вести себя как HTML <table>.
Недоступен

Одиночные значения display

Есть два значения display, которые могут использоваться только сами по себе — none и contents. Давайте рассмотрим, как эти ключевые слова работают со свойством display.

display: none;

Использование display: none скрывает элемент и его потомков на веб-странице. Это свойство часто используется для временного скрытия элементов, которые должны отображаться только при определённых размерах экрана или при срабатывании JavaScript.

Помните, что использование display: none может привести к потенциальному изменению макета страницы. Если необходимо скрыть элемент, сохранив при этом стабильность макета страницы, можно воспользоваться другим CSS объявлением, visibility: hidden. Это объявление делает элемент невидимым, сохраняя его место в макете.

Приведённый ниже CodePen демонстрирует поведение объявлений display: none и visibility: hidden:

See the Pen

Выбор display: none в CodePen удаляет целевой элемент span из макета. Напротив, выбор visibility: hidden делает элемент невидимым, сохраняя его положение.

display: contents;

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

В примере CodePen, приведённом ниже, элемент .wrapper создаёт ненужную вложенность, усложняя flex макет. Необходимо, чтобы элементы .item рассматривались как прямые дочерние элементы .flex контейнера, чтобы их можно было распределить соответствующим образом. Поэтому применяем display: contents к .wrapper, чтобы эффективно удалить его из макета:

See the Pen

Дополнительные материалы

Предыдущая Статья

Освоение области запросов в Laravel

Следующая Статья

Поддержка HTML 5 в PHP 8.4