Блочные и строчные элементы
Блочные элементы занимают всю доступную ширину и начинаются с новой строки. Строчные -- занимают только ширину своего содержимого и не разрывают строку.
Зачем нужно
Понимание блочной и строчной модели -- основа для работы с layout. От типа элемента зависит, как он ведёт себя в потоке документа: где переносится, какие размеры принимает, как реагирует на margin/padding.
Где используется
- Верстка любого HTML-документа
- Понимание CSS display
- Решение проблем с layout (элементы не встают в ряд, отступы не работают)
Предпосылки
Блочные элементы (block)
Блочный элемент:
- Начинается с новой строки
- Занимает 100% ширины родителя
- Можно задать
width,height,margin,paddingсо всех сторон - Может содержать другие блочные и строчные элементы
<!-- Каждый блочный элемент -- на новой строке -->
<div>Первый div (блочный)</div>
<div>Второй div (блочный)</div>
<p>Параграф (блочный)</p>
<h1>Заголовок (блочный)</h1>
Результат:
|Первый div (блочный) |
|Второй div (блочный) |
|Параграф (блочный) |
|Заголовок (блочный) |
Список блочных элементов
| Элемент | Назначение |
|---|---|
<div> |
Универсальный контейнер |
<p> |
Параграф |
<h1>...<h6> |
Заголовки |
<ul>, <ol>, <li> |
Списки |
<table> |
Таблица |
<form> |
Форма |
<header>, <footer>, <main> |
Семантические секции |
<section>, <article>, <aside> |
Семантические секции |
<nav> |
Навигация |
<blockquote> |
Блочная цитата |
<pre> |
Предформатированный текст |
<hr> |
Горизонтальная линия |
<figure>, <figcaption> |
Иллюстрация с подписью |
<details>, <summary> |
Раскрываемый блок |
<dialog> |
Диалоговое окно |
Строчные элементы (inline)
Строчный элемент:
- Не начинается с новой строки
- Занимает только ширину своего содержимого
widthиheightигнорируются- Вертикальные
marginигнорируются - Вертикальные
paddingвизуально работают, но не отодвигают соседей
<p>
Это <strong>жирный</strong> текст и <em>курсив</em>,
а вот <a href="#">ссылка</a> и <span>span</span>.
</p>
Результат:
Это жирный текст и курсив, а вот ссылка и span.
Все строчные элементы остались в одной строке.
Список строчных элементов
| Элемент | Назначение |
|---|---|
<span> |
Универсальный строчный контейнер |
<a> |
Ссылка |
<strong> |
Важный текст (жирный) |
<em> |
Акцент (курсив) |
<b> |
Визуально жирный (без семантики важности) |
<i> |
Визуально курсивный (технический термин, иностранное слово) |
<code> |
Код |
<kbd> |
Ввод с клавиатуры |
<mark> |
Выделение |
<small> |
Мелкий текст (копирайт, примечания) |
<sub>, <sup> |
Подстрочный / надстрочный |
<br> |
Перенос строки |
<wbr> |
Возможное место переноса |
<abbr> |
Аббревиатура |
<time> |
Дата/время |
<img> |
Изображение (inline-replaced) |
<input> |
Поле ввода (inline-replaced) |
<button> |
Кнопка (inline-replaced) |
<label> |
Метка формы |
<select>, <textarea> |
Элементы форм |
Inline-block
inline-block -- гибрид: элемент остаётся в строке, но принимает width, height и вертикальные margin/padding.
<style>
.badge {
display: inline-block;
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
background: #e0e0e0;
border-radius: 4px;
margin: 4px;
}
</style>
<span class="badge">HTML</span>
<span class="badge">CSS</span>
<span class="badge">JS</span>
Результат: три бейджа в ряд, каждый с фиксированными размерами.
Сравнение block, inline, inline-block
<style>
.block {
display: block;
width: 200px;
height: 50px;
margin: 10px;
padding: 10px;
background: lightblue;
}
.inline {
display: inline;
width: 200px; /* ИГНОРИРУЕТСЯ */
height: 50px; /* ИГНОРИРУЕТСЯ */
margin: 10px; /* Вертикальный ИГНОРИРУЕТСЯ */
padding: 10px; /* Вертикальный визуально работает, но не отодвигает */
background: lightgreen;
}
.inline-block {
display: inline-block;
width: 200px; /* Работает */
height: 50px; /* Работает */
margin: 10px; /* Работает полностью */
padding: 10px; /* Работает полностью */
background: lightyellow;
}
</style>
<div class="block">Block</div>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<br><br>
<span class="inline-block">Inline-block</span>
<span class="inline-block">Inline-block</span>
| Свойство | block |
inline |
inline-block |
|---|---|---|---|
| Новая строка | Да | Нет | Нет |
| width/height | Работает | Игнорируется | Работает |
| margin (верт.) | Работает | Игнорируется | Работает |
| margin (гориз.) | Работает | Работает | Работает |
| padding (верт.) | Работает | Визуально да, не отодвигает | Работает |
| Содержит block | Да | Нет* | Да |
*Исключение: <a> может содержать блочные элементы в HTML5.
Поток документа (document flow)
Нормальный поток -- как браузер размещает элементы без CSS-позиционирования:
+--------------------------------------------------+
| <header> (block) |
+--------------------------------------------------+
| <nav> (block) |
+--------------------------------------------------+
| <main> (block) |
| <h1>Заголовок</h1> (block) |
| <p> (block) |
| Текст <a>ссылка</a> ещё текст (inline) |
| <strong>важное</strong> (inline) |
| </p> |
| <p>Другой параграф</p> (block) |
| </main> |
+--------------------------------------------------+
| <footer> (block) |
+--------------------------------------------------+
Блочные элементы укладываются вертикально (сверху вниз). Строчные -- горизонтально (слева направо, с переносом).
Изменение поведения через CSS display
Любой элемент можно "переключить":
<style>
/* Строчный элемент ведёт себя как блочный */
.block-link {
display: block;
padding: 10px;
background: #f0f0f0;
}
/* Блочный элемент ведёт себя как строчный */
.inline-heading {
display: inline;
}
/* Список горизонтально */
.horizontal-list li {
display: inline-block;
margin-right: 10px;
}
</style>
<a href="#" class="block-link">Ссылка во всю ширину</a>
<h2 class="inline-heading">Заголовок</h2>
<h2 class="inline-heading">рядом</h2>
<ul class="horizontal-list">
<li>Пункт 1</li>
<li>Пункт 2</li>
<li>Пункт 3</li>
</ul>
Современные значения display
/* Основные */
display: block;
display: inline;
display: inline-block;
display: none; /* Убирает из потока */
/* Флексбокс */
display: flex; /* Блочный flex-контейнер */
display: inline-flex; /* Строчный flex-контейнер */
/* Грид */
display: grid; /* Блочный grid-контейнер */
display: inline-grid; /* Строчный grid-контейнер */
/* Другие */
display: contents; /* Убирает обёртку, дети в потоке родителя */
display: flow-root; /* Создаёт новый BFC (block formatting context) */
Правила вложенности
<!-- МОЖНО: блочный в блочном -->
<div>
<p>Параграф</p>
</div>
<!-- МОЖНО: строчный в блочном -->
<p>Текст <strong>жирный</strong></p>
<!-- МОЖНО (HTML5): блочный в <a> -->
<a href="/article">
<article>
<h2>Заголовок</h2>
<p>Описание</p>
</article>
</a>
<!-- НЕЛЬЗЯ: блочный в строчном (кроме <a>) -->
<!-- Невалидно: -->
<span>
<div>Блок внутри span</div>
</span>
<!-- НЕЛЬЗЯ: <p> в <p> -->
<!-- Браузер автоматически закроет первый <p> -->
<p>Первый <p>Второй</p>
<!-- Станет: <p>Первый</p><p>Второй</p> -->
Частые ошибки
| Ошибка | Почему плохо | Как правильно |
|---|---|---|
width на inline-элементе |
Игнорируется | Переключи на inline-block или block |
Вертикальный margin на inline |
Не работает | Используй inline-block |
<div> внутри <span> |
Невалидная вложенность | Блочный -- только в блочном |
<p> внутри <p> |
Браузер принудительно закроет первый | Используй <div> или <section> |
| Пробелы между inline-block | Нежелательные зазоры между элементами | font-size: 0 на родителе или flex |
| Забывают про replaced elements | <img>, <input> -- inline, но принимают размеры |
Это inline-replaced, особая категория |
Практика
- Создай три
<div>и три<span>-- увидь разницу в поведении - Попробуй задать
width: 200pxдля<span>-- убедись, что не работает - Переключи
<span>наdisplay: inline-blockи повтори - Создай горизонтальное меню из
<ul>сli { display: inline-block; } - Попробуй вложить
<div>в<span>-- проверь валидатором
Связанные темы
- Семантическая разметка -- выбор правильных элементов
- Теги и атрибуты -- синтаксис HTML
- Параграфы и контейнеры -- div, span, p в деталях