Como Construir uma Galeria de Imagens Responsiva com slick.js
() translation by (you can also view the original English article)
Nesse tutorial nós vamos utilizar o slick.js, um plugin jQuery para construir galerias de imagem responsivas. Aqui está a galeria que nós vamos criar:
Tenha a certeza de que você conferiu a versão em tela cheia, e mude o tamanho da tela do seu browser para ver como layout muda dependendo do tamanho da janela.
O que é slick.js?
Slick.js é um já conhecido plugin jQuery creado por Ken Wheeler que nos permite criar lindos carrosséis de imagens. Para entender melhor o que esse plugin pode nos oferecer, confira sua documentação.
Felizmente, ele funciona não só nos navegadores mais modernos, mas também em alguns dos mais velhos como IE 8+.
Finalmente, você pode querer dar uma olhada na versão para WordPress.
Começando com slick.js
Para iniciar com o slick, comece baixando e instalando os seguintes arquivos no seu projeto:
- jQuery (≥1.7)
-
slick.css
ou sua versão minificada
-
slick.js
ou sua versão minificada
De forma opcional, você pode querer importar o arquivo slick-theme.css
.
Você pode pegar uma cópia dos arquivos correspondentes do slicks visitando seu repositório no GitHub, usando um gerenciador de pacotes (por exemplo, npm) ou carregando os arquivos necessários através de uma CDN (por exemplo, cdnjs). Para este tutorial, eu vou escolher a última opção.
Além disso, eu incorporei o Babel para compilar o código ES6 para ES5 e o Lodash para tirar vantagem de sua função debounce
(usaremos isso mais tarde).
Com isso em mente, se você olhar sob a guia de configurações (Settings) do nosso exemplo, você verá que eu inclui um arquivo CSS externo e três arquivos JavaScript externos.






1. O HTML
Neste ponto é importante compreender a estrutura da nossa página. De maneira geral, definiremos dois carrosséis que têm as mesmas imagens e são sincronizados (discutiremos como mais tarde). As dimensões das imagens são de 860 x 550 pixels, embora em seus próprios projetos, esses tamanhos possam ser diferentes.
Por último, como parte do segundo carrossel, nós especificaremos as setas de navegação, bem como um elemento que mantém controle sobre número total de slides.
Aqui está a estrutura necessária para a nossa página de demonstração:
1 |
<div class="loading">Carousel is loading...</div> |
2 |
<div class="container"> |
3 |
<div class="synch-carousels"> |
4 |
|
5 |
<div class="left child"> |
6 |
<div class="gallery"> |
7 |
<div class="item"> |
8 |
<img src="IMG_SRC" alt=""> |
9 |
</div>
|
10 |
<!-- 4 more images here -->
|
11 |
</div>
|
12 |
</div><!--/left--> |
13 |
|
14 |
<div class="right child"> |
15 |
<div class="gallery2"> |
16 |
<div class="item"> |
17 |
<img src="IMG_SRC" alt=""> |
18 |
</div>
|
19 |
<!-- 4 more images here -->
|
20 |
</div>
|
21 |
<div class="nav-arrows"> |
22 |
<button class="arrow-left"> |
23 |
<!--svg here-->
|
24 |
</button>
|
25 |
<button class="arrow-right"> |
26 |
<!--svg here-->
|
27 |
</button>
|
28 |
</div>
|
29 |
<div class="photos-counter"> |
30 |
<span></span><span></span>
|
31 |
</div>
|
32 |
</div><!--/right--> |
33 |
|
34 |
</div>
|
35 |
</div>
|
2. O CSS
No total, nossa galeria deve ter quatro aparências diferentes, dependendo do tamanho de tela disponível. Vamos visualizá-las seguindo, primeiro, uma abordagem mobile.
Quando a janela do navegador é menor que 480px, ela deve parecer com isto, com apenas o segundo carrossel e as setas de navegação sendo mostradas:



Em seguida, em telas entre 480px e 768px, a aparência deve ser da seguinte maneira, com duas miniaturas sob o slide principal:



Em seguida, em telas entre 769px e 1023px, apresentaremos uma miniatura de terceira imagem:



Finalmente, em grandes telas (≥1024px), o layout deve ser da seguinte maneira, com as miniaturas aparecendo ao lado (note que elas não se encaixam perfeitamente nesta imagem):



Todos os casos acima são atendidos no código mostrado abaixo mostrado abaixo:
1 |
.synch-carousels { |
2 |
position: relative; |
3 |
display: flex; |
4 |
flex-wrap: wrap; |
5 |
justify-content: space-between; |
6 |
}
|
7 |
|
8 |
.synch-carousels > * { |
9 |
width: 100%; |
10 |
}
|
11 |
|
12 |
.synch-carousels .right { |
13 |
order: -1; |
14 |
}
|
15 |
|
16 |
.synch-carousels .left { |
17 |
overflow: hidden; |
18 |
}
|
19 |
|
20 |
.synch-carousels .gallery { |
21 |
display: none; |
22 |
}
|
23 |
|
24 |
.synch-carousels .gallery .slick-list { |
25 |
height: auto !important; |
26 |
margin: 0 -20px; |
27 |
}
|
28 |
|
29 |
.synch-carousels .gallery .slick-slide { |
30 |
margin: 0 20px; |
31 |
}
|
32 |
|
33 |
@media screen and (min-width: 480px) { |
34 |
.synch-carousels .right { |
35 |
margin-bottom: 20px; |
36 |
}
|
37 |
|
38 |
.synch-carousels .gallery { |
39 |
display: block; |
40 |
}
|
41 |
}
|
42 |
|
43 |
@media screen and (min-width: 1024px) { |
44 |
.synch-carousels .right { |
45 |
position: relative; |
46 |
width: calc(100% - 230px); |
47 |
margin-bottom: 0; |
48 |
order: 2; |
49 |
}
|
50 |
|
51 |
.synch-carousels .left { |
52 |
width: 210px; |
53 |
}
|
54 |
|
55 |
.synch-carousels .gallery .slick-slide { |
56 |
margin: 0 0 20px 0; |
57 |
}
|
58 |
|
59 |
.synch-carousels .gallery .slick-list { |
60 |
margin: 0; |
61 |
}
|
62 |
}
|
Observe que há uma regra !important
. Isso substitui um estilo do slick.
3. O JavaScript
Vamos agora voltar nossa atenção para as coisas relacionadas com JavaScript.
Seletores
Quando o DOM está pronto, é uma boa prática colocar em cache alguns dos seletores mais utilizados:
1 |
const $left = $(".left"); |
2 |
const $gl = $(".gallery"); |
3 |
const $gl2 = $(".gallery2"); |
4 |
const $photosCounterFirstSpan = $(".photos-counter span:nth-child(1)"); |
Inicializando os Carrosséis
Então, podemos inicializar e sincronizar nossos dois carrosséis. O código responsável por este comportamento é o seguinte:
1 |
$gl.slick({ |
2 |
rows: 0, |
3 |
slidesToShow: 2, |
4 |
arrows: false, |
5 |
draggable: false, |
6 |
useTransform: false, |
7 |
mobileFirst: true, |
8 |
responsive: [ |
9 |
{
|
10 |
breakpoint: 768, |
11 |
settings: { |
12 |
slidesToShow: 3 |
13 |
}
|
14 |
},
|
15 |
{
|
16 |
breakpoint: 1023, |
17 |
settings: { |
18 |
slidesToShow: 1, |
19 |
vertical: true |
20 |
}
|
21 |
}
|
22 |
]
|
23 |
});
|
24 |
|
25 |
$gl2.slick({ |
26 |
rows: 0, |
27 |
useTransform: false, |
28 |
prevArrow: ".arrow-left", |
29 |
nextArrow: ".arrow-right", |
30 |
fade: true, |
31 |
asNavFor: $gl |
32 |
});
|
Sem dúvida, a melhor maneira de entender como funciona esse código é ler a documentação slick. No entanto, deixe-me explicar duas coisas importantes aqui:
- A opção de configuração
asNavFor
permite sincronizar os carrosséis e usar um como dispositivo de navegação para o outro. - Por padrão, o slick usa transformações CSS. No nosso caso, podemos desabilitá-las, definindo o
useTransform: false
. Isto é necessário porque eles causam uma pequena dessincronização no primeiro slide do primeiro carrossel em telas grandes (nós poderíamos tê-lo desativado apenas para o primeiro carrossel).
Exibindo e Personalizando o Layout da Galeria
Nossa galeria deve ser visível somente quando todos os arquivos da página estiverem prontos. Inicialmente, um pré-carregamento opcional aparece – isso pode ser feito da seguinte maneira:
1 |
<div class="loading">Carousel is loading...</div> |
Neste ponto, temos que pensar novamente sobre o layout desejado para a galeria em grandes telas. Se você olhar para as imagens correspondentes, você notará que os dois carrosséis têm a mesma altura. A fim de alcançar o comportamento desejado, precisamos escrever algum código JavaScript personalizado (além do nosso CSS). Esse código vai, dinamicamente, definir a altura do primeiro carrossel igual à altura do segundo (ou vice-versa).
Conhecendo os requisitos acima, aqui está o código que é executado quando a página inteira está pronta:
1 |
$(window).on("load", () => { |
2 |
handleCarouselsHeight(); |
3 |
setTimeout(() => { |
4 |
$(".loading").fadeOut(); |
5 |
$("body").addClass("over-visible"); |
6 |
}, 300); |
7 |
});
|
E aqui está a declaração da função handleCarouselsHeight
:
1 |
function handleCarouselsHeight() { |
2 |
if (window.matchMedia("(min-width: 1024px)").matches) { |
3 |
const gl2H = $(".gallery2)").height(); |
4 |
$left.css("height", gl2H); |
5 |
} else { |
6 |
$left.css("height", "auto"); |
7 |
}
|
8 |
}
|
Quando a página for carregada, a galeria funciona bem. Mas também deve funcionar como esperado quando a janela do navegador é redimensionada.
O código que lida com essa situação específica é mostrado abaixo:
1 |
$(window).on( |
2 |
"resize", |
3 |
_.debounce(() => { |
4 |
handleCarouselsHeight(); |
5 |
}, 200) |
6 |
);
|
Observe que o manipulador de eventos é encapsulado dentro de uma função debounce
. Essa é uma função Lodash que nos ajuda a restringir a quantidade de vezes que esse manipulador é chamado.
Trabalhando com Eventos e Métodos slick
Agora que nós já implementamos com sucesso a principal funcionalidade da nossa galeria, vamos dar um passo adiante e construir algumas coisas opcionais.
Primeiro, no canto superior direito do segundo carrossel exibimos o slide atual e o número total de slides.



Para fazer isso, aproveitaremos dos eventos init
e afterChange
do slick.
Aqui está o código relacionado:
1 |
/*you have to bind init event before slick's initialization (see demo) */
|
2 |
gl2.on("init", (event, slick) => { |
3 |
$photosCounterFirstSpan.text(`${slick.currentSlide + 1}/`); |
4 |
$(".photos-counter span:nth-child(2)").text(slick.slideCount); |
5 |
});
|
6 |
|
7 |
$gl2.on("afterChange", (event, slick, currentSlide) => { |
8 |
$photosCounterFirstSpan.text(`${slick.currentSlide + 1}/`); |
9 |
});
|
Como uma melhoria, cada vez que clicamos em um slide do primeiro carrossel, o slide associado do segundo carrossel deve ser ativo. Graças ao método slickGoTo
do slick, somos capazes de desenvolver esta funcionalidade.
Aqui está o código relacionado:
1 |
$(".gallery .item").on("click", function() { |
2 |
const index = $(this).attr("data-slick-index"); |
3 |
$gl2.slick("slickGoTo", index); |
4 |
});
|
4. Suporte de Navegador
O demo deve funcionar bem em todos os navegadores recentes e você pode usá-lo com segurança em seus projetos.
Só encontrei um pequeno bug em alguns browsers (Firefox, Edge) ao testar o demo em grandes telas. Ao clicar sobre as setas de navegação, todos os slides do primeiro carrossel falham ao não atingir a parte superior de seu elemento-pai, deixando uma lacuna de pixel único:



Por último mas não menos importante, pequenas melhorias e personalizações podem ser necessárias à medida que a janela é redimensionada, dependendo de suas necessidades.
Conclusão
Neste tutorial, nós utilizamos o slick.js e conseguimos construir uma bela galeria responsiva. Assim, espero que agora você esteja pronto para testar essa implementação em seus próprios projetos. Se isso acontecer, sinta-se livre para compartilhar o link nos comentários abaixo!
Mais Projetos de JavaScript para Apimentar seus Sites
- DesempenhoMelhoria de Desempenho: Como Carregar Imagens Usando o in-view.jsLouie Rootfield
- FlickityConstrua um Slider com o Metafizzy’s FlickityThoriq Firdaus
- jQueryDica Rápida: Animações de Rolagem com fullPage.js e Animate.cssGeorge Martsoukos
- JavaScriptComo Criar um Slider de Tela-Dividida com JavaScriptAdi Purdila