Изменения наложения в позиции: фиксированные элементы

Том Вильциус
Tom Wiltzius

В Chrome 22 поведение элементов position:fixed немного отличается от предыдущих версий. Все position:fixed теперь образуют новые контексты наложения. Это изменит порядок расположения некоторых страниц, что может привести к поломке макета страницы. Новое поведение соответствует поведению браузеров WebKit на мобильных устройствах (iOS Safari и Chrome для Android).

Укладка Что?

Все знают и любят z-index для определения глубины расположения элементов на странице. Однако не все z-индексы одинаковы: z-index элемента определяет только его порядок относительно других элементов в том же контексте стекирования. Большинство элементов на странице находятся в одном корневом контексте стекирования, но абсолютно или относительно позиционированные элементы с неавтоматическими значениями z-index образуют свои собственные контексты стека (то есть все их дочерние элементы будут упорядочены по оси Z внутри родительского и не чередоваться с контентом, находящимся за пределами родительского элемента). Начиная с Chrome 22, элементы position:fixed также будут создавать свои собственные контексты стекирования.

Для общего обзора контекстов стекирования можно прочитать эту статью MDN .

Сравните position:fixed с новым атрибутом позиции:липкий : для справки, position:sticky всегда создает новый контекст стекирования.

Мотивация

Мобильные браузеры (Mobile Safari, Android-браузер, браузеры на базе Qt) помещают элементы Position:fixed в свои собственные контексты стекирования и в течение некоторого времени (начиная с iOS5, Android Gingerbread и т. д.), поскольку это позволяет выполнять определенную оптимизацию прокрутки, что делает веб-страницы более трудоемкими. более отзывчив на прикосновения. Это изменение вносится на настольный компьютер по трем причинам:

  1. Различное поведение рендеринга в «мобильных» и «настольных» браузерах является камнем преткновения для веб-авторов; CSS должен работать везде одинаково, если это возможно.
  2. Применительно к планшетам неясно, какой из алгоритмов создания контекста стекирования «мобильный» или «настольный» является более подходящим.
  3. Перенос оптимизации производительности прокрутки с мобильных устройств на настольные компьютеры выгоден как пользователям, так и авторам.

Особенности изменения

Вот пример, показывающий различное поведение макета: https://codepen.io/paulirish/pen/CgAof .

После этого изменения обе версии будут отображаться как правая версия.

В этом примере зеленое поле имеет z-index: 1 , розовое поле имеет z-index: 3 , а оранжевое поле имеет z-index: 2 . Синее поле является предком оранжевого поля и имеет position:fixed .

Если синий блок получает собственный контекст стекирования, z-index оранжевого блока вычисляется относительно контекста стекирования синего блока. Поскольку синий блок имеет z-index auto , что дает ему нулевой уровень стекирования в корневом контексте стекирования, это означает, что оранжевый блок оказывается позади зеленого и розового блоков, которые имеют z-индексы 1 и 3 (соответственно ) в корневом контексте.

Если синий блок не имеет собственного контекста стекирования, z-index оранжевого блока вычисляется относительно корневого контекста стекирования (вместе с зеленым и розовым блоками). Таким образом, оранжевый прямоугольник чередуется с розовым и зеленым прямоугольниками.

Для получения более подробной информации о критериях создания контекста стекирования (и о том, как контексты стекирования ведут себя в целом), снова обратитесь к этой статье MDN . В примере правая версия всегда давала синему прямоугольнику собственный контекст стекирования, поскольку его непрозрачность меньше 1. Вносимое изменение поведения фактически добавляет еще один критерий для создания отдельного контекста стекирования, а именно положение элемента: фиксированное.

Тестирование и будущее

Чтобы проверить, изменится ли ваша страница, перейдите в Chrome about:flags и включите/выключите «элементы с фиксированным положением создают контексты стека». Если ваш макет ведет себя одинаково в обоих случаях, все готово. Если нет, убедитесь, что этот флаг кажется вам приемлемым, поскольку в Chrome 22 он будет использоваться по умолчанию.

Это изменение удаляет одну возможность — возможность чередования контента внутри поддерева с фиксированной позицией с контентом без прокрутки снаружи. Маловероятно, что кто-либо из веб-разработчиков делает это намеренно, и тот же эффект может быть достигнут путем присвоения нескольким элементам Position:Fixed различным частям DOM. В качестве примера рассмотрим эти два примера:

https://codepen.io/wiltzius/pen/gcjCk

Эта страница пытается взять два дочерних элемента div (overlayA и overlayB) элемента Position:fixed и поместить один над отдельным элементом содержимого, а другой — под этим же отдельным элементом содержимого. Теперь это невозможно сделать, поскольку элемент Position:fixed является собственным контекстом стекирования, и он (вместе со всеми своими дочерними элементами) будет находиться либо полностью над, либо полностью под элементом содержимого. Обратите внимание, что этот пример работает в Chrome 21 и более ранних версиях, но больше не работает в Chrome 22.

Чтобы исправить это, два наложения можно разбить на отдельные позиции: фиксированные элементы. Каждый из них имеет свой собственный контекст стекирования, один из которых может располагаться над элементом содержимого, а другой — под элементом содержимого. См. фиксированный пример, который работает в Chrome 21 и 22:

https://codepen.io/wiltzius/pen/vhFzG

Заслуга в происхождении этого примера принадлежит неподражаемой хикси .

Chrome — первый настольный браузер, в котором элементы позиции: фиксированные создают свои собственные контексты стекирования. Соответствующим стандартом является спецификация CSS z-index (см., например , https://www.w3.org/TR/CSS21/zindex.html ). Пока еще нет единого мнения о том, что делать с разницей между мобильными и настольными браузерами, но, учитывая путаницу, связанную с двумя разными вариантами поведения на мобильных устройствах и настольных компьютерах, Chrome решил на данный момент перейти к этому единому поведению на обеих платформах.

Обновлено 1 октября 2012 г.: в исходной версии этой статьи предполагалось, что спецификация z-index CSS уже была изменена, чтобы отразить новое поведение позиции: фиксированные элементы. Это неточно; это обсуждалось в списке www-style, но пока в спецификацию не внесено никаких изменений.