Fazer um site simulando um aquário pode parecer um daqueles projetos complexos e avançados que envolvem milhares de linhas JavaScript, mas na verdade conseguimos fazer de forma bem simples usando apenas criatividade, HTML e um pouco do recurso de animações no CSS.
Tudo começa com fundo do nosso aquário. Podemos aplicar um simples efeito de gradiente alterando o tom de cor de azul:
body {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
background: linear-gradient(180deg, rgb(0, 150, 180) 0%, rgb(0, 100, 150) 100%);
overflow: hidden;
}

Agora precisamos olhar para o nosso peixe 🐟. Queremos que ele se mova de um lado para o outro de forma automática, sem a necessidade da interação do usuário. Para fazer isso, precisamos criar um @keyframe para poder aplicar uma transformação na imagem. No CSS, a transformação que nos permite deslocar elementos é o translate():
@keyframes nadar {
from {
transform: translateX(-200px) translateY(0);
}
to {
transform: translateX(calc(100vw + 50px)) translateY(-100px);
}
}
Nesta animação configuramos para que o nosso peixinho comece a -200px no eixo X usando a propriedade transform e o translateX. Logo em seguida alteramos o valor para 100vw + 50px, ou seja, desejamos que ele nade até o final do tamanho da janela com o acréscimo de 50px para ele sempre sair de cena (e acabar “reaparecendo” do outro lado).
Você também vai reparar que fizemos uma alteração de 100px negativos no eixo Y usando o translateY, ou seja, a medida que o peixe for nadando da esquerda para a direta, ele também irá nadar um pouco para cima.
Só que só isso não é suficiente, precisamos aplicar esta animação em nosso elemento do peixe usando a propriedade animation.
.fish {
width: 150px;
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.3));
animation: nadar 8s ease-in-out infinite;
}
Agora o peixe levará 8 segundos para completar esta animação e continuará a nadar de forma indefinida. Como diria a Dory do filme Procurando Nemo: “Continue a nadar!”.
Press enter or click to view image in full size

A partir daqui é somente uma questão de criatividade. Podemos inserir outros peixes e outras animações diferentes. No nosso exemplo (abaixo)
Aquário
Peixes nadando usando simplesmente HTML e CSS
aplicamos mais dois tipos de transformações: o scale() e o rotate(). Ficou desta forma:
.fish {
width: 150px;
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.3));
}
.fish:nth-child(1) {
animation: nadar 8s ease-in-out infinite;
}
.fish:nth-child(2) {
animation: nadar2 10s ease-in-out infinite;
animation-delay: -2s;
}
.fish:nth-child(3) {
animation: nadar3 12s ease-in-out infinite;
animation-delay: -4s;
}
.fish:nth-child(4) {
animation: nadar4 9s ease-in-out infinite;
animation-delay: -6s;
}
@keyframes nadar {
from {
transform: translateX(-200px) translateY(0);
}
to {
transform: translateX(calc(100vw + 50px)) translateY(-100px);
}
}
@keyframes nadar2 {
0% {
transform: translateX(100vw) translateY(0px) scaleX(-1);
}
50% {
transform: translateX(calc(50vw)) translateY(120px) scaleX(-1);
}
100% {
transform: translateX(-150px) translateY(-240px) scaleX(-1) rotate(-20deg);
}
}
@keyframes nadar3 {
from {
transform: translateX(-400px) translateY(0);
}
to {
transform: translateX(calc(100vw + 50px)) translateY(200px);
}
}
@keyframes nadar4 {
0% {
transform: translateX(-200px) translateY(0px);
}
50% {
transform: translateX(50vw) translateY(35px);
}
51% {
transform: translateX(50vw) translateY(35px) scaleX(-1);
}
100% {
transform: translateX(-100px) translateY(35px) scaleX(-1);
}
}
Você perceberá que para as animações que envolvem mais de “um passo”, fizemos o controle por meio de % ao invés de usar os termos from e to. E sei que estamos falando de peixes, mas sabe qual foi o pulo do gato? 🐈

O uso do scaleX(-1) para inverter horizontalmente o peixe. É desta forma que conseguimos fazer ele ir da esquerda para a direta ou mudar de tragetória no meio do caminho!




