Neste novo tutorial, aprenderemos como criar um efeito de animação de texto giratório usando variáveis CSS e JavaScript. Embora certamente possamos construir uma animação simples de alteração de texto em CSS puro, colocaremos JavaScript no loop para tornar as coisas mais fáceis de manter e eficazes.
Animação giratória de texto básico
Definiremos um h1
elemento onde colocaremos como span
são todas as palavras que queremos animar. Por padrão, todos span
terá o data-bg-color
e data-color
atributos personalizados que determinarão as cores do texto e do plano de fundo de acordo. Além disso, inicialmente, apenas o span
com o current
class ficará visível – a primeira no nosso caso.
Este é o formato de marcação necessário:
1 |
|
2 |
I want to learn class="css">CSS and
|
3 |
class="words">
|
4 |
class="current" data-bg-color="#ffc703" data-color="#000">React
|
5 |
data-bg-color="#004e98" data-color="#fff">TypeScript
|
6 |
data-bg-color="#8cb369" data-color="#000">Python
|
7 |
data-bg-color="#104911" data-color="#fff">PrestaShop
|
8 |
data-bg-color="#b8c0ff" data-color="#000">Ruby
|
9 |
data-bg-color="#e71d36" data-color="#fff">Angular
|
10 |
data-bg-color="#e2c044" data-color="#000">WordPress
|
11 |
data-bg-color="#065a82" data-color="#fff">Node
|
12 |
. |
13 |
|
Como fizemos em muitos outros tutoriais no passado, usaremos CSS Grid para colocar todas as palavras umas sobre as outras. Mas lembre-se que cada vez, apenas a palavra com o current
classe aparecerá.
Aqui estão todos os estilos necessários:
1 |
.words-wrapper { |
2 |
font-size: 40px; |
3 |
font-weight: bold; |
4 |
text-align: center; |
5 |
}
|
6 |
|
7 |
.words-wrapper .css { |
8 |
color: #2ec4b6; |
9 |
}
|
10 |
|
11 |
.words-wrapper .words { |
12 |
display: inline-grid; |
13 |
padding: 0 10px; |
14 |
border-radius: 6px; |
15 |
color: var(--color, #000); |
16 |
background: var(--color-bg, #ffc703); |
17 |
}
|
18 |
|
19 |
.words-wrapper .words span { |
20 |
grid-area: 1/1; |
21 |
display: none; |
22 |
}
|
23 |
|
24 |
.words-wrapper .words span.current { |
25 |
display: block; |
26 |
}
|
Para mostrar uma palavra diferente após um determinado período de tempo, seguiremos esta abordagem:
- A cada 1,5 segundos, direcionaremos a palavra visível (ativa).
- Então, encontraremos sua palavra irmã adjacente, se existir, caso contrário, obteremos a primeira palavra.
- Nós vamos remover o
current
class da palavra ativa e adicione-a ao novo elemento. - Finalmente, pegaremos as cores da nova palavra ativa e atualizaremos as variáveis CSS correspondentes.
Aqui está o JavaScript necessário:
1 |
const wrapper = document.querySelector(".words"); |
2 |
const CURRENT_CLASS = "current"; |
3 |
|
4 |
setInterval(() => { |
5 |
const currentWord = wrapper.querySelector("span.current"); |
6 |
const nextWord = currentWord.nextElementSibling |
7 |
? currentWord.nextElementSibling |
8 |
: wrapper.firstElementChild; |
9 |
currentWord.classList.remove(CURRENT_CLASS); |
10 |
nextWord.classList.add(CURRENT_CLASS); |
11 |
wrapper.style.setProperty("--color", nextWord.dataset.color); |
12 |
wrapper.style.setProperty("--color-bg", nextWord.dataset.bgColor); |
13 |
}, 1500); |
Terminaremos com a seguinte demonstração:
Animação rotativa de texto complexo
Vamos agora aproveitar o exemplo anterior e criar algo mais elegante!
A marcação permanecerá a mesma, exceto por uma alteração; desta vez, adicionaremos o next
class à palavra que vem depois da ativa, assim:
1 |
|
2 |
I want to learn class="css">CSS and
|
3 |
class="words">
|
4 |
class="current" data-bg-color="#ffc703" data-color="#000">React
|
5 |
class="next" data-bg-color="#004e98" data-color="#fff">TypeScript
|
6 |
data-bg-color="#8cb369" data-color="#000">Python
|
7 |
data-bg-color="#104911" data-color="#fff">PrestaShop
|
8 |
data-bg-color="#b8c0ff" data-color="#000">Ruby
|
9 |
data-bg-color="#e71d36" data-color="#fff">Angular
|
10 |
data-bg-color="#e2c044" data-color="#000">WordPress
|
11 |
data-bg-color="#065a82" data-color="#fff">Node
|
12 |
. |
13 |
|
Ao contrário do exemplo anterior, não usaremos CSS Grid para posicionar as palavras, mas em vez disso, cada palavra será um elemento posicionado de forma absoluta. Seu pai imediato (ou seja, o .words
elemento) terá uma largura que dependerá da largura da palavra ativa. A próxima palavra aparecerá suavemente de baixo para cima e depois moverá para cima para desaparecer.



Em telas pequenas onde o texto se divide em mais de uma linha, para evitar oscilações nas linhas que podem ocorrer dependendo da largura da palavra ativa, definiremos a largura de todas as palavras igual à largura da palavra maior. Neste caso, usaremos o !important
palavra-chave para substituir a largura do .words
elemento que é definido através do width
Variável CSS.
Aqui estão todos os estilos necessários:
1 |
.words-wrapper { |
2 |
font-size: 40px; |
3 |
font-weight: bold; |
4 |
text-align: center; |
5 |
}
|
6 |
|
7 |
.words-wrapper .css { |
8 |
color: #2ec4b6; |
9 |
}
|
10 |
|
11 |
.words-wrapper .words { |
12 |
display: inline-block; |
13 |
position: relative; |
14 |
vertical-align: bottom; |
15 |
width: var(--width); |
16 |
height: 60px; |
17 |
padding: 0 10px; |
18 |
border-radius: 6px; |
19 |
color: var(--color, #000); |
20 |
background: var(--color-bg, #ffc703); |
21 |
box-sizing: content-box; |
22 |
transition: all 0.7s; |
23 |
}
|
24 |
|
25 |
.words-wrapper .words span { |
26 |
position: absolute; |
27 |
top: 0; |
28 |
left: 50%; |
29 |
opacity: 0; |
30 |
transform: translate(-50%, -100%); |
31 |
transition: transform 0.7s, opacity 0.25s 0.25s; |
32 |
}
|
33 |
|
34 |
.words-wrapper .words span.current { |
35 |
opacity: 1; |
36 |
transform: translate(-50%, 0); |
37 |
}
|
38 |
|
39 |
.words-wrapper .words span.next { |
40 |
transform: translate(-50%, 100%); |
41 |
}
|
42 |
|
43 |
@media (max-width: 700px) { |
44 |
.words-wrapper .words { |
45 |
width: var(--width-mobile) !important; |
46 |
}
|
47 |
}
|
Quando o DOM estiver pronto, especificaremos a largura inicial do .words
wrapper atualizando os valores do width
e width-mobile
Valores de variáveis CSS.
A seguir, semelhante ao exemplo anterior, para mostrar uma palavra diferente após um determinado período de tempo, seguiremos esta abordagem:
- A cada 1,5 segundos, direcionaremos as palavras visíveis (ativas) e as próximas palavras ativas.
- Então, encontraremos a palavra irmã adjacente da próxima palavra ativa, se existir, caso contrário, obteremos a primeira palavra.
- Nós vamos remover o
current
classe da palavra ativa e donext
classe da próxima palavra ativa. - Vamos adicionar o
current
classe para a próxima palavra ativa e onext
class para sua palavra irmã adjacente. - Finalmente, pegaremos a largura e as cores da nova palavra ativa e atualizaremos as variáveis CSS correspondentes.
Aqui está o JavaScript necessário:
1 |
const wrapper = document.querySelector(".words"); |
2 |
const words = wrapper.querySelectorAll("span"); |
3 |
const currentWord = wrapper.querySelector("span.current"); |
4 |
const wordsWidths = Array.from(words).map((word) => word.offsetWidth); |
5 |
const maxWordsWidth = Math.max(...wordsWidths); |
6 |
const CURRENT_CLASS = "current"; |
7 |
const NEXT_CLASS = "next"; |
8 |
|
9 |
wrapper.style.setProperty("--width", `${currentWord.offsetWidth}px`); |
10 |
wrapper.style.setProperty("--width-mobile", `${maxWordsWidth}px`); |
11 |
|
12 |
setInterval(() => { |
13 |
const currentWord = wrapper.querySelector("span.current"); |
14 |
const nextWord = wrapper.querySelector("span.next"); |
15 |
const nextNextWord = nextWord.nextElementSibling |
16 |
? nextWord.nextElementSibling |
17 |
: wrapper.firstElementChild; |
18 |
currentWord.classList.remove(CURRENT_CLASS); |
19 |
nextWord.classList.remove(NEXT_CLASS); |
20 |
nextWord.classList.add(CURRENT_CLASS); |
21 |
nextNextWord.classList.add(NEXT_CLASS); |
22 |
wrapper.style.setProperty("--color", nextWord.dataset.color); |
23 |
wrapper.style.setProperty("--color-bg", nextWord.dataset.bgColor); |
24 |
wrapper.style.setProperty("--width", `${nextWord.offsetWidth}px`); |
25 |
}, 1500); |
Recomendo que você use o console do navegador para inspecionar as palavras e ver como elas se comportam.
Terminaremos com a seguinte demonstração:
Aqui está o que vamos criar. É um ótimo complemento para sites de portfólio ou seções principais para destacar coisas.
Conclusão
Neste tutorial, usamos variáveis CSS e JavaScript para construir um efeito de animação de texto onde certas palavras mudam após um período específico. Esperamos que isso inspire você a criar coisas ainda mais interessantes, alterando talvez mais de uma palavra simultaneamente, etc.
Como sempre, muito obrigado pela leitura!
Descubra mais efeitos de texto baseados em JavaScript
Interessado em efeitos de animação de texto mais criativos com JavaScript? Se sim, confira estes tutoriais: