Carlos A. Gomes

Como criar um plugin de Carrossel de imagens com css puro

Atualizado -Publicado

Existem vários plugins para jQuery, React e até mesmo Angular para criar um carrossel de imagens, mas é possível criar utilizando apenas CSS puro.

Elementos de um carrossel

Elementos de um carrossel

  • Stage: A área disponível para o carrossel
  • Item: O item visível atualmente pelo usuário
  • Next/Prev Buttons: Os botões para passar aos items anteriores/próximos, que normalmente estão ocultos

Updates:

  • 2021-01-25
    • movido código para CodeSandbox
    • revisão do texto do post
    • grande redução no código fonte

Conceito

Vamos utilizar inputs do tipo radio, que estarão ocultos para os usuários, em conjunto com a tag label com o atributo for="", que ao ser clicada, automaticamente checa um radio que tenha o id correspondente.

Todos os input radio terão o mesmo atributo name, assim o próprio navegador se encarrega de desmarcar e marcar os radios sem a necessidade de JavaScript.

Estrutura HTML do carrossel de images

Utilizaremos 4 inputs do tipo rádio pra controlar 4 imagens no carrossel. Repare que o primeiro item não tem o botão “anterior” e o último não tem o botão “próximo”.

 1<section class="carousel">
 2  <input type="radio" name="carousel" id="carousel1" checked="checked" />
 3  <input type="radio" name="carousel" id="carousel2" />
 4  <input type="radio" name="carousel" id="carousel3" />
 5  <input type="radio" name="carousel" id="carousel4" />
 6
 7  <main class="carousel__stage">
 8    <aside class="carousel__item">
 9      <img class="carousel__image" src="images/forest-1.jpg" />
10      <label for="carousel2" class="carousel__next carousel__control"></label>
11    </aside>
12
13    <aside class="carousel__item">
14      <label for="carousel1" class="carousel__prev carousel__control"></label>
15      <img class="carousel__image" src="images/sun-clouds.jpg" />
16      <label for="carousel3" class="carousel__next carousel__control"></label>
17    </aside>
18
19    <aside class="carousel__item">
20      <label for="carousel2" class="carousel__prev carousel__control"></label>
21      <img class="carousel__image" src="images/tree.jpg" />
22      <label for="carousel4" class="carousel__next carousel__control"></label>
23    </aside>
24
25    <aside class="carousel__item">
26      <label for="carousel3" class="carousel__prev carousel__control"></label>
27      <img class="carousel__image" src="images/flower.jpg" />
28    </aside>
29  </main>
30</section>

A primeira coisa que precisamos fazer é ocultar os inputs para o usuário. Será utilizada a técnica de mover o elemento para fora do viewport, pois alguns navegadores tratam inputs “ocultos” como estando desabilitados.
Desta maneira o input fica invisível, mas ainda é um elemento válido para os navegadores.

1.carousel input {
2  position: absolute;
3  left: -10000px;
4}

Vamos deixar o carrossel responsivo:

 1.carousel {
 2  width: 80%;
 3  height: 80%;
 4  margin: 0 auto;
 5}
 6
 7.carousel__stage {
 8  overflow: hidden;
 9  font-size: 0;
10  white-space: nowrap;
11  width: 100%;
12  height: 100%;
13  transition: text-indent 500ms;
14  position: relative;
15}
16
17.carousel__item {
18  display: inline-block;
19  text-indent: 0;
20  width: 100%;
21  height: 100%;
22}
23
24.carousel__image {
25  width: 100%;
26  height: 100%;
27  object-fit: cover;
28}

Posicionamento dos botões Próximo / Anterior. Repare que o elemento stage é quem tem posicionamento relative, então todos os botões serão alinhados a ele.
Como os botões terão sua visibilidade oculta por padrão, ao movimentarmos de um item para o outro, vamos exibir os botões corretamente, dando uma ilusão para o usuário que o botão não mudou.

 1.carousel__control {
 2  display: none;
 3  position: absolute;
 4  top: 50%;
 5  color: #fff;
 6  background: rgba(255, 255, 255, 0.3);
 7  z-index: 1;
 8  font-size: 1rem;
 9  padding: 20px;
10  cursor: pointer;
11}
12
13.carousel__prev {
14  left: 0;
15}
16
17.carousel__prev::after {
18  content: ' << ';
19  display: inline-block;
20}
21
22.carousel__next {
23  right: 0;
24}
25
26.carousel__next::after {
27  content: ' >> ';
28  display: inline-block;
29}

Agora é aonde a mágica começa.

Será utilizado o seletor :checked do css para sabermos qual é o input radio que está selecionado no momento.

Utilizando a propriedade text-indent do CSS é possível movimentarmos o stage e dar a impressão de animação.

Nesta etapa temos que fazer um seletor para cada “estado” da animação:

 1#carousel1:checked ~ .carousel__stage {
 2  text-indent: 0;
 3}
 4
 5#carousel2:checked ~ .carousel__stage {
 6  text-indent: -100%;
 7}
 8
 9#carousel3:checked ~ .carousel__stage {
10  text-indent: -200%;
11}
12
13#carousel4:checked ~ .carousel__stage {
14  text-indent: -300%;
15}

Para finalizar, vamos fazer a mágica de só mostrar os botões Próximo / Anterior referentes ao item atual no stage:

1#carousel1:checked ~ .carousel__stage .carousel__item:nth-child(1) .carousel__control,
2#carousel2:checked ~ .carousel__stage .carousel__item:nth-child(2) .carousel__control,
3#carousel3:checked ~ .carousel__stage .carousel__item:nth-child(3) .carousel__control,
4#carousel4:checked ~ .carousel__stage .carousel__item:nth-child(4) .carousel__control {
5  display: block;
6}

Resultado final

Você pode conferir o código fonte do exemplo aqui:
https://codesandbox.io/s/carousel-with-css-only-nshhx

Continue lendo: