Копание в свойстве отображения: два значения отображения

Опубликовано: 2022-03-10
Краткое резюме ↬ Мы много говорим о Flexbox и CSS Grid Layout, но эти методы макета, по сути, являются значениями свойства CSS display , рабочей лошадкой свойства, которому не уделяется много внимания. Рэйчел Эндрю лучше выглядит в коротком сериале.

Макет Flex или Grid начинается с объявления display: flex или display: grid . Эти методы макета являются значениями свойства display CSS. Мы склонны не слишком много говорить об этом свойстве отдельно, вместо этого концентрируясь на значениях flex или grid , однако есть некоторые интересные вещи, которые нужно понять о display и о том, как оно определяется, что значительно облегчит вашу жизнь при использовании. CSS для макета.

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

Блочные и встроенные элементы

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

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

Поведение блочных и встроенных элементов является фундаментальным для CSS, и тот факт, что правильно размеченный HTML-документ будет читабельным по умолчанию. Этот макет называется «блочным и встроенным макетом» или «нормальным потоком», потому что именно так элементы располагаются сами по себе, если мы не делаем с ними ничего другого.

Еще после прыжка! Продолжить чтение ниже ↓

Внутренние и внешние значения display

Мы понимаем блочные и встроенные элементы, но что произойдет, если мы сделаем элемент display: grid ? Это что-то совсем другое? Если мы посмотрим на компонент, для которого мы указали display: grid , с точки зрения родительского элемента в макете он ведет себя как элемент block level . Элемент будет растягиваться и занимать столько места во встроенном измерении, сколько доступно, он будет начинаться с новой строки. Он ведет себя точно так же, как элемент block с точки зрения того, как он ведет себя вместе с остальной частью макета. Мы не сказали display: block , хотя?

Оказывается, у нас есть. На уровне 3 спецификации Display значение display определяется как два ключевых слова. Эти ключевые слова определяют внешнее значение отображения, которое будет inline или block и, следовательно, определяют, как элемент ведет себя в макете вместе с другими элементами. Они также определяют внутреннее значение элемента — или то, как ведут себя непосредственные дочерние элементы этого элемента.

Это означает, что когда вы говорите display: grid , на самом деле вы говорите display: block grid . Вы запрашиваете контейнер сетки на уровне блока. Элемент, который будет иметь все атрибуты блока — вы можете задать ему высоту и ширину, поля и отступы, и он будет растягиваться, чтобы заполнить контейнер. Однако дочерним элементам этого контейнера было присвоено внутреннее значение grid , поэтому они становятся элементами сетки. То, как ведут себя эти элементы сетки, определено в спецификации CSS Grid: спецификация display дает нам способ сообщить браузеру, что это метод макета, который мы хотим использовать.

Я думаю, что такое представление об display невероятно полезно; это напрямую объясняет, что мы делаем с различными методами компоновки. Если бы вы указали display: inline flex , чего бы вы ожидали? Надеюсь, блок, который ведет себя как встроенный элемент, с дочерними элементами, которые являются гибкими элементами.

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

Мы всегда возвращаемся к нормальному потоку

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

См. Pen Block и Inline Layout Рэйчел Эндрю.

См. Pen Block и Inline Layout Рэйчел Эндрю.

В приведенном ниже примере содержится некоторая разметка, которую я превратил в медиа-объект, сделав div display: flex (два прямых дочерних элемента) теперь гибкими элементами, поэтому изображение теперь находится в строке с содержимым. Однако, если вы видите в содержании, есть заголовок и абзац, которые снова отображаются в обычном порядке. Прямые дочерние элементы медиа-объекта стали гибкими элементами; их дочерние элементы возвращаются к нормальному потоку, если мы не изменим значение display на элементе flex. Flex-контейнер сам по себе представляет собой блочный блок, как вы можете видеть по тому факту, что граница простирается до края его родителя.

См. Pen Block и Inline Layout With Flex Component Рэйчел Эндрю.

См. Pen Block и Inline Layout With Flex Component Рэйчел Эндрю.

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

Объяснение flow-root и inline-block

Значение inline-block также, вероятно, знакомо многим из нас, кто какое-то время занимался CSS. Это значение — способ получить некоторое поведение блока для inline элемента. Например, элемент inline-block может иметь ширину и высоту. Элемент с display: inline-block также ведет себя интересным образом, поскольку он создает блокировку B для форматирования содержимого ( BFC ).

BFC делает некоторые полезные вещи с точки зрения макета, например, он содержит числа с плавающей запятой. Подробнее о контекстах блочного форматирования см. в моей предыдущей статье «Понимание макета CSS и контекста блочного форматирования». Поэтому, говоря display: inline-block , вы получаете встроенный блок, который также устанавливает BFC.

Как вы обнаружите (если вы читали вышеупомянутую статью о контексте блочного форматирования), существует более новое значение display, которое также явно создает BFC. Это значение flow-root . Это значение создает BFC на блоке, а не на встроенном элементе.

  • display: inline-block дает вам BFC на встроенном поле.
  • display: flow-root дает вам BFC на блок-боксе.

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

Устаревшие значения отображения

Спецификация CSS2 детализировала следующие значения свойства display :

  • inline
  • block
  • inline-block
  • list-item
  • none
  • table
  • inline-table

Также были определены различные внутренние свойства таблицы, такие как table-cell , которые мы не рассматриваем в этой статье.

Затем мы добавили к ним некоторые значения для отображения, чтобы поддерживать flex и сетку:

  • grid
  • inline-grid
  • flex
  • inline-flex

Примечание . Спецификация также определяет ruby ​​и inline-ruby для поддержки Ruby Text, о чем вы можете прочитать в спецификации Ruby.

Это все отдельные значения свойства display , определенные до того, как спецификация была обновлена ​​для объяснения CSS Layout таким образом. Что очень важно в CSS, так это тот факт, что мы не ломаем сеть; мы не можем просто что-то изменить . Мы не можем внезапно решить, что все должны использовать этот новый синтаксис с двумя значениями, и поэтому каждый когда-либо созданный веб-сайт, использующий синтаксис с одним значением, сломается, если разработчик не вернется и не исправит его!

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

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

Одно значение Значения двух ключевых слов Описание
block block flow Блочная коробка с нормальным потоком внутри
flow-root block flow-root Блок-бокс, определяющий BFC
inline inline flow Встроенная коробка с нормальным потоком внутри
inline-block inline flow-root Встроенный блок, определяющий BFC
list-item block flow list-item Блок-бокс с нормальным внутренним потоком и дополнительным маркерным блоком
flex block flex Блок-бокс с внутренней гибкой компоновкой
inline-flex inline flex Встроенный блок с внутренней гибкой компоновкой
grid block grid Блок-бокс с внутренней сеткой
inline-grid inline grid Встроенный блок с внутренней сеткой
table block table Блок-бокс с внутренней компоновкой стола
inline-table inline table Встроенный блок с внутренней компоновкой таблицы

Чтобы объяснить, как это работает, мы можем подумать о грид-контейнере. В мире двух значений мы бы создали контейнер сетки на уровне блока с:

 .container { display: block grid; }

Однако устаревшее ключевое слово означает, что следующее делает то же самое:

 .container { display: grid; }

Если вместо этого нам нужен встроенный грид-контейнер, в мире двух значений мы будем использовать:

 .container { display: inline grid; }

И если использовать устаревшие значения:

 .container { display: inline-grid; }

Теперь мы можем вернуться к тому, с чего начался этот разговор, и посмотреть на display: inline-block . Глядя на таблицу, вы можете видеть, что это определяется в мире двух значений как display: inline flow-root . Теперь он соответствует display: flow-root , что в мире с двумя значениями было бы display: block flow-root . Небольшая уборка и разъяснение того, как эти вещи определяются. Рефакторинг CSS, если хотите.

Поддержка браузерами синтаксиса с двумя значениями

Пока что браузеры не поддерживают синтаксис с двумя значениями для свойства display . Ошибку реализации для Firefox можно найти здесь. Реализация — когда это произойдет — по существу будет включать псевдонимы устаревших значений для версий с двумя значениями. Поэтому, скорее всего, пройдет немало времени, прежде чем вы действительно сможете использовать эти версии с двумя значениями в своем коде. Однако суть данной статьи не в этом. Вместо этого я думаю, что рассмотрение значений отображения в свете двухзначной модели помогает объяснить многое из того, что происходит.

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