Абсолютное позиционирование

position: absolute убирает элемент из обычного потока документа и позиционирует его относительно ближайшего предка с непустым position - а если такого предка нет, относительно всей страницы. Место под ним не резервируется, а размер по умолчанию - по содержимому, а не на весь родитель.

Попробуй прямо сейчас: убери у .card строку position: relative - оба absolute-блока "выпрыгнут" из карточки и спозиционируются уже относительно всей страницы.

Как уже говорилось в обзорном уроке про position и уроке про relative, absolute-элемент ищет точку отсчёта, поднимаясь вверх по дереву предков, пока не найдёт первый с непустым position (relative, absolute, fixed или sticky). Если такого предка нет вообще - точкой отсчёта становится вся страница. Но есть менее очевидное исключение: даже обычный, "непозиционированный" предок (со static) станет точкой отсчёта, если у него задан transform, filter или perspective, отличный от none - это частая причина неожиданного поведения absolute в реальных проектах.

.card { position: relative; } - явный и предсказуемый способ сделать родителя точкой отсчёта.

.card { transform: scale(1); } без осознания последствий - такой transform "случайно" превращает .card в точку отсчёта для всех absolute-потомков, даже если сам разработчик хотел просто применить трансформацию, а не менять контекст позиционирования.

Место не резервируется, размер - по содержимому

Как и у fixed, место absolute-элемента в обычном потоке НЕ резервируется - соседи ведут себя так, будто его там никогда не было (в отличие от relative, где место остаётся). А без явных width и height absolute-элемент по умолчанию занимает размер по своему содержимому, а не растягивается на всю ширину или высоту родителя, как это делает обычный блочный элемент.

Есть удобное исключение: если задать ОБА противоположных отступа на одной оси - например, и top, и bottom - а размер по этой оси оставить auto, элемент растянется и заполнит всё расстояние между ними.

position: absolute; top: 0; bottom: 0; width: 40px; - высота элемента растянется на всю доступную высоту родителя, а ширина останется 40px.

position: absolute; без width, ожидая, что элемент растянется на всю ширину родителя, как обычный div - absolute без явных offset'ов на обеих сторонах оси остаётся по размеру содержимого.

margin: auto и все отступы в 0 - центрирование

Классический приём для центрирования absolute-элемента с известными width и height: задать все четыре отступа в 0 (короткая запись - inset: 0, то есть top/right/bottom/left: 0 сразу) и margin: auto. Браузер распределит свободное место поровну со всех сторон - элемент окажется точно по центру родителя, причём по обеим осям сразу, без вычисления точных пикселей вручную.

position: absolute; inset: 0; margin: auto; width: 100px; height: 60px; - элемент 100×60px окажется точно по центру родителя.

position: absolute; top: 0; margin: auto; без right/bottom/left - для этого трюка нужны отступы со ВСЕХ четырёх сторон (или хотя бы противоположной пары на каждой оси), иначе margin: auto не сработает как центрирование.

Из истории В конце 1990-х - начале 2000-х position:absolute (наравне с float) был одним из главных инструментов движения "tableless" - отказа от вёрстки HTML-таблицами, которую до этого продвигал Дэвид Сигел в книге "Creating Killer Web Sites". Спецификация CSS2 с расширенным позиционированием вышла в мае 1998-го, но массовый переход занял ещё годы: в феврале 2001-го The Web Standards Project запустил кампанию за обновление браузеров, в 2002-м на CSS перешёл сайт журнала Wired, а в 2003-м вышел CSS Zen Garden - проект, который по общему признанию популяризировал вёрстку без таблиц. Сегодня для целых макетов страниц absolute почти не используют - эту роль давно забрали Flexbox и Grid, а position:absolute чаще применяют точечно, как в этом уроке - для бейджей, тултипов и модальных окон.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Не подозревают, что transform/filter у предка тоже создаёт точку отсчёта absolute-потомок неожиданно позиционируется не от страницы, а от предка с transform Проверять, нет ли у предков transform/filter/perspective, если позиционирование "странно" работает
Ждут, что absolute без width растянется на весь родитель Элемент остаётся по размеру содержимого, а не растягивается Задать width явно или использовать offset'ы с обеих сторон оси (например, left и right)
Пытаются центрировать через margin: auto без всех нужных отступов Центрирование не срабатывает - margin: auto нужно распределяемое свободное место Задать все четыре отступа (inset: 0) вместе с явными width и height
Забывают, что место absolute-элемента в потоке не резервируется Соседние элементы "не видят" absolute-элемент и сдвигаются, как будто его нет Использовать position: relative, если нужно сохранить место в разметке

Шпаргалка

Что нужноКак сделать
Точка отсчёта для absolute-потомковposition: relative; у родителя
Растянуть по одной оси между двумя краямиtop: 0; bottom: 0; (height остаётся auto)
Центрировать по обеим осямinset: 0; margin: auto; + явные width/height
Позиционировать в углу карточкиposition: absolute; top: 8px; right: 8px;
Случайная точка отсчёта, о которой легко забытьtransform/filter/perspective ≠ none у предка

Коротко: отвечаем на вопросы

Почему у absolute-элемента без width он не растягивается на весь родитель?

По умолчанию absolute-элемент занимает размер по своему содержимому, а не по родителю - это отличает его от обычного блочного элемента. Растянуть можно, задав явный width/height или offset'ы с обеих сторон одной оси (например, left: 0 и right: 0 растянут элемент по ширине).

Как отцентровать absolute-элемент через margin: auto?

Нужно задать все четыре отступа в 0 (inset: 0, то есть top/right/bottom/left: 0) вместе с явными width и height, и добавить margin: auto - браузер распределит свободное место поровну со всех сторон, и элемент окажется точно по центру родителя по обеим осям.

Может ли непозиционированный элемент стать точкой отсчёта для absolute-потомка?

Да, если у него задан transform, filter или perspective, отличный от none - даже при position: static такой предок становится точкой отсчёта, как будто у него был relative. Это частая причина неожиданного поведения absolute в реальных проектах.

Категория
css
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×