position: absolute на одном примере
Абсолютно позиционированный элемент извлекается из обычного потока и размещается через top, right, bottom и left. Эти смещения отсчитываются от ближайшего предка, у которого position не static, поэтому родителю задают position: relative:
Удалите position: relative у .card, и бейдж прыгнет в правый верхний угол всей страницы, потому что у него больше нет позиционированного предка. Эта одна строка объясняет большинство вопросов «не работает position absolute».
Что нужно знать об абсолютных элементах:
- Они не занимают места. Заголовок и абзац размещены так, будто бейджа нет.
- Их ширина сжимается по содержимому, если не задать
widthили сразуleftиright. - Смещения отсчитываются от края padding содержащего блока, внутри его рамки.
Пять значений position
| Значение | В потоке? | Смещения отсчитываются от | Типичное применение |
|---|---|---|---|
static (по умолчанию) | Да | Смещения игнорируются | Обычные элементы |
relative | Да, место сохраняется | Собственного обычного положения | Опора для абсолютных дочерних элементов, небольшие сдвиги |
absolute | Нет | Ближайшего позиционированного предка (или страницы) | Бейджи, подсказки, наложения, кнопки закрытия |
fixed | Нет | Окна просмотра | Шапки, кнопки чата, плашки cookie |
sticky | Да | Контейнера прокрутки, когда элемент доходит до смещения | Заголовки таблиц, заголовки разделов, боковые панели |
position: relative
Относительно позиционированный элемент остается на своем месте в потоке. Смещения меняют место, где он рисуется, но его исходное место остается зарезервированным, поэтому ничего вокруг не сдвигается:
Блок 2 нарисован на 20px ниже и на 20px правее и перекрывает блок 3, но блок 3 не сдвинулся: он по-прежнему оставляет место для блока 2 в исходной позиции. Сам по себе relative редко используют для перемещения; его главная задача быть опорным блоком для абсолютных дочерних элементов.
Смещения и inset
top, right, bottom и left принимают длины, проценты (от содержащего блока) и auto. Сокращенное свойство inset задает все четыре в том же порядке, что и margin:
.overlay {
position: absolute;
inset: 0; /* top: 0; right: 0; bottom: 0; left: 0; */
}
.corner {
position: absolute;
inset: auto 16px 16px auto; /* bottom right corner, 16px in */
}
Если задать противоположные стороны, элемент растягивается: left: 0; right: 0 делает его шириной с содержащий блок. inset: 0 у абсолютного дочернего элемента это стандартный способ накрыть карточку наложением.
Центрирование через absolute и transform
top: 50%; left: 50% ставит левый верхний угол элемента в центр. translate(-50%, -50%) затем сдвигает его назад на половину собственного размера:
Flexbox и grid центрируют проще, если элемент может оставаться в потоке; все способы сравниваются на странице выравнивание div по центру.
position: fixed
Фиксированный элемент размещается относительно окна просмотра и остается на месте при прокрутке страницы:
.chat-button {
position: fixed;
bottom: 16px;
right: 16px;
}
Два подвоха. Фиксированный элемент не занимает места, поэтому фиксированная шапка закрывает верх страницы, если не добавить body padding-top. А если у любого предка есть transform, filter или perspective, опорным блоком становится этот предок, а не окно просмотра, и элемент прокручивается вместе с ним.
position: sticky
Липкий элемент прокручивается как обычно, пока не дойдет до своего смещения, а затем прилипает там, пока конец его родителя не уйдет за край. Прокрутите блок ниже:
Каждая буква прилипает к верху блока прокрутки, пока виден ее раздел, а затем ее выталкивает следующая, потому что липкий элемент никогда не покидает своего родителя.
Если sticky не прилипает, проверьте:
- Нет смещения.
position: stickyничего не делает безtop,bottom,leftилиright. - Предок с
overflow: hidden,autoилиscroll. Он становится контейнером прокрутки, и если он на самом деле не прокручивается, ничего не прилипает. Используйтеoverflow: clip, если нужно только скрыть переполнение. - Родитель не выше липкого элемента. Внутри него негде прилипать.
- Flex- или grid-родитель растягивает его. Во flex-строке добавьте липкой боковой панели
align-self: flex-start.
Частые ошибки
- Забытый
position: relativeу родителя абсолютного элемента. - Absolute для раскладки страницы. Абсолютные элементы игнорируют друг друга и содержимое, поэтому на маленьких экранах текст наезжает. Для раскладки используйте flexbox или grid, а absolute для небольших украшений.
- Смещения у статичного элемента.
top: 10pxничего не делает безposition. - Споры о том, какой элемент сверху. Порядок перекрывающихся позиционированных элементов задает z-index.
- Фиксированная шапка скрывает содержимое. Добавьте странице padding или
scroll-padding-top, чтобы ссылки-якоря не прятались под шапкой.
Часто задаваемые вопросы
Что делает position: absolute?
Убирает элемент из обычного потока (остальные элементы ведут себя так, будто его нет) и размещает его через top, right, bottom и left, отсчитывая от содержащего блока: ближайшего предка, у которого position не static.
Как спозиционировать элемент абсолютно относительно родителя?
Задайте родителю position: relative;, а дочернему элементу position: absolute; со смещениями вроде top: 0; right: 0;. Без позиционированного родителя дочерний элемент размещается относительно страницы.
Чем position relative отличается от absolute?
relative оставляет элемент в потоке и только сдвигает место, где он рисуется, сохраняя его исходное место. absolute убирает его из потока и размещает относительно позиционированного предка.
Почему не работает position: sticky?
Обычно по одной из трех причин: не задан top (или другое смещение), у предка overflow: hidden или auto, и он становится контейнером прокрутки, или родитель липкого элемента не выше самого элемента, так что прилипать негде.
Чем fixed отличается от sticky?
fixed убирается из потока и закрепляется относительно окна просмотра (если только у предка нет transform или filter). sticky остается в потоке и прокручивается как обычно, пока не дойдет до своего смещения, а затем прилипает, пока его родитель еще на экране.