Как сделать, чтобы элемент с position absolute позиционировался относительно body в CSS
Что проверяют
Знаете ли вы, что такое containing block и от чего он на самом деле зависит. Следом обычно спрашивают, почему элемент внезапно привязался к карточке без position: relative и как вынести его из-под overflow: hidden.
Как отвечать
position: absolute отсчитывается от ближайшего предка, который создаёт containing block. Это предок с position, отличным от static, а ещё любой предок с transform, filter, perspective, will-change: transform или contain: paint. Если такого предка нет, отсчёт идёт от начального containing block: он размером с окно браузера и привязан к началу документа, а не к body.
Отсюда способы:
position: relativeуbodyи ни одного позиционированного предка между ним и элементом. Тогдаtopиleftсчитаются отbodyс учётом его стандартногоmargin, аbottom: 0окажется внизуbody, а не внизу первого экрана;- перенос в DOM: если элемент лежит внутри позиционированного контейнера, CSS его оттуда не вытащит. Узел переносят в конец
bodyскриптом или порталом (createPortalв React,Teleportво Vue); - верхний слой: для модалок, подсказок и меню лучше
<dialog>сshowModal()или атрибутpopover. Такие элементы попадают в top layer и не зависят ни от предков, ни отz-index; position: fixed: подходит, если нужна привязка к окну, а не к документу, но он тоже ломается о предка сtransform.
Где спотыкаются
Говорят, что без позиционированных предков элемент позиционируется относительно body. На длинной странице элемент с bottom: 0 встанет в конец первого экрана, а не документа.
Забывают про transform и filter. Анимация или размытие на обёртке меняет точку отсчёта, хотя position: relative там нигде нет.
Считают, что всё решит z-index: 9999. Если предок создал свой контекст наложения, элемент не поднимется выше соседей этого предка при любом значении.