Контекст блочного форматирования и списки.

Источник: Block formatting contexts and lists.
Автор:  Paul Bakaus.
Перевод: .

Если вы в курсе последних событий из области CSS, то скорее всего уже читали о flow-root. Данное свойство устанавливает контекст блочного форматирования, но многие не обращают внимания на этот факт, а просто используют его в качестве замены хака clearfix. Теперь давайте рассмотрим чрезвычайно распространенный случай, когда имеющиеся на странице несколько параграфов текста взаимодействуют со смещенным изображением и несколькими пунктами списка:

See the Pen Block formatting contexts by Paul Bakaus (@pbakaus) on CodePen.

Как вы видите, все вроде бы работает. В приведенном выше примере использованы следующие настройки:

img {
width: 33%;
height: auto;
float: left;
}

Однако, в глаза бросаются нелепые отступы (а точнее их отсутствие) между маркерами списка и изображением. Как оказалось, данная проблема не может быть решена обычным путем. То есть, привычные для нас методы, которые, собственно, и предназначены для подобных ситуаций, в данном случае просто не работают. Речь идет о свойствах padding-left и margin-left. Почему так происходит?

Дело в том, что при смещении элемента с помощью свойства float, каких либо изменений прилегающих к нему боксов соседних элементов, к сожалению, не происходит. Попробуйте перейти к необходимому элементу в консоли DevTools, это вызовет визуальную подсветку соответствующего бокса на странице. Вот, что вы увидите:

Как бы то ни было, но реальный текстовый контент, включая строчные элементы, должным образом смещается вправо, огибая смещенный элемент. Если вы хотите увеличить отступ для маркеров списка, то можете установить величину его левого поля (margin-left) превышающую ширину самого изображения. Однако поступая таким образом, вы должны быть уверены в том, что изображение всегда будет находиться нужном месте. Сами понимаете — гарантий никаких.

Ладно, и где же выход?

Я рад, что вы задаете такой вопрос. Очевидным ответом на него является использование flow-root:

ul {
display: flow-root;
}

Но больное место этого свойства — все еще слабая поддержка браузерами. Тем не менее, я нашел 4 варианта решения этой проблемы. Один лучше другого. Каждый из них устанавливает блочный контекст форматирования и должен быть применен к элементу <ul>:

  1. Использование display: inline-block. Вроде бы работает, но при условии, что в самих пунктах списка (в элементах <li>) нет переноса текста на другую строку. А это, как вы понимаете, трудно гарантировать.
  2. Правило overflow: hidden. Прекрасно подходит для случаев, когда в вашем списке отсутствуют элементы, позиционированные за пределами форматируемого бокса.
  3. display: table-cell. Тоже неплохой вариант, но ох уж эти таблицы, всегда с ними что-нибудь не так. Ячейка таблицы имеет свойство адаптации своего размера под объем содержимого, что не всегда приемлемо.
  4. При всех преимуществах гибкой модели — display: flex; flex-direction: column;, ее применение напрямую зависит от способа использования списка.

С помощью представленного выше Codepen проекта и инструментария DevTools вы можете подобрать вариант, который максимально удовлетворит вашим требованиям.

И если все работает, то зачем обременять себя ожиданием полной поддержки flow-root? Хотя это свойство уже существует, ваш CSS будет лучше выражать намерения разработчика. А шансы, что спустя год вы вспомните, почему для <ul> вы применили, допустим display: table-cell, практически равны нулю.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *