В спецификации HTML представлены теги, которые являются изначально либо строчными (свойство display имеет значение inline), либо блочные (display: block). Однако с выходом стандарта CSS3 появилась возможность изменять отображение элемента на строчно-блочное (display: inline-block).

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

Лучше всего это можно продемонстрировать на примере. В файле ниже в двух колонках с одинаковым текстом выделены одни и те же словосочетания. Выделения находятся в элементах span с классом inline слева и inline-block справа. Для этих классов заданы общие правила:

Но в левой колонке все span имеют свойство display: inline, которое назначено для них в спецификации по умолчанию. А для span в правой колонке задан display: inline-block

Можно заметить, что за счет внутренних отступов (padding) слева цветные выделения накладываются друг на друга, кое-где перекрывая текст, а это и некрасиво, и нечитабельно. Что касается внешних отступов (margin), то сверху и снизу для span в левой колонке они просто игнорируются, и только слева и справа отодвигают текст от соседнего.

В правой колонке ситуация несколько иная - здесь все элементы span визуально отделены от соседнего текста, причем margin-ы работает по всем 4-м сторонам, а padding не приводят к перекрыванию текста выше. Выделенные блоки с большим количеством текста выглядят именно как блочные элементы, а те, где текста мало вписываются в текст, но за счет margin-ов увеличивают высоту строки.

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

  1. строчным элементам с фоном не стоит задавать большие внутренние отступы (padding), иначе они перекрывают выше идущий текст. Максимально это должно быть 3px и при этом стоит увеличить высоту строки (line-height) для родительского элемента (абзаца или div-а, например);
  2. строчно-блочные элементы с фоном, размещенные в тексте, не должны содержать большие объемы текста, иначе они будут "вываливаться" из него наподобие цитат, или врезок. Лучше использовать этот тип отображения для элементов, которые предназначены для каких-либо оформительских целей, например, для буквиц, шрифтовых иконок, кнопок, ссылок и т.п.

Использование inline-block элементов для создания кнопок

Сделаем еще один небольшой сравнительный анализ. В примере ниже представлены ссылки, внешний вид которых с помощью css-стилей отображает их как кнопки. Но 2 из них имеют display: inline-block, одна - display: inline (по умолчанию заданный в спецификации для ссылки) и еще одна  - display: block. Над каждой кнопкой подписано, каким образом она была отформатирована.

При клике на каждую из ссылок-кнопок текст, написанный на ней будет увеличен. В результате и сама кнопки либо увеличится, либо останется неизменной.

Что касается кнопок с display: inline-block и display: inline, у которых размер был сформирован padding-ами, то при добавлении текста они просто расширяются. Оранжевая кнопка  Sale, у которой размер имеет фиксированную ширину и высоту, увеличивается за счет добавленного текста вниз, хотя ни фон, ни рамка на этот текст не распространяются. Кнопка-ссылка с display: block изначально занимает всю ширину родительского элемента, поэтому добавление текста не влияет на ее размер на больших экранах. А вот на маленьких в ней текст за счет фиксированной высоты тоже выходит за пределы фона вниз. Еще можно заметить, что для желтой кнопки с display: inline несколько иначе определяются отступы от заголовка сверху - она расположена чуть выше всех остальных кнопок, хотя margin ни для одной из них в свойствах задан не был. Форматирование кнопок определялось такими свойствами:

Использование inline-block элементов для создания колонок

Сейчас существует масса способов сделать колонки, например, на основе Flexbox-модели, но свойство display: inline-block также можно использовать для этой цели. И здесь можно столкнуться с некоторыми особенностями поведения строчно-блочных элементов, о которых вы вряд ли задумывались когда-нибудь.

Например, у нас есть такая html-разметка: внутри родительского элемента с классом wrap есть 3 колонки с классами .col с заголовком и 3-мя абзацами. Можно воспользоваться аббревиатурой Emmet:

Нажимаем Tab и получаем разметку:

Для всех элементов добавим свойство box-sizing: border-box, чтобы ширина элементов не зависела от padding и border, а для родительского элемента .wrap зададим следующие максимальную ширину и внешние отступы:

Для 3-х колонок ширина их контейнера представляет собой 100%. Мы хотим, чтобы между колонками были отступы по 2%. Поскольку нам необходимы отступы только между первой и второй, а затем между второй и третьей, но не после 3-й колонки, то пространство контейнера следует разделить следующим образом: 100% - 4% margin = 96%. Далее 96%/3= 32% - получаем width каждой колонки. Затем используем это для свойств наших колонок с классом .col:

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

И вот, что мы получим в итоге:

Вуа-ля - и нет 3-х колонок, которые выстроились в одну линию. Вместо этого есть 2 колонки в одном ряду + одна в нижнем ряду. Совсем не то, что нужно. В чем же причина "сваливания" последней колоки?

Дело в том, что поскольку display: inline-block предполагает все-таки частично строчное размещение текста, то в конце каждой колонки у нас образуется еще один пробельный символ, в который превращаются все знаки в HTML (пробелы, табуляция, переносы слов), в каком бы количестве они не встречались в тексте. Именно этот пробельный символ, размер которого зависит от размера шрифта, и добавляет нам несколько пикселей между колонками, которые "выбивают" третью из них вниз. 

Чтобы этого избежать, имеет смысл воспользоваться функцией calc(), которая появилась в стандарте CSS3 и давно уже поддерживается современными браузерами. Важным моментом в ее использовании является установка пробелов ДО и ПОСЛЕ знака минус:

Результат уже намного лучше:

Для того чтобы колонки с разным количеством текста не выбивались из одной линии, необходимо использовать свойство vertical-align чаще всего со значением top. Добавим его к нашим css-свойствам:

В результате получим колонки разной высоты, но выровненные по верхней линии:

Автор: Админ

3 комментария

  1. Если в блоке я напишу так:
    link

    ...

    и поставлю для блока text-align: center, то ссылка и список станут по центру, хотя ссылка - это inline-элемент, а список - блочный. Почему так?

    • Дело в том, что в любом блочном элементе (список в вашем примере), для которого задан text-align: center, текст будет выравниваться по центру. Именно это вы и видите. Если элемент, которому задан display: block, нетекстовый - картинка, например, то text-align: center для родительского элемента никакого влияния на вложенный элемент не окажет.
      Пробуйте сами: ссылка на codepen.io.

  2. Спасибо. Все очень понятно расписано

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

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