display: inline-block
Иногда возникает необходимость расположить в ряд несколько элементов с заданными размерами. Строчные элементы для этого не подходят, т.к. не воспринимают размеры. Блочные элементы тоже не подходят, т.к. до и после них существует перенос строки. Конечно, блочные элементы можно приспособить для такой задачи, используя дополнительные свойства (которые будут разбираться в курсе про сетки).
Но более простой способ — использоватьблочно-строчныеэлементы. В HTML нет тегов, которые по умолчанию вели бы себя как блочно-строчные, но любой элемент можно переключить в данный режим, задав ему свойствоdisplayсо значениемinline-block.
Особенности блочно-строчных элементов:
- им можно задавать размеры, рамки и отступы, как и блочным элементам;
- их ширина по умолчанию зависит от содержания, а не растягивается на всю ширину контейнера;
- они не порождают принудительных переносов строк, поэтому могут располагаться на одной строке, пока помещаются в родительский контейнер;
- элементы в одной строке выравниваются вертикально подобно строчным элементам.
Блочно-строчные элементы ведут себя двояко. Снаружи они выглядят как обычные строчные, но внутри они ведут себя как блочные.
От строчных им достались следующие черты:
- по ширине они ужимаются под своё содержимое;
- могут располагаться в одну строку;
- реагируют на вертикальное выравнивание,
vertical-align; - реагируют на горизонтальное выравнивание,
text-align, заданное у родителя.
От блочных:
- им можно задавать размеры с помощью
widthиheight; - а также внешние и внутренние отступы и рамки, которые работают во всех направлениях и увеличивают размер элемента.
Блочно-строчные элементы очень часто используют для создания декоративных элементов: кнопок, плашек, блочков. Также благодаря их умному поведению с их помощью создают различные списки товаров в каталогах.
Для создания сеток страниц эти элементы используются реже. Первая причина заключается в том, что их не поддерживают старые браузеры, например, IE7 и младше. А сетка страницы — слишком критичная вещь, чтобы позволять ей ломаться даже в старых браузерах.
inline-block и пробелы в коде
Мы рассчитали всё правильно, однако по три товара в строку не помещается.
Причина заключается в пробелах после тэгов в HTML-коде. Блочно-строчные ведут себя как текст, поэтому если в коде есть пробел между элементами, то он отображается и на странице. Этот пробел увеличивает отступы между товарами, не давая им поместиться в одну строку.
Бороться с пробелом после блочно-строчных можно несколькими способами:
- удалять пробелы в коде;
- обнулять размер шрифта;
- играться с маргинами после блочно-строчного.
У каждого из способов есть свои недостатки, а подробнее эти и другие способы разбираются внашем переводе хорошей статьи(есть ещё более обширнаястатьяпро блочно-строчные).
Мы попробуем последние два способа.
Способ со шрифтом заключается в том, что мы задаём нулевой размер шрифта у контейнера инлайн-блоков, а самим инлайн-блокам задаём исходный размер шрифта. Способ не работает, если вы используете относительные размеры шрифта.
Способ с маргинами заключается в том, что мы уменьшаем отступ после инлайн-блока на ширину пробела, около4-5px. А если нам нужно, чтобы элементы стояли вплотную друг к другу, то задаём отрицательный отступ. Проблема с этим способом заключается в том, что размер пробела может быть разным в разных шрифтах и может изменяться при изменении размера шрифта.
Если применяется свойство стиля display: inline-block тогда желательно сразу указать vertical-alignчтобы избежать вот такого поведения:

все элементы inline-block, и по умолчанию vertical-align: baseline - в результате такое поведение (из-за этого под строчными элементами есть небольшой отступ - необходимый для шрифтов - "хвостиков" таких букв как "y"). Можно поменять на vertical-align: top и все будет как задумывалось
Еще одна особенность - между двумя соседними inline-block элементами могут возникнуть пробел.
<div class='container'>
<div class='text'>test1</div>
<div class='text'>test2</div>
</div>
в данном примере перенос строки добавляет пробел. Один из способов борьбы с этим - задать родительскому элементу font-size: 0, но тогда дочерним элементам нужно не забыть нужный размер строки.
margin: 0 auto - НЕ работает для inline-block