display: block растягивает элемент на всю ширину и переносит соседей на новую строку; display: inline не переносит строку и игнорирует width, height и вертикальные отступы; display: inline-block совмещает оба поведения - стоит в строке, но при этом уважает размеры и отступы, как блочный элемент.
В этом уроке
Попробуй прямо сейчас: у .inline тоже задан width: 200px - но браузер его полностью проигнорирует, а вот у .inline-block такой же width сработает как надо.
display: block - вся ширина и новая строка
Блочный элемент (div, p, h1-h6, ul, li и другие по умолчанию) занимает всю доступную ширину родителя, если не задать width явно, и всегда начинается с новой строки - следующий элемент после него уже не может встать рядом. Vertical margin и padding у блочного элемента работают полностью: сверху и снизу, как и слева-справа.
display: block; width: 100px; - блок сузится до 100px, ширину блочного элемента задавать можно и нужно, если требуется не на всю ширину.
display: block; без width, ожидая, что элемент "сам подстроится под контент" - блочный элемент без явной ширины растягивается на ВСЮ ширину родителя, а не по содержимому.
display: inline - в потоке текста, без width и height
Строчный элемент (span, a, strong, em и другие по умолчанию) стоит в общем потоке текста, не переносится на новую строку сам и не переносит следующий за ним элемент. Но у него есть важное ограничение: свойства width и height НЕ РАБОТАЮТ - размер строчного элемента всегда определяется только его содержимым, сколько бы пикселей ни было указано в width. Вертикальные margin и padding тоже не влияют на расположение соседних строк - можно задать margin-top: 50px, но соседние элементы не сдвинутся ни на пиксель.
display: inline; без попыток задать width/height - для строчного текста внутри абзаца или ссылки это ожидаемое и единственно рабочее поведение.
display: inline; width: 300px; height: 200px;, ожидая элемент нужного размера - у строчного элемента width и height полностью игнорируются браузером; в разметке результат будет ровно по размеру содержимого, а не 300×200px.
display: inline-block - строка снаружи, блок внутри
inline-block - компромисс: снаружи элемент ведёт себя как строчный (стоит в строке рядом с соседями, не переносит их), а внутри - как блочный (width, height и вертикальные margin/padding работают полностью, как у обычного div). Это удобно для кнопок, карточек в ряд или пунктов меню, которые должны стоять бок о бок, но иметь заданный размер.
Есть характерная особенность: если между двумя inline-block элементами в HTML-коде есть пробел или перенос строки (а обычно они там есть - просто ради читаемости кода), между элементами на странице появляется небольшой видимый зазор - браузер воспринимает этот пробел как настоящий пробел в тексте. Убрать зазор можно, написав теги вплотную друг к другу без пробела в коде, либо задав родителю font-size: 0.
display: inline-block; width: 120px; - элемент получит именно эту ширину и встанет в строку рядом с соседними inline-block элементами.
А Б с display: inline-block у обоих, но не подозревая про зазор - пробел между тегами в коде добавит лишнее расстояние между блоками на странице, из-за которого вёрстка "не сходится" на пиксель.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Задают width и height строчному элементу (display: inline) | Оба свойства полностью игнорируются, размер остаётся по содержимому | Использовать display: inline-block или display: block, если размер важен |
| Ждут, что margin-top/bottom у inline-элемента сдвинет соседние строки | Вертикальные отступы у inline-элемента не влияют на расположение соседей | Переключить элемент на inline-block или block, если нужен реальный вертикальный отступ |
| Не понимают, откуда взялся зазор между inline-block элементами | Пробел или перенос строки между тегами в HTML-коде превращается в видимый зазор на странице | Убрать пробел между тегами в коде или задать родителю font-size: 0 |
| Забывают, что блочный элемент без width занимает всю ширину родителя | Элемент "не по размеру контента", хотя это ожидаемое поведение блочных элементов | Задать width явно или переключить на inline-block, если нужна ширина по контенту |
Шпаргалка
| Что нужно | Как сделать |
|---|---|
| Элемент на всю ширину, с новой строки | display: block; |
| Элемент в потоке текста, без своих width/height | display: inline; |
| Элемент в строке, но с заданными размерами | display: inline-block; |
| Убрать зазор между inline-block элементами | Убрать пробел между тегами в HTML или font-size: 0 у родителя |
| Вертикальный отступ, который реально сдвигает соседей | display: block; или display: inline-block; вместо inline |
Коротко: отвечаем на вопросы
Почему у inline-элемента не работают width и height?
Так устроена сама модель отображения inline: размер строчного элемента всегда определяется его содержимым - объёмом текста или вложенных элементов, а не заданными числами. Чтобы задать точный размер, нужно переключить элемент на display: inline-block или display: block.
Откуда берётся зазор между соседними inline-block элементами?
Из пробела или переноса строки между тегами в самом HTML-коде - браузер воспринимает его как обычный текстовый пробел и рисует между блоками. Избавиться можно, написав теги вплотную друг к другу в коде без пробела, либо задав font-size: 0 родительскому элементу.
Чем display: inline-block отличается от display: block?
У обоих работают width, height и вертикальные margin/padding. Разница - в переносе строки: block всегда начинается с новой строки и не даёт соседям встать рядом, а inline-block остаётся в общем потоке строки, как обычный текст, и может стоять рядом с другими inline или inline-block элементами.