How to create an image gallery in Svelte (carousel)
Introduction
In this article we will see how to create an image gallery in Svelte (carousel gallery) in a very simple way, creating your own component and without the need for external plugins or libraries.
Let’s go! 💃🏻
Create a new Svelte project
To create a project in Svelte, let’s remember, with the following command:
npx degit sveltejs/template <Nombre_del_proyecto>
For the example I will call the project galeria-svelte
:
npx degit sveltejs/template galeria-svelte
Degit
clones just the published git workspace and not the git repo.
Then, we only have to install the dependencies with yarn install
or npm install
(that’s your choice, I’ll use NPM).
cd galeria-svelte
npm install
Well. We already have our new project installed to create our awesome image gallery 🙃 If you run npm run dev you should see your project in
Well. We already have our new project installed to create our awesome image gallery galería de imágenes 🙃 If you run npm run dev
you should see your project in http://localhost:5000/
:
<Carousel />
Component
We are going to create our basic component to view our gallery, which we will call it Carousel
:
// Carousel.svelte
<script>
export let images;
</script>
As you can see, with export let images
we are telling the component that we will props a variable (which will be an array of images) called images
.
<!-- Carousel.svelte -->
<div class="carousel">
<div class="carousel__container">
{#each images as image (image.id)}
<img src={image.path} alt={image.alt} id={image.id} height="100" />
{/each}
</div>
</div>
The html is very simple at the moment. We make a loop of the array of images that we receive by parameter and we put an image for each item.
/* Carousel.svelte */
<style>
.carousel {
display: flex;
overflow-x: auto;
position: relative;
width: 100%;
}
.carousel__container {
display: flex;
}
</style>
And finally we give it a bit of style, to see all the images next to each other, and in the event that we have more images and they do not fit the width of the page, make us a horizontal scroll.
The complete Carousel.svelte
would be as follows:
<script>
export let images;
</script><div class="carousel">
<div class="carousel__container">
{#each images as image (image.id)}
<img src={image.path} alt={image.alt} id={image.id} height="100" />
{/each}
</div>
</div><style>
.carousel {
display: flex;
overflow-x: auto;
position: relative;
width: 100%;
}
.carousel__container {
display: flex;
}
</style>
How can I use my <Carousel /> component?
To use a component in Svelte, as in other JavaScript frameworks is very very VERY easy. We import the component and call it as an html tag. Let’s see it with an example, for this we will edit the example src/App.svelte
file that Svelte itself generates when creating the project.
We will leave it as follows:
<script>
import Carousel from './Carousel.svelte';
const images = [
{
path: 'https://picsum.photos/id/1012/3973/2639',
id: 'imagen-ejemplo-1',
alt: 'Atributo ALT de ejemplo para la imagen #1',
},
{
path: 'https://picsum.photos/id/1005/5760/3840',
id: 'imagen-ejemplo-2',
alt: 'Atributo ALT de ejemplo para la imagen #2',
},
{
path: 'https://picsum.photos/id/1020/4288/2848',
id: 'imagen-ejemplo-3',
alt: 'Atributo ALT de ejemplo para la imagen #3',
},
{
path: 'https://picsum.photos/id/1025/4951/3301',
id: 'imagen-ejemplo-4',
alt: 'Atributo ALT de ejemplo para la imagen #4',
},
{
path: 'https://picsum.photos/id/103/2592/1936',
id: 'imagen-ejemplo-5',
alt: 'Atributo ALT de ejemplo para la imagen #5',
},
{
path: 'https://picsum.photos/id/104/3840/2160',
id: 'imagen-ejemplo-6',
alt: 'Atributo ALT de ejemplo para la imagen #6',
},
];
</script><main>
<h2 class="item__title">Mi galería de ejemplo</h2>
<div class="item__gallery">
<Carousel {images} />
</div>
<p class="item__description">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae ipsum
possimus accusamus aut, assumenda fuga labore provident, non molestiae
recusandae harum, fugit neque nisi quos qui nulla. Non, quaerat officia.
</p>
</main><style>
main {
padding: 1em;
max-width: 800px;
margin: 0 auto;
}
</style>
As you can see, we import the component with import Carousel from './Carousel.svelte';
and we define an array of images with three attributes (path, id, alt). And we invoke the Carousel
component passing it the array of images that we have defined previously:
<Carousel {images} />
If everything has worked correctly, surely it will 🕵🏻♂️, you should see our first image carousel:
Easy, right?
Parameterize the component
The grace of the components is that we may want to reuse them in other parts of the web, with different parameters and style, right? For example, in our case, we might want different image sizes for one gallery or another, or a separation between images, or both!
Go for it.
Variable image size in our gallery
We are going to define a new imageHeight
parameter in our Carousel.svelte that will be the maximum size of the images:
// ...
// Maximum default height of 150px
export let imageHeight = 150;
// ...
And we pass it to the html in the following way:
<!-- ... -->
<img
src={image.path}
alt={image.id}
id={image.id}
style={`height: ${imageHeight}px;`}
/>
<!-- ... -->
Delete the
height="100"
property that we initially passed to it because now we are going to pass it to it dynamically. I add it to the style tag because then we will pass it another css property 🙃
And now we can create our galleries with different image sizes.
Image gallery with 200px height
<Carousel {images} imageHeight={200} />
Image gallery with 275px height
<Carousel {images} imageHeight={275} />
And of course you can reuse the component and put two galleries with different sizes:
<Carousel {images} imageHeight={205} />
<Carousel {images} />
Note that I have not passed the
imageHeight
property to the secondCarousel
, so it takes 150 by default, which is the default value declared inCarousel.svelte
🎉
Spacing between images
Let’s do another little configuration. We are going to separate the images from each other or not. For this we will use a new property called imageSpacing
:
// ...
// By default the images are not separated
export let imageSpacing = 0;
// ...
And we pass it to the html in the following way:
<!-- ... -->
<img
src={image.path}
alt={image.id}
id={image.id}
style={`height: ${imageHeight}px; margin-right: ${imageSpacing}px`}
/>
<!-- ... -->
And now we can create our galleries with the images separated by the remaining pixels, for example:
Image gallery 140px high and 3px separated
<Carousel {images} imageHeight={140} imageSpacing={3} />
As you will see, its configuration and use is very simple.
Final code
Finally the component should have been like this:
<script>
export let images;
export let imageHeight = 150;
export let imageSpacing = 0;
</script><div class="carousel">
<div class="carousel__container">
{#each images as image (image.id)}
<img
src={image.path}
alt={image.alt}
id={image.id}
style={`height: ${imageHeight}px; margin-right: ${imageSpacing}px`}
/>
{/each}
</div>
</div><style>
.carousel {
display: flex;
overflow-x: auto;
position: relative;
width: 100%;
}
.carousel__container {
display: flex;
}
</style>
Repository in Github
Repo: https://github.com/alextomas80/galeria-imagenes-svelte
And that’s all. I hope it can serve you 😉