Construindo Carrosséis Suaves com CSS Puro

Durante anos, criar carrosséis significava recorrer a bibliotecas JavaScript como Swiper ou Glide. Cada uma adicionava kilobytes ao seu bundle, introduzia dependências e exigia gerenciamento cuidadoso de event listeners e estado. Mas o CSS moderno evoluiu silenciosamente para lidar com carrosséis nativamente—sem necessidade de JavaScript.
Este artigo explora como construir carrosséis CSS performáticos e acessíveis usando scroll-snap, pseudo-elementos experimentais e outras técnicas de CSS puro que funcionam hoje e permanecerão relevantes por anos.
Principais Conclusões
- As propriedades scroll-snap transformam qualquer contêiner rolável em uma experiência de carrossel suave
- Pseudo-elementos experimentais no Chrome 135+ permitem controles de navegação nativos sem JavaScript
- Carrosséis CSS puro melhoram a performance ao eliminar parsing de JavaScript e event listeners
- Estratégias de fallback garantem compatibilidade enquanto se preparam para recursos futuros dos navegadores
A Base: Scroll Snap CSS
A pedra angular de qualquer carrossel CSS puro é a propriedade scroll-snap. Ela transforma um contêiner rolável em uma experiência paginada com apenas algumas linhas:
.carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
.carousel-item {
flex: 0 0 100%;
scroll-snap-align: center;
}
Isso cria um carrossel horizontal onde cada item se encaixa no lugar. A palavra-chave mandatory
garante que os usuários sempre pousem em um slide completo, enquanto scroll-behavior: smooth
adiciona transições fluidas entre os itens.
Scroll Snap CSS funciona em todos os navegadores modernos, tornando-o a base mais confiável para carrosséis sem JavaScript. Para designs responsivos, combine-o com CSS Grid ou ajuste o flex-basis para mostrar múltiplos itens por visualização:
.carousel-item {
flex: 0 0 calc(33.333% - 1rem);
margin: 0 0.5rem;
}
Navegação Moderna: Pseudo-Elementos Experimentais
O Chrome 135+ introduz pseudo-elementos experimentais que geram controles de carrossel automaticamente. Esses recursos requerem habilitar recursos experimentais da plataforma web nas flags do Chrome.
O pseudo-elemento ::scroll-button
cria botões anterior/próximo sem marcação adicional:
.carousel::scroll-button(inline-start),
.carousel::scroll-button(inline-end) {
background: rgba(0, 0, 0, 0.5);
color: white;
padding: 1rem;
border: none;
}
.carousel::scroll-button(inline-start)::before {
content: "←";
}
.carousel::scroll-button(inline-end)::before {
content: "→";
}
Da mesma forma, ::scroll-marker
gera pontos de paginação para cada seção rolável:
.carousel {
scroll-marker-group: after;
}
.carousel-item::scroll-marker {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
background: #ccc;
}
.carousel-item::scroll-marker:target-current {
background: #333;
}
Note que esses pseudo-elementos são experimentais e sua sintaxe pode mudar. A pseudo-classe :target-current
destaca o marcador ativo conforme os usuários rolam. Esses recursos reduzem os requisitos de JavaScript enquanto fornecem suporte nativo de acessibilidade.
Discover how at OpenReplay.com.
Estratégia de Fallback para Produção
Como scroll-button e scroll-marker têm suporte limitado nos navegadores, use detecção de recursos com @supports
:
/* Navegação de fallback */
.carousel-nav {
display: flex;
gap: 0.5rem;
}
/* Ocultar fallback quando controles nativos são suportados */
@supports (scroll-button-inline: both) {
.carousel-nav {
display: none;
}
}
Para maior compatibilidade, combine scroll-snap com links âncora para navegação:
<nav class="carousel-nav">
<a href="#slide1">1</a>
<a href="#slide2">2</a>
<a href="#slide3">3</a>
</nav>
<div class="carousel">
<div id="slide1" class="carousel-item">...</div>
<div id="slide2" class="carousel-item">...</div>
<div id="slide3" class="carousel-item">...</div>
</div>
Carrossel CSS com Autoplay Sem JavaScript
Criar um carrossel CSS com autoplay requer apenas animações keyframe:
@keyframes slide {
0%, 20% { transform: translateX(0); }
25%, 45% { transform: translateX(-100%); }
50%, 70% { transform: translateX(-200%); }
75%, 95% { transform: translateX(-300%); }
100% { transform: translateX(0); }
}
.autoplay-carousel {
display: flex;
animation: slide 12s infinite;
}
.autoplay-carousel:hover {
animation-play-state: paused;
}
Esta técnica funciona de forma confiável, mas troca controle do usuário por simplicidade. Pausar ao passar o mouse melhora a usabilidade, e combiná-la com prefers-reduced-motion
respeita as preferências de acessibilidade:
@media (prefers-reduced-motion: reduce) {
.autoplay-carousel {
animation: none;
}
}
Acessibilidade e Performance
Carrosséis CSS puro se destacam em performance—sem parsing de JavaScript, sem event listeners, sem layout thrashing. A rolagem nativa do navegador lida automaticamente com entradas de toque, teclado e mouse.
Para acessibilidade, garanta:
- Scroll-snap fornece rolagem suave, mas navegação completa por teclado e controles acessíveis requerem os novos recursos ::scroll-button e ::scroll-marker.
- Indicadores de foco permanecem visíveis
- Conteúdo permanece acessível quando o CSS falha
- Alvos de toque atendem ao tamanho mínimo de 44×44px
Adicione labels ARIA para melhorar a experiência de leitores de tela:
<div class="carousel" role="region" aria-label="Galeria de Produtos">
<div class="carousel-item" aria-label="Slide 1 de 3">...</div>
</div>
Conclusão
O CSS moderno eliminou a necessidade de bibliotecas JavaScript de carrossel na maioria dos casos. Scroll-snap fornece a base hoje, enquanto recursos emergentes como scroll-button e scroll-marker antecipam um futuro onde componentes de UI complexos não requerem JavaScript. Essas técnicas reduzem o tamanho dos bundles, melhoram a performance e simplificam a manutenção—benefícios que se acumulam ao longo do tempo.
Comece com scroll-snap para sites em produção. Experimente os novos pseudo-elementos no Chrome. Mais importante ainda, questione se você realmente precisa daquela biblioteca de carrossel de 50KB quando 20 linhas de CSS alcançam o mesmo resultado.
Perguntas Frequentes
Sim, as propriedades scroll-snap têm excelente suporte nos navegadores em todos os navegadores modernos. Os pseudo-elementos experimentais devem ser usados apenas com fallbacks adequados, pois atualmente funcionam apenas no Chrome 135+ com flags habilitadas.
Scroll-snap suporta automaticamente gestos de toque através da rolagem nativa do navegador. Os usuários podem deslizar naturalmente entre slides, e os pontos de snap obrigatórios garantem que sempre pousem em slides completos sem código adicional.
Carrosséis CSS continuam funcionando perfeitamente quando o JavaScript está desabilitado, pois dependem inteiramente de propriedades CSS nativas. Os usuários ainda podem navegar usando toque, mouse ou teclado, tornando-os mais resilientes do que soluções baseadas em JavaScript.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..