Поток документа и display
Почему одни элементы занимают всю строку, а другие стоят рядом, что делает inline-block и чем display: none отличается от visibility: hidden.
Что ты научишься делать
- Объяснишь, почему заголовок занимает всю строку, а ссылка — нет
- Поймёшь, какие свойства не действуют на строчные элементы
- Сверстаешь горизонтальное меню без флексов — и почувствуешь, зачем они нужны
#Поток: элементы становятся в очередь
Пока ты ничего не задал, браузер расставляет элементы сам, сверху вниз и слева направо. Это называется нормальный поток.
Как именно элемент встаёт в этот поток, зависит от значения display. По умолчанию оно у каждого тега своё, и его-то мы и будем менять.
#Блочные и строчные
| Блочные (block) | Строчные (inline) | |
|---|---|---|
| Примеры | div, p, h1, section, ul | span, a, strong, em, img |
| Занимают | Всю доступную ширину | Ровно столько, сколько нужно содержимому |
| Начинаются | С новой строки | Продолжают текущую строку |
width, height | Работают | Не работают |
Вертикальные margin, padding | Работают | Padding рисуется, но не раздвигает строку |
| Горизонтальные отступы | Работают | Работают |
#inline-block: компромисс
display: inline-block берёт лучшее от обоих: элемент остаётся в строке рядом с соседями, но при этом слушается width, height и вертикальных отступов.
Это классический способ сделать кнопку из ссылки: a строчный, а кнопке нужны отступы.
.btn { display: inline-block; padding: 12px 24px; background: #6544e0; color: #fff; border-radius: 999px; text-decoration: none;}#Основные значения display
| Значение | Что делает |
|---|---|
block | Занимает всю ширину, начинается с новой строки |
inline | Живёт внутри строки, размеры не задаются |
inline-block | В строке, но с размерами и отступами |
none | Элемента нет вообще: он не занимает места |
flex | Делает элемент флекс-контейнером — двадцатый урок |
grid | Делает элемент грид-контейнером — двадцать первый урок |
list-item | Как блок, но с маркером списка |
#none, hidden и прозрачность
Три способа «спрятать» элемент — и все три разные.
| Способ | Занимает место? | Читает голосовая программа? | Кликается? |
|---|---|---|---|
display: none | Нет | Нет | Нет |
visibility: hidden | Да | Нет | Нет |
opacity: 0 | Да | Да | Да |
Атрибут hidden | Нет | Нет | Нет |
Класс .visually-hidden | Почти нет | Да | Да |
/* Текст не виден, но программа чтения его прочитает. Нужен для подписей к иконкам и невидимых заголовков. */.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;}#overflow: что делать с тем, что не влезло
Если содержимое больше блока, по умолчанию оно просто вылезает наружу. overflow задаёт другое поведение.
#Меню без флексов: почувствуй боль
Задача простая: поставить пункты меню в строку. Флексов у нас пока нет — сделаем на inline-block.
Работает — но с оговорками. Разметку пришлось писать без переносов строк, иначе появятся зазоры. Прижать последний пункт вправо нечем. Выровнять пункты разной высоты по центру — тоже. Расстояние между ними задаётся отступами у каждого, а не одним свойством.
Всё это решает одна строка display: flex. Через три урока ты вернёшься к этому меню и перепишешь его за минуту.
Где спотыкаются почти все
Заданы width и height строчному элементу
Почему Свойства просто игнорируются. Человек видит, что «CSS не работает», и начинает искать ошибку не там.
Как надо Добавь display: inline-block или display: block — и размеры заработают.
Элемент спрятан через opacity: 0
Почему Он остаётся на месте: перекрывает клики и читается голосовой программой.
Как надо Действительно спрятать — display: none. Спрятать только визуально, оставив для голоса, — класс .visually-hidden.
Между inline-block элементами появились зазоры
Почему Переносы строк в разметке браузер считает пробелами и рисует их.
Как надо Не бороться, а перейти на флексы. Там пробелы между элементами не появляются вовсе.
overflow: hidden поставлен «чтобы не вылезало»
Почему Обрезается не только лишнее: пропадают тени, всплывающие подсказки и выпадающие меню внутри блока.
Как надо Сначала разберись, почему содержимое не помещается. Обрезка — крайняя мера.
- Нормальный поток normal flow
- Порядок, в котором браузер расставляет элементы по умолчанию: сверху вниз, слева направо.
- Блочный элемент block
- Занимает всю ширину строки, начинается с новой строки, слушается размеров.
- Строчный элемент inline
- Живёт внутри строки, размеры к нему не применяются.
- inline-block inline-block
- В строке, но с размерами и вертикальными отступами.
- overflow overflow
- Что делать с содержимым, которое не помещается: показать, обрезать или прокручивать.
Проверь себя
Строчный элемент занимает столько места, сколько нужно содержимому. Чтобы задать размеры, поменяй <code>display</code>.
<code>none</code> убирает элемент из потока полностью, <code>hidden</code> оставляет пустое место на его размер.
Приём с размером 1×1 пиксель и обрезкой убирает текст с экрана, но оставляет его в дереве доступности.
Строчные элементы разделяются пробельными символами так же, как слова в предложении.
<code>auto</code> показывает полосу только при необходимости. <code>scroll</code> рисует её всегда.
Задание
Горизонтальное меню без флексов
Собери меню в строку, не используя display: flex и grid. Условия:
- пункты стоят в одну строку;
- маркеры списка убраны;
- у ссылок внутренние отступы не меньше 10px по вертикали и 16px по горизонтали;
- ссылки без подчёркивания;
- при наведении у ссылки меняется фон.
Подсказка 1
Чтобы вертикальные отступы у ссылки заработали, ей тоже нужен display: inline-block.
Подсказка 2
Маркеры убираются у самого списка: .menu { list-style: none; padding: 0; }
Показать решение
<ul class="menu"><li><a href="#">Главная</a></li><li><a href="#">Меню</a></li><li><a href="#">О нас</a></li><li><a href="#">Контакты</a></li></ul>.menu { padding: 0; list-style: none;}.menu li { display: inline-block;}.menu a { display: inline-block; padding: 10px 16px; color: #333; text-decoration: none; border-radius: 8px;}.menu a:hover { background: #eceaff;}