30 de maio de 2018 • 6 min de leitura
Menu Sticky e Smooth Scroll com CSS puro
Aprenda algumas propriedades bem interessantes do CSS e já saia brincando por aí.
Introdução
Fala pessoal, como eu acho que fiquei parado muito tempo e o número de posts caiu muito, quero voltar a escrever mais. E por isso decidi que vou fazer vários posts bem simples, mas não menos importantes, sobre algumas propriedades do CSS que podemos usar a nosso favor, assim como alguns experimentos legais, que podem ser usados nos seus próximos trabalhos.
Eu já tinha pensando em fazer esse post, mas o @felipefialho_ acabou dando uma forcinha quando criou o seguinte Tweet:
👉 position: sticky;
— Felipe Fialho (@felipefialho_) May 29, 2018
- Mistura \\`fixed\\` e \\`absolute\\`
- Só com CSS conseguimos um efeito que necessitava de JavaScript
- Suporte em todos os browsers modernos (bugs contornáveis)
- É legal pra caraleo
Vejam esse exemplo simplezão 😁https://t.co/fM22xYUMBV
Bom vamos lá, a trilha sonora que me acompanha hoje é um post-rock dos bons, a banda se chama Tides from nebula e para mim é um som perfeito para se concentrar e programar.
O experimento
Se quiser pular tudo e já ver funcionando, só abrir esse link aqui. Mas se quiser seguir comigo a explicação é super super fácil!
Position: sticky
Essa é uma propriedade que já foi introduzida há um boooooom tempo, lá nos idos de 2012 e então logo foi removida, pois na época a sua implementação era "bugada" e não funcional como alguns dos desenvolvedores falavam.
Mas agora em 2016 o sticky voltou! E como ele funciona?
O
position: sticky;
é um híbrido entre ofixed
e orelative
. O elemento é tratado comorelative
até alcançar um limite especificado, que é através dotop, bottom, left, right
. Alcançando esse ponto, ele vai ser tratado como fixo. E assim que chegar a sua posição "original", ele voltará a funcionar comorelative
.
Parece meio complicado né? Vamos tentar ver melhor na prática.
Menu fixo
Vamos lá, como foi feito o exemplo acima? Primeiro vendo o menu, temos o seguinte html:
<body>
<header>
<h1>Scroll & Sticky!</h1>
</header>
<nav>
<ul>
<li><a href="#hey">Hey!</a></li>
<li><a href="#cool">Cool</a></li>
<li><a href="#truth">Truth</a></li>
<li><a href="#all-css">All CSS</a></li>
</ul>
</nav>
</body>
Reparem que eu tenho 2 elementos filhos do body
, que são o header
e o nav
. Eu fiz algumas pequenas edições no css, dando uma altura ao header e também estilo ao nav, mas vamos focar nas seguintes propriedades css:
header {
height: 90vh;
}
nav {
position: sticky;
top: 0;
}
Se você não reconhece aquele valor vh
ali, saiba que é uma viewport unit, eu escrevi sobre isso, neste post. Mas tenha em mente que a única coisa que isso faz é dar uma altura de 90% do espaço da tela visível.
Com isso, o meu nav
vai aparecer logo no finalzinho da tela certo? Já que o header vai ocupar 90% de altura. E é aí que entra o pulo do gato. Ao definir o position: sticky
no meu nav
junto com o top: 0
, eu digo para ele que no momento que o nav
alcançar o topo do body
, que ele comece a se comportar como fixed
e é isso que faz o nosso menu ficar preso ali no topo.
E porque ele não some da tela por mais que faça scroll?
Simples, como o nav
é filho do body
, o pai vai sempre estar na tela e o position do top
é em relação a visão do elemento pai na tela.
Samuel fixo
Eu resolvi colocar um outro elemento com position: sticky
para mostrar a diferença e também porque é divertido ver o Samuel L. Jackson pulando no meio da tela e não saindo, vai dizer que não é legal?
Bom, vamos entender como esse funciona, primeiro, vamos ao markup:
<article class="container">
<section id="hey"></section>
<section id="cool"></section>
<section id="truth"></section>
<section id="all-css"></section>
<img class="sticky" src="..." />
<section></section>
<a class="link" href="http://slipsum.com/">Text by Samuel L. Ipsum</a>
</article>
Reparem agora que eu tenho a imagem com a classe .sticky
e ela está dentro do pai, que é o .container
. Isso significa que o posicionamento da minha imagem vai funcionar em relação ao .container
.
Agora então definindo o seguinte css:
.sticky {
position: sticky;
bottom: 50px;
}
Eu digo para o meu elemento o seguinte, no momento que o meu elemento pai
aparecer, comporte-se como fixed
com espaçamento de 50px
da parte inferior da tela, quando chegar na posição original dentro do pai, volte a ser relative
.
Compatibilidade
Essa propriedade apesar de já ser velha conhecida, como falei lá no início do post, ela ainda está sendo aplicada aos poucos pelos browsers, mas já está funcionando nos browsers mais atuais. E você pode olhar no Can I use.
Smooth Scroll
Por final, se você clicar em cada uma das âncoras, vai ver o efeito de scroll to
, onde eu deslizo a tela até o elemento indicado pela âncora. Mas repare que é um deslizar bonitinho, que a maioria dos clientes pedem naquelas landing pages. E o mais incrível de tudo isso, é que esse efeito é feito com apenas 1 propriedade do css:
html {
scroll-behavior: smooth;
}
Compatibilidade
Essa propriedade é bem legal, mas infelizmente ainda está bem no início, só funcionando no Chrome e Firefox, mas vamos ter fé que já já melhora o suporte, vamos vendo no Can I use.
Conclusão
Bom galera, espero que tenham curtido o post, é algo bem simples, mas talvez seja útil em algum projeto de vocês, nem que seja só para um protótipo para validar uma ideia =)
Eu prometo continuar com posts mais frequentes e outras dicas assim. E vamos que vamos! Se você não tem acessado o blog recentemente, eu lancei 2 posts nos últimos 2 dias, uhul! Dá uma lida também, Criando um Codepen simples em poucas linhas e Performance Web: Evite escrever HTML demais.