position: sticky
é uma nova maneira de posicionar elementos e é conceitualmente semelhante a position: fixed
. A diferença é que um elemento com position: sticky
se comporta como position: relative
no pai até que um determinado limite de deslocamento seja atendido na janela de visualização.
Casos de uso
Parafraseando a proposta original de Edward O'Connor para esse recurso:
Introdução ao posicionamento fixo
Basta adicionar position: sticky
(prefixo do fornecedor) para definir um elemento como position: relative
até que o usuário role o item (ou o pai dele) para ficar a 15 px da parte de cima:
.sticky {
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
top: 15px;
}
Em top: 15px
, o elemento se torna fixo.
Para ilustrar esse recurso em uma configuração prática, montei uma DEMONSTRAÇÃO que fixa os títulos do blog enquanto você rola a página.
Antiga abordagem: eventos de rolagem
Até agora, para conseguir o efeito fixo, os sites configuravam listeners de eventos scroll
no JS. Também usamos essa técnica nos tutoriais do html5rocks. Em telas menores que 1.200 px, a barra lateral do sumário muda para position: fixed
após uma certa quantidade de rolagem.
Confira a maneira (agora antiga) de ter um cabeçalho que gruda na parte de cima da viewport quando o usuário rola para baixo e volta ao lugar quando o usuário rola para cima:
<div class="header"></div>
<script>
var header = document.querySelector('.header');
var origOffsetY = header.offsetTop;
function onScroll(e) {
window.scrollY >= origOffsetY ? header.classList.add('sticky') :
header.classList.remove('sticky');
}
document.addEventListener('scroll', onScroll);
</script>
Teste: http://output.jsbin.com/omanut/2/
Isso é bastante fácil, mas esse modelo quebra rapidamente se você quiser fazer
isso para vários nós DOM, por exemplo, cada título <h1>
de um blog conforme o usuário rola a página.
Por que o JS não é ideal
Em geral, os manipuladores de rolagem nunca são uma boa ideia. As pessoas tendem a fazer muito trabalho e se perguntam por que a interface está instável.
Outro ponto a ser considerado é que cada vez mais navegadores estão implementando a rolagem com aceleração de hardware para melhorar o desempenho. O problema é que, quando os manipuladores de rolagem do JS estão em ação, os navegadores podem voltar para um modo mais lento (de software). Agora não estamos mais executando na GPU. Em vez disso, voltamos à CPU. O resultado? O usuário percebe mais lentidão ao rolar a página.
Portanto, faz muito sentido ter esse recurso declarado no CSS.
Suporte
Infelizmente, não há uma especificação para isso. Ele foi proposto no estilo www em junho e lançado no WebKit. Isso significa que não há uma boa documentação para apontar. No entanto, de acordo com este bug, se left
e right
forem especificados, left
vai prevalecer. Da mesma forma, se top
e bottom
forem usados ao mesmo tempo, top
vai vencer.
No momento, o suporte é para o Chrome 23.0.1247.0+ (Canary atual) e para o WebKit noturno.