Фиксированное позиционирование

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

Попробуй прямо сейчас: прокрути блок с рамкой внутри блокнота — кнопка "Наверх" останется в том же углу, хотя содержимое блока уедет вверх.

Привязка к окну просмотра: что происходит при прокрутке

fixed отсчитывает top/right/bottom/left от краёв окна просмотра (viewport), а не от какого-либо блока в разметке - в этом его ключевое отличие от absolute. При прокрутке страницы координаты fixed-элемента на экране не меняются вообще: он не "уезжает" вместе с контентом, а остаётся точно на том же месте. Это же поведение приводило к болезненной истории на мобильных устройствах - в обзорном уроке про position уже рассказывалось, что десктопный IE5.5/6 вообще не поддерживал fixed, но и после того, как эта проблема решилась, на мобильных всё повторилось заново с большими багами.

position: fixed; bottom: 20px; right: 20px; - классическая кнопка "наверх", которая всегда на виду, независимо от прокрутки.

position: absolute; bottom: 20px; right: 20px;, ожидая, что кнопка останется на экране при прокрутке - absolute отсчитывается не от viewport, а от ближайшего позиционированного предка (или страницы), и при прокрутке "уедет" вместе с контентом.

Исключение: transform, filter и perspective у предка

Как и у absolute из прошлого урока, здесь есть то же самое исключение: если у ЛЮБОГО предка fixed-элемента задан transform, filter или perspective, отличный от none, - точкой отсчёта становится именно ЭТОТ предок, а не окно просмотра. Это работает, даже если у самого предка position: static - в этом случае fixed фактически ведёт себя как absolute внутри такого предка. Такая ситуация - частая и неожиданная причина того, что "прилипший" элемент вдруг перестаёт быть прилипшим и начинает уезжать вместе со страницей.

position: fixed; у элемента вне блоков с анимациями/transform - предсказуемо привязан к окну просмотра.

.page-wrapper { transform: translateZ(0); } на всей странице (частый приём для аппаратного ускорения анимаций) с вложенным fixed-элементом внутри - fixed внутри такого wrapper'а перестанет быть привязанным к экрану и станет вести себя как absolute внутри wrapper'а.

Размер по умолчанию и место в потоке

Без явных width и height fixed-элемент, как и absolute, занимает размер по своему содержимому, а не растягивается на весь экран или родителя. Место в потоке документа тоже не резервируется - соседние элементы ведут себя так, будто fixed-элемента вообще не существует в разметке.

position: fixed; width: 100%; - явно растянуть на всю ширину, например, для фиксированной шапки сайта.

position: fixed; без width, ожидая шапку на всю ширину экрана - без явного width элемент останется по размеру содержимого, а не растянется на весь экран.

Из истории Даже когда десктопные браузеры наконец разобрались с поддержкой fixed (см. урок про основы position и историю провала IE5.5/6), на мобильных всё повторилось заново с опозданием на десятилетие. iOS Safari формально "поддержал" position:fixed только в iOS 5, вышедшей в 2011 году, но поддержка была фактически сломана: разработчик Реми Шарп в подробном разборе от мая 2012 года описывает, как фиксированные элементы дёргались при прокрутке, "уплывали" вверх при увеличении масштаба вплоть до полного исчезновения из вида, а нажатие на что-то внутри fixed-блока могло сдвинуть весь блок с места. Получается, одно и то же CSS-свойство прошло через два независимых десятилетия боли с реализацией - сначала в десктопном Internet Explorer, а затем ещё раз в мобильном Safari.

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

ОшибкаЧто происходитКак исправить
Используют absolute вместо fixed для элементов, которые должны оставаться на экране Элемент "уезжает" вместе со страницей при прокрутке, а не остаётся на месте Использовать position: fixed, если элемент должен быть привязан именно к окну просмотра
Не подозревают, что transform/filter у предка "ломает" fixed fixed-элемент вдруг начинает вести себя как absolute и уезжать при прокрутке Проверять предков на transform/filter/perspective, если fixed перестал "прилипать" к экрану
Ждут, что fixed-элемент без width растянется на весь экран Элемент остаётся по размеру содержимого, а не занимает всю ширину Задать width явно (например, width: 100% для шапки на всю ширину)

Шпаргалка

Что нужноКак сделать
Кнопка "наверх" на весь экранposition: fixed; bottom: 20px; right: 20px;
Фиксированная шапка на всю ширинуposition: fixed; top: 0; left: 0; width: 100%;
Случайно "ломает" fixed у потомковtransform/filter/perspective ≠ none у любого предка
Размер fixed-элемента без width/heightпо содержимому, не растягивается
Место в потоке документане резервируется, как у absolute

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

Уезжает ли fixed-элемент вместе со страницей при прокрутке?

Нет - в этом и есть смысл position: fixed. Он привязан к окну просмотра (viewport), а не к контенту страницы, поэтому остаётся на одном и том же месте экрана независимо от прокрутки. Если элемент всё же "уезжает", скорее всего у одного из его предков задан transform, filter или perspective.

Почему мой fixed-элемент вдруг перестал прилипать к экрану?

Скорее всего, у одного из предков этого элемента задан transform, filter или perspective, отличный от none - даже без position такой предок становится точкой отсчёта для fixed-потомка вместо окна просмотра, и элемент начинает вести себя как absolute.

Чем fixed отличается от absolute на практике?

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

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

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

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

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

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

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