Display и позиционирование
Зачем это нужно
До сих пор элементы шли друг за другом сверху вниз — это нормальный поток документа.
Но на настоящих сайтах меню стоит в строку, значок «−20%» висит в углу карточки, кнопка чата
не уезжает при прокрутке, а окно входа появляется поверх страницы. Всё это делают свойства
display и position.
display: как элемент встаёт в поток
.a { display: block; }
.b { display: inline; }
.c { display: inline-block; }
.d { display: none; }
| Значение | Как ведёт себя | Кто такой по умолчанию |
|---|---|---|
block |
с новой строки, на всю ширину; width, height, margin работают |
div, p, h1, ul, li |
inline |
внутри строки, как слово; width и height не работают |
span, a, strong, img |
inline-block |
в строке, как слово, но размеры и отступы работают | button, input |
none |
элемента нет: не виден и не занимает места | head, script |
<style>
a { display: inline-block; padding: 10px 20px; background: gold; }
</style>
<a href="#">Купить</a> <a href="#">В корзину</a>
Результат: две жёлтые кнопки рядом. С обычным inline padding сверху и снизу наехал бы на соседние строки.
display: none используют, чтобы прятать элементы (меню на телефоне, окно до нажатия кнопки).
А visibility: hidden прячет элемент, но оставляет пустое место под него.
position: где стоит элемент
| Значение | От чего отсчитывается | Уходит из потока? |
|---|---|---|
static |
обычное положение (по умолчанию) | нет |
relative |
от своего обычного места | нет, место остаётся |
absolute |
от ближайшего предка с position не static |
да |
fixed |
от окна браузера; не двигается при прокрутке | да |
sticky |
обычный, но «прилипает» при прокрутке | нет |
Положение задают top, right, bottom, left — расстояние от соответствующего края.
relative
.shift { position: relative; top: 10px; left: 20px; }
Результат: элемент сдвинут на 10px вниз и 20px вправо, а на старом месте осталась «дырка».
Сам по себе relative нужен редко — чаще его ставят родителю, чтобы внутри работал absolute.
absolute
<style>
.photo { position: relative; width: 200px; height: 150px; background: #ddd; }
.sale { position: absolute; top: 0; left: 0; background: red; color: white; }
</style>
<div class="photo">
<span class="sale">−20%</span>
</div>
Результат: красная плашка «−20%» в левом верхнем углу серого блока.
Важно: absolute ищет ближайшего предка с position: relative (или absolute, fixed, sticky).
Если такого нет — отсчёт пойдёт от всей страницы, и значок улетит в угол экрана.
fixed
.up { position: fixed; right: 20px; bottom: 20px; }
Результат: кнопка всегда в правом нижнем углу окна, что бы ни прокручивал пользователь. Так делают кнопки «Наверх», чаты поддержки, баннеры cookie.
sticky
.header { position: sticky; top: 0; background: white; }
Результат: шапка едет вместе со страницей, но, дойдя до верха окна, «прилипает» и остаётся там.
Без top sticky не работает: браузеру нужно знать, где прилипать.
z-index: кто сверху
Когда элементы перекрываются, сверху оказывается тот, у кого больше z-index
(работает только у позиционированных элементов — не static):
.modal { position: fixed; z-index: 100; }
.chat { position: fixed; z-index: 10; }
Результат: окно перекроет кнопку чата. Представь стопку листов: z-index — номер листа сверху.
Как это работает внутри
Браузер сначала раскладывает все элементы обычного потока сверху вниз. Элементы с absolute
и fixed он «вынимает» из потока — соседи их не видят и сдвигаются на освободившееся место.
Затем вынутые элементы рисуются по своим координатам поверх остальных, по порядку z-index.
Частые ошибки
widthуinline. У<span>и<a>размеры не работают — нуженinline-blockилиblock.- Забыли
relativeу родителя.absolute-значок улетает в угол страницы. z-index«не работает». У элементаposition: static— z-index не действует. Добавьposition: relative.stickyбезtop. Ничего не прилипает.- Вёрстка целиком на
absolute. На другом размере экрана всё наедет друг на друга. Для раскладки используй Flexbox и Grid (следующие темы), аabsolute— для мелочей вроде значков.
Шпаргалка
| Код | Что делает |
|---|---|
display: block / inline / inline-block |
как встаёт в поток |
display: none |
убрать элемент совсем |
visibility: hidden |
спрятать, оставив место |
position: relative |
сдвиг от своего места; «якорь» для absolute |
position: absolute |
от ближайшего позиционированного предка |
position: fixed |
от окна, не двигается при прокрутке |
position: sticky; top: 0 |
прилипает при прокрутке |
top / right / bottom / left |
координаты |
z-index |
кто сверху |