Frontier who watches the watchmen?

Инлайн-блоки как светлое настоящее

Пока flexbox ещё за Горами Реализаций, inline-block — надёжный инструмент верстальщика.

TL;DR: элемент со свойством display: inline-block рендерится как блок, но при этом позиционируется в строке.

История

Помимо квадратуры круга и простого доказательства Великой теоремы Ферма, перед человечеством с момента создания интернета стоял важный вопрос — как отцентрировать блок по вертикали, если высота этого блока заранее неизвестна (ведь если известна, то всё просто)

Каждый решал этот вопрос в меру своей испорченности — кто возвращал макет дизайнерам с пометкой «no way», кто забивал на семантику и верстал таблицами, а кто делал получше, применяя display: table к <div>. Хитрая техника c абсолютным позиционированием не была ещё сильно известна.

И тут inline-block вступает в игру. Он нормально поддерживается всеми браузерами (IE — с восьмой версии), довольно семантичен и прост. Вертикальное центрирование — лишь одно из многих применений.

И для его реализации есть два метода, в зависимости от того, известна ли высота родительского

  • Выставляем line-height родительского блока равным высоте, а самому блоку сбрасываем line-height и присваиваем vertical-align: middle.
  • Вставляем внутри родительского блока рядом ещё один inline-block с height: 100% и vertical-align: middle. Таким образом, line-height родительского блока всё равно становится равной его высоте и мы возвращаемся к предыдущему варианту без необходимости сбрасывать line-height.

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

отцентрируйте меня, пожалуйста

Этот и следующие примеры стоит рассматривать также в Developer’s Tools или аналоге вашего браузера для наглядности.

Суть

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

С использованием инлайн-блоков также элементарно сверстать типичную подачу товаров в интернет-магазине, с которой раньше было много проблем: нужно чётко подсчитывать ширину, выводить бэкендом в специальных контейнерах специальное количество блоков с float: left. А если что-то пойдёт не так, то вся вёрстка разъезжается к чёрту. Инлайн-блоки делают процесс гораздо проще — можно в один контейнер накидать кучу блоков и они сами распределятся, если не влезли на одну строку — перенесутся.

К сути:

  • Котейка номер раз. Очень вежливый, приучен к лотку. Любит Звёздные Войны и верстать на досуге.
  • Котейка номер два. Не такой вежливый, зато милый: расцарапает, а не жалко!
  • Котейка номер три. Если можно так сказать, чёрная лошадка среди этих котеек. Я бы даже сказал, кот в мешке!

Попробуйте изменить размер окна так, чтобы третий блок перенёсся на следующую строку

С использованием инлайн-блока для подобных целей следует помнить, что он рендерится в строке. А значит, что все пробелы между элементами, которые нужны для форматирования кода схлопываются в один, который честно занимает своё место в строке. Эта особенность, если про неё забыть, может стоить вам получаса отладки, когда блок из-за неведомой (но только что объяснённой) магии сдвигается на два-три пикселя и съезжает в итоге вниз, например.

Столкнувшись с этой особенностью (не баг, а фича!), веб-технологи тут же придумали несколько вариантов решения:

  • Не закрывать теги. Теги <li>, <p> можно не закрывать — браузер сам закроет их, когда встречает следующий <li> или <p>.
    • Плюсы: легко использовать
    • Минусы: редактор так и норовит закрыть </li>; не применить к другим тегам
  • Не вставлять пробелов между тегами.
    • Плюсы: foolproof. Ну, почти. Применимо к любым тегам
    • Минусы: код не так красиво отформатирован в редакторе! (не имеет значения, если разметка генерируется сервером)
  • Вставлять HTML-комментарии. </div><!--куча отступов--><div>
    • Плюсы: Применимо ко всем тегам. Мой личный фаворит.
    • Минусы: некоторым не нравятся «лишние» комментарии в коде.
  • Использовать font-size: 0 на родительском элементе.
    • Плюсы: прост в использовании, никаких изменений разметки.
    • Минусы: если вы используете em, то все размеры к чертям. Используйте rem.

Для дальнейшего рассказа потребуется ещё немного теории, налейте себе кофе.

Чуть-чуть теории

Любой элемент на странице обернут в один из так называемых боксов. Существуют боксы инлайн-уровня, а есть блочные боксы, и напрямую рядом они не могут стоять. Так, например, если сделать <div>Привет, <div>мир!</div>Я так рад тебя видеть</div>, то внутренний <div> уедет на отдельную строку.

Привет,
мир!
Я так рад тебя видеть

Так получается потому, что строки «Привет, » и «Я так рад тебя видеть» из-за соседства с внутренним <div> оборачиваются в анонимные боксы блочного уровня — у них нет имени и им невозможно присвоить стили: что можно наследовать, они наследуют, всё остальное становится initial. В то же время, inline-block не заставляет оборачиваться строки вокруг в такие боксы, то есть он сохраняет контекст форматирования строки.

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

Текст внутри этого спана может легко разбиваться на две строки, ведь это инлайновый бокс.
Текст внутри этого span'а не будет разбиваться на несколько строк до последнего, ведь это inline-block.

Заметили резкий обрыв первой строки? Такое поведение инлайн-блоков стоит учитывать, чтобы не возникло некрасивых переносов.

Вот, собственно, и всё, что нужно знать об инлайн-блоках, чтобы начать ими восхищаться и пользоваться.