As animações CSS tornaram-se essenciais para o web design moderno. Em 2026, com a API View Transition, animações orientadas por rolagem e estilo @starting para animações de entrada agora suportadas em todos os principais navegadores, as animações CSS estão mais poderosas do que nunca. Este guia cobre tudo, desde transições básicas até animações avançadas de quadros-chave e novas APIs 2026.
📋 Table of Contents
Transições – Mudanças Simples de Estado
/* transition: property duration timing-function delay */
.button {
background: #0066CC;
transform: translateY(0);
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: background 200ms ease,
transform 150ms ease,
box-shadow 200ms ease;
}
.button:hover {
background: #0052A3;
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0,102,204,0.3);
}
.button:active {
transform: translateY(0);
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* Timing functions */
/* ease (default), linear, ease-in, ease-out, ease-in-out */
/* cubic-bezier(x1, y1, x2, y2) — custom curve */
.smooth { transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1); } /* ease-out-expo */
.bounce { transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1); } /* bounce */
Animações de quadro-chave
/* Define the animation */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Apply animations */
.hero-title {
animation: fadeInUp 600ms ease-out both; /* both = apply forwards and backwards fill */
}
.loading-icon {
animation: spin 1s linear infinite;
}
.highlight {
animation: pulse 2s ease-in-out infinite;
}
/* Stagger children animations */
.card-list .card {
animation: fadeInUp 400ms ease-out both;
}
.card-list .card:nth-child(1) { animation-delay: 0ms; }
.card-list .card:nth-child(2) { animation-delay: 100ms; }
.card-list .card:nth-child(3) { animation-delay: 200ms; }
.card-list .card:nth-child(4) { animation-delay: 300ms; }
@starting-style – Animações de entrada (2024+)
/* Animate elements entering the DOM */
dialog, [popover] {
opacity: 1;
transform: scale(1);
transition: opacity 200ms ease, transform 200ms ease,
display 200ms ease allow-discrete; /* allow display changes */
/* @starting-style defines state BEFORE element appears */
@starting-style {
opacity: 0;
transform: scale(0.95);
}
}
/* Exit animation via overlay::before-close (coming soon) */
/* Currently handle with JS class toggling */
Animações baseadas em rolagem (2024+)
/* Animate based on scroll position — NO JavaScript needed! */
@keyframes reveal {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.reveal-on-scroll {
animation: reveal linear both;
animation-timeline: view(); /* tied to element's position in viewport */
animation-range: entry 0% entry 30%; /* animate when 0-30% of element enters */
}
/* Progress bar tied to page scroll */
.reading-progress {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: #0066CC;
transform-origin: left;
animation: scaleX linear;
animation-timeline: scroll(root); /* tied to document scroll */
}
@keyframes scaleX {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
Ver API de transições
// Animate between page states or route changes
async function navigateTo(url) {
// Start transition
const transition = document.startViewTransition(async () => {
// Update the DOM here
const content = await fetchPage(url);
document.body.innerHTML = content;
});
// Wait for transition complete
await transition.finished;
}
// In Next.js / React — use experimental viewTransition
import { unstable_viewTransition as viewTransition } from 'react';
function handleNavigation() {
viewTransition(() => {
router.push('/new-page');
});
}
/* CSS controls the animation */
::view-transition-old(root) {
animation: slide-out 300ms ease-out;
}
::view-transition-new(root) {
animation: slide-in 300ms ease-out;
}
@keyframes slide-out {
to { transform: translateX(-100%); opacity: 0; }
}
@keyframes slide-in {
from { transform: translateX(100%); opacity: 0; }
}
/* Per-element transitions */
.hero-image {
view-transition-name: hero; /* matched between pages */
}
/* Browser automatically morphs .hero-image between pages! */
Dicas de desempenho
- Animar apenas propriedades compatíveis com o compositor:
transformandopacity - Evite animar: largura, altura, topo, esquerda, margem, preenchimento – causam layout
- Use will-change com moderação:
will-change: transformpromove para a camada GPU - Respeite o movimento reduzido:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Comparação da Biblioteca de Animação
| Ferramenta | Usar quando |
|---|---|
| Transições CSS | Efeitos simples de foco, mudanças de estado |
| Quadros-chave CSS | Animações em loop, carregamento de spinners |
| API orientada por rolagem | Revelar na rolagem, barras de progresso |
| Ver transições | Transições de página/rota |
| Movimento do enquadrador | Animações e gestos complexos do React |
| GSAP | Animações complexas da linha do tempo, ScrollTrigger |
As animações CSS em 2026 podem lidar com 80% das necessidades de animação sem JavaScript. Use transições CSS para estados de foco, quadros-chave para loops e entradas, animações orientadas por rolagem para efeitos de revelação e a API View Transitions para transições de página suaves. Use Framer Motion ou GSAP somente quando o CSS não conseguir lidar com a complexidade.
🔗 Share this article
✍️ Leave a Comment