CSS position sticky

CSS position sticky

O sticky é um novo valor da propriedade position do CSS. Com ele é possível criarmos elementos que se comportam ora como position:fixed, ora como position:relative dependendo de um valor de offset definido. Hein?

O efeito

Com um exemplo sempre fica mais fácil.

Caso você esteja usando o Chrome Canary, já deve ter percebido que os títulos deste post estão usando o position:sticky. Basta dar scroll na página até que os subtítulos do post batam no topo. Quando batem, ficam fixos no topo até que o elemento em que ele está contido (o elemento pai) suma por completo. No Chrome versão estável (atualmente 26.0.1410.65) também é possível brincar com esse novo valor de position. Basta digitar chrome://flags na barra de endereços, e habilitar o experimento Experimental WebKit features, como na imagem abaixo.

Habilitar experimentos do WebKit

Caso tenha habilitado o experimento, é preciso reiniciar o navegador.

Sintaxe

Para usar a position:sticky é preciso, além de setar um elemento como sticky, usar a propriedade top. É a propriedade top que define a partir de onde o nosso elemento vai se comportar como position:fixed.

.title-sticky {
    position: -webkit-sticky; /* apenas chrome e webkit nightly */
    top: 0;
  }
  

No exemplo acima, os elementos com a classe title-sticky irão se comportar como position:relative até que estejam a 0 pixels do topo do viewport. A partir desse momento, eles se comportam como se possuissem position:fixed. E só irão subir junto com o scroll quando o elemento em que ele está contido estiver totalmente fora do viewport.

Em outras palavras, os elementos com essa classe irão ficar fixos quando encostarem em cima do navegador (logo embaixo da barra de endereço) e só irão sumir quando o elemento pai também sumir, por completo.

É um pouco confuso explicar essa feature. E super simples de entender experimentando no navegador. Por favor, testem.

Mas eu já faço isso com JS

Esse efeito não é nenhuma novidade. É possível obter o mesmo resultado com JavaScript. Nós mesmo usamos JavaScript para ter esse efeito no aside de nossos posts, onde aparecem a data, autor e tags do post. E não é nada difícil de ser implementado.

Porém, o evento scroll deve ser usado com muita, mas muita cautela. Ele é disparado várias vezes em apenas um toque na mouse wheel. E, dependendo da computação que você está fazendo quando o evento é disparado, pode tornar a página pesada. Uma simples busca por elementos no DOM com jQuery já pode diminuir consideravelmente o número de frames por segundos da renderização da nossa página.

Outra coisa a ser considerada é que cada vez mais os navegadores estão otimizando a rolagem implementando aceleração nas GPUs. Com o uso do JavaScript no eventos de scroll, nós podemos cair para uma aceleração padrão na CPU, por software, deixando o scroll mais "pesado".

Além do que é bem mais fácil usarmos apenas CSS. E também faz mais sentido, já que estamos definindo layout.

Quando posso usar?

Infelizmente o position:sticky ainda não é um padrão W3C. Ele foi proposto mas até o momento implementado apenas pelo WebKit e agora Blink, o motor de renderização do Chrome (que é um fork do WebKit).

Suporte

position:sticky;23 *6.1Nightly----
* Deve ser habilitado através de uma flag.

Mas nós sempre podemos encher o saco dos programadores dos nossos queridos navegadores abrindo issues em seus projetos. Apenas naqueles que forem open source, claro.

Atualizações

15/10/2013

Safari 6.1 e Firefox Nightly já apresentam suporte.

27/06/2014

A propriedade foi removida do Blink — o motor de renderização do Chrome. Mais detalhes no log do commit da alteração.

#43