No Chrome 22, o comportamento do layout dos elementos position:fixed
é um pouco diferente das versões anteriores. Todos os elementos position:fixed
agora formam novos contextos de empilhamento. Isso vai mudar a ordem de empilhamento de algumas páginas, o que pode interromper os layouts. O novo comportamento corresponde ao comportamento dos navegadores do WebKit em dispositivos móveis (iOS Safari e Chrome para Android).
O que há empilhando?
Todo mundo conhece e adora o z-index
para determinar a ordem de profundidade dos elementos em uma página. No entanto, nem todos os Z-indexes são criados da mesma forma: o z-index
de um elemento determina a ordem em relação a outros elementos no mesmo contexto de empilhamento. A maioria dos elementos em uma página está em um único contexto de empilhamento raiz, mas elementos absolutos ou relativamente posicionados com valores de z-index
não automáticos formam os próprios contextos de empilhamento, ou seja, todos os filhos serão ordenados em z dentro do pai e não serão intercalados com conteúdo de fora do pai. A partir do Chrome 22, os elementos position:fixed
também vão criar os próprios contextos de empilhamento.
Para uma visão geral sobre o empilhamento de contextos, este artigo da MDN é ótimo para ler.
Compare position:fixed
com o novo atributo position:sticky: para referência, position:sticky
sempre cria um novo contexto de empilhamento.
Motivação
Os navegadores para dispositivos móveis (Mobile Safari, navegador Android, navegadores baseados em Qt) colocam os elementos position:fixos em seus próprios contextos de empilhamento e têm há algum tempo (desde o iOS5, Android Gingerbread etc.) porque permitem certas otimizações de rolagem, tornando as páginas da web muito mais responsivas ao toque. A mudança está sendo implementada nos computadores por três motivos:
- Ter um comportamento de renderização diferente em navegadores para dispositivos móveis e computadores é um obstáculo para os autores da Web. O CSS deve funcionar da mesma forma em qualquer lugar, sempre que possível.
- Com tablets, não fica claro qual dos algoritmos de criação de contexto de empilhamento para "dispositivo móvel" ou "computador" é mais apropriado.
- Trazer as otimizações de desempenho de rolagem do celular para o computador é bom para usuários e autores.
Detalhes da mudança
Confira um exemplo dos diferentes comportamentos de layout: https://codepen.io/paulirish/pen/CgAof (em inglês).
Com a mudança, as duas versões serão renderizadas como a versão à direita.
Neste exemplo, a caixa verde tem um z-index: 1
, a caixa rosa tem um z-index: 3
e a caixa laranja tem um z-index: 2
. A caixa azul é um ancestral da caixa laranja e tem position:fixed
.
Se a caixa azul receber o próprio contexto de empilhamento, o z-index
da caixa laranja vai ser calculado em relação ao contexto de empilhamento da caixa azul. Como a caixa azul tem um z-index
de auto
, o que dá a ela um nível de empilhamento zero no contexto de empilhamento raiz, isso significa que a caixa laranja fica atrás das caixas verde e rosa, que têm Z-indexes de 1 e 3 (respectivamente) no contexto raiz.
Se a caixa azul não tiver o próprio contexto de empilhamento, o z-index
da caixa laranja vai ser calculado em relação ao contexto de empilhamento raiz, com as caixas verde e rosa. Portanto, a caixa laranja acaba intercalada com as caixas rosa e verde.
Para saber mais sobre os critérios de criação de contexto de empilhamento (e como eles se comportam em geral), consulte este artigo da MDN. No exemplo, a versão à direita sempre deu à caixa azul o próprio contexto de empilhamento, porque a opacidade é inferior a 1. A mudança de comportamento feita adiciona outro critério para criar um contexto de empilhamento separado, ou seja, um elemento que tem posição fixa.
Testes e o futuro
Para testar se a página vai mudar, acesse o about:flags
do Chrome e ative/desative a opção "Elementos de posição fixa criam contextos de empilhamento". Se o layout se comportar da mesma forma nos dois casos, está tudo pronto. Caso contrário, verifique se o problema é aceitável com essa sinalização ativada, já que esse será o padrão no Chrome 22.
Essa mudança remove um recurso, ou seja, a possibilidade de intercalar o conteúdo dentro de uma subárvore de posição:fixada com conteúdo sem rolagem de fora É improvável que algum desenvolvedor da Web faça isso de propósito, e o mesmo efeito pode ser gerado ao atribuir a vários elementos position:fixos diferentes partes do DOM. Por exemplo, considere estes dois exemplos:
https://codepen.io/wiltzius/pen/gcjCk
Esta página tenta pegar dois divs filhos (overlayA e overlayB) de um elemento position:Fixed e colocar um acima de um div de conteúdo separado e outro abaixo do mesmo div de conteúdo separado. Agora é impossível fazer isso porque o elemento position:fix é o próprio contexto de empilhamento e ele (junto com todos os filhos) vai estar totalmente acima ou abaixo do div de conteúdo. No Chrome 2 e versões anteriores.
Para corrigir isso, as duas sobreposições podem ser divididas em seus próprios elementos de posição:fixo. Cada um tem o próprio contexto de empilhamento. Um deles pode ficar acima do div de conteúdo e outro abaixo dele. Veja o exemplo fixo que funciona no Chrome 21 e 22:
https://codepen.io/wiltzius/pen/vhFzG
O crédito para a gênese deste exemplo vai para o inimitável hixie.
O Google Chrome é o primeiro navegador para computador a fazer com que os elementos position:fixos criem seus próprios contextos de empilhamento. O padrão relevante é a especificação z-index do CSS (por exemplo, https://www.w3.org/TR/CSS21/zindex.html). Ainda não há consenso sobre o que fazer sobre a diferença entre navegadores para dispositivos móveis e computadores. No entanto, por conta da confusão de ter dois comportamentos diferentes em dispositivos móveis e computadores, por enquanto, o Chrome optou por mudar para esse único comportamento em ambas as plataformas.
Atualizado em 1o de outubro de 2012: a versão original deste artigo sugeriu que a especificação z-index
do CSS já havia sido alterada para refletir o novo comportamento da posição: elementos fixos. Isso é impreciso; já foi discutido na lista de estilo www, mas ainda nenhuma alteração foi feita na especificação.