Pare de chutar e aprenda como funciona a position: fixed
Quando estou gravando aulas de CSS do curso Do Front ao End e tirando dúvidas dos alunos pelo Discord da CollabCode sobre as propriedades de posicionamento do CSS, a position: fixed é a mais divertida de explicar :-)
Ah! Esse será o primeiro post que vou te propor um desafio final para você testar o seu conhecimento sobre o conteúdo passado aqui e outras coisas mais sobre CSS. Depois que terminar o desafio ou enquanto você estiver fazendo, entre lá no Discord da CollabCode clicando no link a seguir para você tirar suas dúvidas e compartilhar todo seu conhecimento:
Se tem dúvidas sobre outras propriedades de posicionamento do CSS, eu tenho um post que é o agregador para todos os posts que escrevi sobre o assunto:
Não diferente dos outros posts sobre as propriedades de posicionamento do CSS, neste nós teremos um objetivo e código inicial. Vou começar te mostrando o nosso código inicial e em seguida mostro qual será o objetivo que implementaremos durante o post.
Nosso layout inicial tem 3 arquivos: index.html
, reset.css
e position.css
.
index.html
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Exemplo de como funciona a propriedade position: fixed</title><link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/position.css">
</head>
<body>
<header class="header">
<img class="header-logo" src="img/logo.png" alt="Logo do CollabCode">
</header> <article>
<h1>Novos Vídeos toda segunda, quarta e sexta</h1> <p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore dicta voluptate odit aperiam distinctio, minus unde alias assumenda, excepturi perferendis laborum dolores beatae? Quae sed, magnam sequi aspernatur sit error.
</p>
</article> <aside class="banner">
Último vídeo
</aside> <a class="button" href="">Assistir agora</a>
</body>
</html>
reset.css
* {
margin: 0;
padding: 0;
border: 0;
}
body {
font-family: "Open Sans", sans-serif;
}
ul, ol, li {
list-style: none;
}
position.csss
.header {
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}.header-logo {
height: 50px;
}.banner {
background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}p {
margin-bottom: 20px;
}
Ah! Você também vai precisar do logo da CollabCode que usamos dentro da tag <header>
, aí está ele:
Se você abrir o arquivo index.html
em seu browser (navegador) verá o seguinte resultado visual:
Nosso objetivo é deixar o menu fixo ao topo do browser, o botão verde fixo na parte inferior do browser e por último deixar a caixa roxa fixa do lado direito e centralizada no sentido horizontal (eixo y) do nosso browser. Quando eu falo fixo, estou querendo dizer que quando o usuário utilizar o scroll (barra de rolagem) os 3 elementos que comentei anteriormente ficam parados.
Vamos começar a implementar nosso objetivo pela tag aside
que está na cor roxa. Primeiro vamos deixá-la do lado direito no topo em relação ao browser de forma que ela fique fixa no topo à direita mesmo se o usuário utilizar o scroll do browser. Para ficar fixa utilizaremos a propriedade position
com o valor fixed
e junto podemos utilizar a propriedade right
com o valor 0
e a top
com valor 0
para movermos a aside
para o topo e a direita em relação ao browser. Aplicaremos essas três propriedades dentro do seletor .banner
no arquivo position.css
:
position.css
.header {
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}.header-logo {
height: 50px;
}.banner {
position: fixed;
top: 0;
right: 0; background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}p {
margin-bottom: 20px;
}
Salvando o arquivo position.css
e abrindo o arquivo index.html
no browser você terá o seguinte resultado visual:
Assim que adicionamos a propriedade position
com o valor fixed
o nosso elemento roxo sai do contexto padrão do browser e fica em um novo contexto. Esse novo contexto fica à frente do contexto padrão do browser, além disso, é liberado o espaço que o elemento ocupava no contexto do browser. Por isso, o botão verde que estava abaixo do elemento roxo subiu e ocupou o lugar do elemento roxo.
Outro comportamento do position:fixed
, é que a referência dele de alinhamento é o browser, por este motivo que no momento que utilizamos a propriedade right
e top
o elemento se posicionou no topo do browser e à direita.
Agora precisamos centralizar o elemento roxo no sentido vertical, para que isso aconteça podemos começar setando o valor de 50%
na propriedade top
. Volte ao arquivo position.css
e faça essa alteração:
position.css
.header {
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}.header-logo {
height: 50px;
}.banner {
position: fixed;
top: 50%;
right: 0; background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}p {
margin-bottom: 20px;
}
Por favor, volte ao browser, atualize e você terá o resultado similar a este:
Olhando o resultado no browser podemos concluir que não conseguimos centralizar o elemento roxo, isso aconteceu porque quando colocamos o position: fixed
ele não utilizou o centro do elemento roxo para efetuar o deslocamento dele, em vez disso ele pegou o topo porque utilizamos a propriedade top
, se tivéssemos utilizado a propriedade bottom
o deslocamento seria feito tendo como referência a parte de baixo do elemento. Para que fique de fato ao centro, precisamos mover a nossa caixa roxa, metade do tamanho dela para cima. Felizmente nós temos uma propriedade que torna possível de implementarmos esse comportamento, ela é a transform
com o valor translateY(-50%).
A propriedade translateY
é utilizada para deslocar o elemento no sentido vertical (eixo Y). Quando aplicado um valor negativo o elemento sobe e caso seja aplicado um valor positivo o elemento desce. Utilizamos um valor percentual dentro do translateY
e diferente da propriedade top
, o translateY
não pega a altura do browser como referência, essa propriedade pega a altura do elemento onde ela foi aplicada e é este o comportamento que precisamos para deixar o nosso elemento roxo centralizado verticalmente. Por favor, volte ao arquivo position.css
e adicione a transform: translateY(-50%)
no seletor .banner
:
position.css
.header {
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}.header-logo {
height: 50px;
}.banner {
position: fixed;
top: 50%;
right: 0;
transform: translateY(-50%); background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}p {
margin-bottom: 20px;
}.button {
display: block;
width: 100px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}p {
margin-bottom: 20px;
}
Só salvar o arquivo position.css
, depois voltar para seu browser (não esquece de atualizar) e você verá o seguinte resultado visual:
Para finalizar essa primeira fase do nosso objetivo só precisamos deslocar o elemento roxo um pouco para a esquerda tendo como referência o lado direito do browser. Só precisamos então atribuir um valor positivo para a propriedade right
que está no seletor .banner
:
position.css
.header {
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}.header-logo {
height: 50px;
}.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%); background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}p {
margin-bottom: 20px;
}
Só salvar o arquivo position.css
e voltar até o browser que teremos finalizado a primeira parte do nosso objetivo:
Na nossa segunda fase vamos implementar o header (cabeçalho) fixo. Já que queremos algo fixo precisamos setar o valor da propriedade position
para fixed
no seletor .header
que está no arquivo position.css
:
position.css
header {
position: fixed; padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}
.header-logo {
height: 50px;
}
.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%);
background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}
p {
margin-bottom: 20px;
}
Salvando e voltando ao nosso browser você terá o seguinte resultado visual:
Conforme o esperado, nosso elemento header
está em um novo contexto por causa do fixed
e liberou o espaço que ocupava no contexto do browser. Outro comportamento do postion: fixed
é que uma vez que não temos width
e/ou height
definido, o que define o tamanho dele é o conteúdo do elemento que está o position: fixed
. Mas de alguma forma precisamos implementar um código que faça o nosso header
ocupar 100% da largura do nosso browser. Portanto, precisamos voltar em nosso arquivo positiom.css
e definir a propriedade width
com o valor de 100%
:
position.css
header {
position: absolute;
width: 100%; padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}
.header-logo {
height: 50px;
}
.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%);
background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}
p {
margin-bottom: 20px;
}
Se for até o navegador e atualizá-lo, verá o resultado visual a seguir:
Legal! Agora está me incomodando muito o fato do logo da CollabCode se misturar com o conteúdo que está atrás dela. Para resolver isso só precisamos definir uma cor de fundo para o nosso header
com background-color: #FFF
no nosso arquivo position.css
:
.header {
position: fixed;
width: 100%; background-color: #FFF;
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}
.header-logo {
height: 50px;
}
.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%);background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}
p {
margin-bottom: 20px;
}
Eita! Onde foi parar o nosso título que estava misturado com o logo da CollabCode? Ela continua atrás do nosso header
só que agora o header
tem uma cor de fundo definida que faz com que o nosso título não fique mais visível. Para resolver isso precisamos empurar o nosso título um pouco para baixo, vamos aplicar um padding-top
de 140px
em nosso article
:
article {
padding-top: 140px;
}.header {
position: fixed;
width: 100%; background-color: #FFF;
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}
.header-logo {
height: 50px;
}
.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%);background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}
p {
margin-bottom: 20px;
}
Atualize seu browser e você terá o resultado visual a seguir, agora com o título aparecendo abaixo do nosso header
:
O resultado visual já está certo mas temos uma pegadinha em nosso header
, a largura dele é um pouco maior do que nós precisamos, ele está ultrapassando a largura do nosso navegador, só não apareceu um scroll vertical porque o nosso header
está com a position: fixed
. Vamos voltar no arquivo position.css
e trocar o position: fixed
por position: static
e você verá o scroll vertical acontecendo:
article {
padding-top: 140px;
}.header {
position: static;
width: 100%; background-color: #FFF;
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}
.header-logo {
height: 50px;
}
.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%);background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}
p {
margin-bottom: 20px;
}
Atualize o seu browser e você verá terá o seguinte resultado:
Agora o que está causando esse scroll vertical? Nós temos um width: 100%
no nosso header
, esse 100% é exatamente a largura do elemento pai do header
que no nosso caso é o browser então se tivermos um navegador com 1920px de largura também teremos o header
com 1920px de largura? Sim isso é verdade, mas em nosso header
também temos um padding: 20px 40px
que é adicionado 20px de respiro interno no topo e na parte inferior dele e 40px de respiro interno no lado esquerdo e lado direto. Esses respiros internos que aplicamos nos lados direito e esquerdo por padrão são somados à largura que definimos na propriedade width
e dessa forma a largura do nosso header
fica maior que a largura (2000px) do nosso browser (1920px), como ilustrado na imagem a seguir.
Felizmente para resolver isso é bem simples, só precisamos mudar o comportamento padrão da propriedade box-sizing
de content-box
para border-box
. Uma vez que definirmos o box-sizing
com border-box
o valor definido no width
será respeitado de fato conforme ilustrado na imagem a seguir:
Agora que entendemos o que estava de errado com a largura do nosso header
e já estudamos como resolver, bora implementar. Vá até o arquivo position.css
e adicione o box-sizing: border-box
no header
e volte o position: fixed
:
article {
padding-top: 140px;
}.header {
position: fixed;
box-sizing: border-box;
width: 100%; background-color: #FFF;
padding: 20px 40px;
border-bottom: 1px solid #222f3e;
margin-bottom: 30px;
}
.header-logo {
height: 50px;
}
.banner {
position: fixed;
top: 50%;
right: 5%;
transform: translateY(-50%);background-color: #5f27cd;
color: #FFF;
text-transform: uppercase;
text-align: center;
width: 200px;
height: 200px;
line-height: 200px;
}
.button {
display: block;
width: 160px;
height: 40px;
opacity: 0.95;
height: 60px;
line-height: 60px;
text-align: center;
color: #FFF;
text-decoration: none;
text-transform: uppercase;
background-color: #1dd1a1;
}
p {
margin-bottom: 20px;
}
Atualizando seu browser você terá o serguinte resultado:
Pronto! O próximo passo é o desafio final onde você vai testar seu conhecimento. Lembre-se que se você tiver dúvidas pode mandar lá no Discord da CollabCode. Partiu desafio final.
Desafio final
Sabe o botão fixo na parte inferior da nossa page que está na cor verde com o conteúdo assitir agora, esse é o desafio que você terá que implementar, conforme está no gif a seguir:
Isso é tudo que queria passar te conhecimento pra você sobre o position: fixed
até o próximo post que parece mais um livro…kkkk
Ah! É bem possível que eu tenha esquecido algum ponto, então recomendo que você também leia a documentação lá na MDN: https://developer.mozilla.org/pt-BR/docs/Web/CSS/position