В спецификации HTML представлены теги, которые являются изначально либо строчными (свойство display имеет значение inline), либо блочные (display: block). Однако с выходом стандарта CSS3 появилась возможность изменять отображение элемента на строчно-блочное (display: inline-block).
По сути строчно-блочные элементы являются чем-то средним между строчными и блочными. То есть они имеют свойства и тех, и других элементов, комбинируя их. Каким образом? - В тексте они ведут себя, как строчные элементы, т.е. занимают ровно столько места, сколько текста содержится в них (если не заданы ширина или отступы), однако при назначении свойств box-модели, интерпретируют их, как блочные элементы.
Лучше всего это можно продемонстрировать на примере. В файле ниже в двух колонках с одинаковым текстом выделены одни и те же словосочетания. Выделения находятся в элементах span с классом inline слева и inline-block справа. Для этих классов заданы общие правила:
.inline, .inline-block {
margin: 7px;
padding: 7px;
}
Но в левой колонке все span имеют свойство display: inline, которое назначено для них в спецификации по умолчанию. А для span в правой колонке задан display: inline-block.
Можно заметить, что за счет внутренних отступов (padding) слева цветные выделения накладываются друг на друга, кое-где перекрывая текст, а это и некрасиво, и нечитабельно. Что касается внешних отступов (margin), то сверху и снизу для span в левой колонке они просто игнорируются, и только слева и справа отодвигают текст от соседнего.
В правой колонке ситуация несколько иная - здесь все элементы span визуально отделены от соседнего текста, причем margin-ы работает по всем 4-м сторонам, а padding не приводят к перекрыванию текста выше. Выделенные блоки с большим количеством текста выглядят именно как блочные элементы, а те, где текста мало вписываются в текст, но за счет margin-ов увеличивают высоту строки.
Сложно назвать оба вида форматирования красивыми, но из этого тестового упражнения можно сделать следующие выводы:
- строчным элементам с фоном не стоит задавать большие внутренние отступы (
padding), иначе они перекрывают выше идущий текст. Максимально это должно быть 3px и при этом стоит увеличить высоту строки (line-height) для родительского элемента (абзаца или div-а, например); - строчно-блочные элементы с фоном, размещенные в тексте, не должны содержать большие объемы текста, иначе они будут "вываливаться" из него наподобие цитат, или врезок. Лучше использовать этот тип отображения для элементов, которые предназначены для каких-либо оформительских целей, например, для буквиц, шрифтовых иконок, кнопок, ссылок и т.п.
Использование inline-block элементов для создания кнопок
Сделаем еще один небольшой сравнительный анализ. В примере ниже представлены ссылки, внешний вид которых с помощью css-стилей отображает их как кнопки. Но 2 из них имеют display: inline-block, одна - display: inline (по умолчанию заданный в спецификации для ссылки) и еще одна - display: block. Над каждой кнопкой подписано, каким образом она была отформатирована.
При клике на каждую из ссылок-кнопок текст, написанный на ней будет увеличен. В результате и сама кнопки либо увеличится, либо останется неизменной.
Что касается кнопок с display: inline-block и display: inline, у которых размер был сформирован padding-ами, то при добавлении текста они просто расширяются. Оранжевая кнопка Sale, у которой размер имеет фиксированную ширину и высоту, увеличивается за счет добавленного текста вниз, хотя ни фон, ни рамка на этот текст не распространяются. Кнопка-ссылка с display: block изначально занимает всю ширину родительского элемента, поэтому добавление текста не влияет на ее размер на больших экранах. А вот на маленьких в ней текст за счет фиксированной высоты тоже выходит за пределы фона вниз. Еще можно заметить, что для желтой кнопки с display: inline несколько иначе определяются отступы от заголовка сверху - она расположена чуть выше всех остальных кнопок, хотя margin ни для одной из них в свойствах задан не был. Форматирование кнопок определялось такими свойствами:
.readmore,
.sale,
.sale-block,
.inline {
color: #000;
text-decoration: none;
border-radius: 7px;
border: 3px solid;
}
.readmore {
display: inline-block;
padding: 10px 17px;
background-color: #6efc68;
border-color: #37ac32;
}
.inline {
background-color: #ffff37;
border-color: #ffc937;
padding: 10px 17px;
}
.sale,
.sale-block {
height: 35px;
line-height: 35px;
text-align: center;
}
.sale {
display: inline-block;
width: 135px;
background-color: #f7692a;
border-color: #c13c01;
}
.sale-block {
display: block;
background-color: #3ad9ff;
border-color: #0a6d84;
}
Использование inline-block элементов для создания колонок
Сейчас существует масса способов сделать колонки, например, на основе Flexbox-модели, но свойство display: inline-block также можно использовать для этой цели. И здесь можно столкнуться с некоторыми особенностями поведения строчно-блочных элементов, о которых вы вряд ли задумывались когда-нибудь.
Например, у нас есть такая html-разметка: внутри родительского элемента с классом wrap есть 3 колонки с классами .col с заголовком и 3-мя абзацами. Можно воспользоваться аббревиатурой Emmet:
.wrap.col*3>h2{Some Title $}+p*3>lorem15
Нажимаем Tab и получаем разметку:
<div class="wrap">
<h2>Колонки</h2>
<div class="col">
<h2>Some Title 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur ...</p>
<p>Quia neque ut repellat ratione ullam...</p>
<p>Dolore consequatur omnis ...</p>
</div>
<div class="col">
<h2>Some Title 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur ...</p>
<p>Quibusdam, consequatur animi, rem ...</p>
<p>Nisi quibusdam dolore atque ...</p>
</div>
<div class="col">
<h2>Some Title 3</h2>
<p>Lorem ipsum dolor sit amet ...</p>
<p>Ipsum magnam, nam consequatur ...</p>
<p>Accusantium necessitatibus ...</p>
</div>
</div>
Для всех элементов добавим свойство box-sizing: border-box, чтобы ширина элементов не зависела от padding и border, а для родительского элемента .wrap зададим следующие максимальную ширину и внешние отступы:
* { box-sizing: border-box;}
.wrap {
max-width: 1200px;
margin: auto;
}
Для 3-х колонок ширина их контейнера представляет собой 100%. Мы хотим, чтобы между колонками были отступы по 2%. Поскольку нам необходимы отступы только между первой и второй, а затем между второй и третьей, но не после 3-й колонки, то пространство контейнера следует разделить следующим образом: 100% - 4% margin = 96%. Далее 96%/3= 32% - получаем width каждой колонки. Затем используем это для свойств наших колонок с классом .col:
.col {
display: inline-block;
width: 32%;
margin-right: 2%;
margin-bottom: 20px;
padding: 0 15px;
background-color: #fff;
}
.col:last-child { margin-right: 0;}
Обязательно нужно отключить правый margin для последней колонки, что мы и сделали с помощью псевдокласса :last-child.
И вот, что мы получим в итоге:
Вуа-ля - и нет 3-х колонок, которые выстроились в одну линию. Вместо этого есть 2 колонки в одном ряду + одна в нижнем ряду. Совсем не то, что нужно. В чем же причина "сваливания" последней колоки?
Дело в том, что поскольку display: inline-block предполагает все-таки частично строчное размещение текста, то в конце каждой колонки у нас образуется еще один пробельный символ, в который превращаются все знаки в HTML (пробелы, табуляция, переносы слов), в каком бы количестве они не встречались в тексте. Именно этот пробельный символ, размер которого зависит от размера шрифта, и добавляет нам несколько пикселей между колонками, которые "выбивают" третью из них вниз.
Чтобы этого избежать, имеет смысл воспользоваться функцией calc(), которая появилась в стандарте CSS3 и давно уже поддерживается современными браузерами. Важным моментом в ее использовании является установка пробелов ДО и ПОСЛЕ знака минус:
.col {
display: inline-block;
width: calc(32% - 3px);
margin-right: 2%;
margin-bottom: 20px;
padding: 0 15px;
background-color: #fff;
}
Результат уже намного лучше:
Для того чтобы колонки с разным количеством текста не выбивались из одной линии, необходимо использовать свойство vertical-align чаще всего со значением top. Добавим его к нашим css-свойствам:
.col {
display: inline-block;
vertical-align: top;
width: calc(32% - 3px);
margin-right: 2%;
margin-bottom: 20px;
padding: 0 15px;
background-color: #fff;
}
В результате получим колонки разной высоты, но выровненные по верхней линии:
Если в блоке я напишу так:
link
...
и поставлю для блока text-align: center, то ссылка и список станут по центру, хотя ссылка - это inline-элемент, а список - блочный. Почему так?
Дело в том, что в любом блочном элементе (список в вашем примере), для которого задан
text-align: center, текст будет выравниваться по центру. Именно это вы и видите. Если элемент, которому заданdisplay: block, нетекстовый - картинка, например, тоtext-align: centerдля родительского элемента никакого влияния на вложенный элемент не окажет.Пробуйте сами: ссылка на codepen.io.
Спасибо. Все очень понятно расписано