1. Web Design
  2. HTML/CSS
  3. Bootstrap

How to Build a Responsive Slider With Swiper.js

Scroll to top
Read Time: 10 min

Have you ever built an advanced slider for a project? If so, you might have taken advantage of any one of a number of JavaScript carousels. In the past, I’ve covered two of them: slick and Owl. Today, I’ll introduce another well-known one: Swiper.

Our Slider Project

Check what we’ll be building:

Be sure to open the demo on a large screen and resize your window to see how the page layout changes.

What is Swiper Slider?

Swiper is a free JavaScript plugin created by Vladimir Kharlampidi that lets you create modern, responsive sliders.

The Swiper logo

With almost 30k GitHub stars at the time of this writing, it’s considered one of the most dominant JavaScript plugins out there. To better understand its capabilities, check out the available demos.

Swiper isn’t only available for use with pure JavaScript. If you plan to build an app with one of the popular JavaScript frameworks (e.g. React) and need a slider, consider looking at the associated built-in Swiper component.

Getting Started With Swiper

To get started with Swiper, begin by downloading and installing the following files in your project:

  • swiper-bundle.css or its minified version
  • swiper-bundle.js or its minified version

You can grab a copy of these Swiper files by visiting the GitHub repo, using a package manager (e.g. npm), or loading the necessary assets through a CDN (e.g. cdnjs). For this tutorial, I’ll choose the last option.

For this tutorial, beyond the Swiper files, I’ve also incorporated Bootstrap 5’s CSS file.

With that in mind, if you look under the Settings tab of our demo pen, you’ll see that there are two external CSS files and one external JavaScript file.

The required CSS assetsThe required CSS assetsThe required CSS assets
The required JS assetThe required JS assetThe required JS asset

1. Identify the Layout

To get started, let’s first identify the project scope.

Today’s demo is a web page dedicated to Tanzania, a country with immense beauty. To set up the page, we’ll grab some content from Wikipedia and images from Unsplash.

Let’s determine how the page layout will appear on various screens.

The Mobile Layout

On small screens (<768px), its appearance will be like this:

The mobile layoutThe mobile layoutThe mobile layout

Notice that each slider shows the first slide and half of the second one.

The Tablet Layout

Next, on medium screens (768px), its appearance will change as follows:

The tablet layoutThe tablet layoutThe tablet layout

Notice that the first slider shows the first two slides and half of the third one, while the second slider still shows two slides.

The Desktop Layout

Finally, on large screens (1200px), it will have this appearance:

The desktop layoutThe desktop layoutThe desktop layout

Again, consider that the first slider shows the first three slides and half of the fourth one, while the second slider shows the first two slides and half of the third one.

Also, pay attention to another thing: the right side of the first slider is aligned to the container width that, as we’ll see, will be 1100px. In the same way, the left slide of the second slider is aligned to the container width.

The red area indicates the empty space that will be increased as the viewport becomes bigger and bigger.

2. Define the HTML Markup

The markup for our page will consist of four sections:

  • The first and third sections will contain info about Tanzania taken from Wikipedia.
  • The second and fourth sections will include two equal carousels that will display Tanzania through Unsplash photos. These sections will only have a different class that will determine their layout. That said, the second section will have the section-with-right-offset class, while the fourth section the section-with-left-offset one. 

Here’s the page structure:

1
<section class="mt-5">
2
  <div class="container">...</div>
3
</section>
4
5
<section class="section-with-carousel section-with-right-offset position-relative mt-5">
6
  <div class="container">
7
    <h2 class="mb-3">...</h2>
8
  </div> 
9
  <div class="carousel-wrapper">
10
    <div class="swiper">
11
      <div class="swiper-wrapper">
12
        <div class="swiper-slide">
13
          <figure>
14
            <img width="640" height="480" src="tanzania1.jpg" alt="">
15
            <figcaption>
16
              <svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20">
17
                <path d="M12 13.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z"></path>
18
                <path fill-rule="evenodd" d="M19.071 3.429C15.166-.476 8.834-.476 4.93 3.429c-3.905 3.905-3.905 10.237 0 14.142l.028.028 5.375 5.375a2.359 2.359 0 003.336 0l5.403-5.403c3.905-3.905 3.905-10.237 0-14.142zM5.99 4.489A8.5 8.5 0 0118.01 16.51l-5.403 5.404a.859.859 0 01-1.214 0l-5.378-5.378-.002-.002-.023-.024a8.5 8.5 0 010-12.02z"></path>
19
              </svg>
20
              Nungwi, Zanzibar, Tanzania
21
            </figcaption>
22
          </figure>
23
        </div>
24
        <!-- more slides here -->
25
      </div>
26
    </div>
27
  </div>
28
  <div class="carousel-controls">
29
    <button class="carousel-control carousel-control-left" type="button">
30
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="40" height="40">
31
        <path fill-rule="evenodd" d="M10.78 19.03a.75.75 0 01-1.06 0l-6.25-6.25a.75.75 0 010-1.06l6.25-6.25a.75.75 0 111.06 1.06L5.81 11.5h14.44a.75.75 0 010 1.5H5.81l4.97 4.97a.75.75 0 010 1.06z"></path>
32
      </svg>
33
    </button>
34
    <button class="carousel-control carousel-control-right" type="button">
35
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="40" height="40">
36
        <path fill-rule="evenodd" d="M13.22 19.03a.75.75 0 001.06 0l6.25-6.25a.75.75 0 000-1.06l-6.25-6.25a.75.75 0 10-1.06 1.06l4.97 4.97H3.75a.75.75 0 000 1.5h14.44l-4.97 4.97a.75.75 0 000 1.06z"></path>
37
      </svg>
38
    </button>
39
  </div>
40
  <div class="swiper-pagination"></div>
41
</section>
42
43
<section class="mt-5">
44
  <div class="container">...</div>
45
</section>
46
47
<section class="section-with-carousel section-with-left-offset position-relative mt-5">
48
  <!-- content same as second section -->
49
</section>

3. Specify the Main Styles

Let’s now concentrate on the most important styles of our page.

Here are the remarkable things:

  • The container will have a maximum width of 1100px.
  • The initial dimensions of the Unsplash images won't be equal. With that in mind, the carousel images will have a fixed height that will vary across the screen sizes. Here we'll use the object-fit: cover property value for fitting the images within the container. Alternatively, we could have added the images as background ones.
  • By default, all image captions will be hidden apart from the caption of the active slide. As the active slide changes, the associated caption will appear with small slide animation.

Here are the associated styles:

1
.container {
2
  max-width: 1100px;
3
}
4
5
.section-with-carousel .swiper-slide figure {
6
  position: relative;
7
  overflow: hidden;
8
}
9
10
.section-with-carousel .swiper-slide img {
11
  width: 100%;
12
  height: 320px;
13
  object-fit: cover;
14
}
15
16
.section-with-carousel .swiper-slide figcaption {
17
  position: absolute;
18
  bottom: 0;
19
  left: 0;
20
  right: 0;
21
  transform: translateY(20%);
22
  display: flex;
23
  align-items: baseline;
24
  justify-content: center;
25
  padding: 20px;
26
  text-align: center;
27
  opacity: 0;
28
  visibility: hidden;
29
  color: white;
30
  background: rgba(0, 0, 0, 0.5);
31
  transition: all 0.4s;
32
}
33
34
.section-with-carousel .swiper-slide figcaption svg {
35
  flex-shrink: 0;
36
  fill: white;
37
  margin-right: 10px;
38
}
39
40
.section-with-carousel .swiper-slide-active figcaption {
41
  opacity: 1;
42
  visibility: visible;
43
  transform: none;
44
}
45
46
.section-with-carousel .carousel-controls {
47
  position: absolute;
48
  top: 50%;
49
  left: 0;
50
  right: 0;
51
  transform: translateY(-50%);
52
  display: flex;
53
  justify-content: space-between;
54
  padding: 0 12px;
55
  z-index: 1;
56
}
57
58
.section-with-carousel .carousel-controls .carousel-control {
59
  opacity: 0.25;
60
  transition: opacity 0.3s;
61
}
62
63
.section-with-carousel .carousel-controls .carousel-control:hover {
64
  opacity: 1;
65
}
66
67
@media (min-width: 768px) {
68
  .section-with-carousel .swiper-slide img {
69
    height: 370px;
70
  }
71
}
72
73
@media (min-width: 1200px) {
74
  .section-with-carousel .swiper-slide img {
75
    height: 420px;
76
  }
77
  
78
  .section-with-carousel .carousel-controls {
79
    padding: 0 50px;
80
  }
81
}

Customize Dot Navigation

The initial appearance of the dot navigation is this one:

The default dots navigation

Why not make it more informative and attractive? To achieve this, we’ll add some styles and update its default markup during the plugin initialization.

Here’s the updated navigation:

The dots navigation after adding styles

The required styles:

1
.section-with-carousel .swiper-pagination-bullets {
2
  position: static;
3
  display: flex;
4
  justify-content: center;
5
  margin-top: 10px;
6
}
7
8
.section-with-carousel .swiper-pagination-bullets .swiper-pagination-bullet {
9
  display: flex;
10
  flex-direction: column;
11
  align-items: center;
12
  justify-content: center;
13
  width: auto;
14
  height: auto;
15
  background: transparent;
16
  opacity: 0.5;
17
  margin: 0 8px;
18
  border-radius: 0;
19
  transition: opacity 0.3s;
20
}
21
22
.section-with-carousel
23
  .swiper-pagination-bullets
24
  .swiper-pagination-bullet
25
  .line {
26
  width: 3px;
27
  height: 3px;
28
  background: black;
29
  transition: transform 0.3s;
30
}
31
32
.section-with-carousel
33
  .swiper-pagination-bullets
34
  .swiper-pagination-bullet
35
  .number {
36
  opacity: 0;
37
  transform: translateY(-7px);
38
  transition: all 0.3s;
39
}
40
41
.section-with-carousel
42
  .swiper-pagination-bullets
43
  .swiper-pagination-bullet.swiper-pagination-bullet-active {
44
  opacity: 1;
45
}
46
47
.section-with-carousel
48
  .swiper-pagination-bullets
49
  .swiper-pagination-bullet.swiper-pagination-bullet-active
50
  .line {
51
  transform: scaleX(8);
52
}
53
54
.section-with-carousel
55
  .swiper-pagination-bullets
56
  .swiper-pagination-bullet.swiper-pagination-bullet-active
57
  .number {
58
  opacity: 1;
59
  transform: none;
60
}

Be sure to click on a dot to see the little slide animation that happens.

4. Add the JavaScript

At this point, we’re ready to turn our attention to JavaScript.

As you can see from the previous visualizations, the carousel sections will be full-screen on screens up to 1199px wide. On larger screens, their left or right side will stop being full-screen and be aligned to the container width. As discussed earlier, this behavior will be determined by the section-with-left-offset and section-with-right-offset classes. This way, we’ll be able to generate unique layouts that won’t be limited to sections that follow a grid system.

The offsetThe offsetThe offset

Here’s the JavaScript code that implements this functionality:

1
createOffsets();
2
window.addEventListener("resize", createOffsets);
3
4
function createOffsets() {
5
  const sectionWithLeftOffset = document.querySelector(
6
    ".section-with-left-offset"
7
  );
8
  const sectionWithLeftOffsetCarouselWrapper = sectionWithLeftOffset.querySelector(
9
    ".carousel-wrapper"
10
  );
11
  const sectionWithRightOffset = document.querySelector(
12
    ".section-with-right-offset"
13
  );
14
  const sectionWithRightOffsetCarouselWrapper = sectionWithRightOffset.querySelector(
15
    ".carousel-wrapper"
16
  );
17
  const offset = (window.innerWidth - 1100) / 2;
18
  const mqLarge = window.matchMedia("(min-width: 1200px)");
19
20
  if (sectionWithLeftOffset && mqLarge.matches) {
21
    sectionWithLeftOffsetCarouselWrapper.style.marginLeft = offset + "px";
22
  } else {
23
    sectionWithLeftOffsetCarouselWrapper.style.marginLeft = 0;
24
  }
25
26
  if (sectionWithRightOffset && mqLarge.matches) {
27
    sectionWithRightOffsetCarouselWrapper.style.marginRight = offset + "px";
28
  } else {
29
    sectionWithRightOffsetCarouselWrapper.style.marginRight = 0;
30
  }
31
}

Initialize Swiper

This is the last required step to initialize Swiper. Here, we pass as part of the configuration object all our customizations. Look at the relevant code snippet below:

1
const sectionsWithCarousel = document.querySelectorAll(
2
  ".section-with-carousel"
3
);
4
5
for (const section of sectionsWithCarousel) {
6
  let slidesPerView = [1.5, 2.5, 3.5];
7
  if (section.classList.contains("section-with-left-offset")) {
8
    slidesPerView = [1.5, 1.5, 2.5];
9
  }
10
  const swiper = section.querySelector(".swiper");
11
  new Swiper(swiper, {
12
    slidesPerView: slidesPerView[0],
13
    spaceBetween: 15,
14
    loop: true,
15
    lazyLoading: true,
16
    keyboard: {
17
      enabled: true
18
    },
19
    navigation: {
20
      prevEl: section.querySelector(".carousel-control-left"),
21
      nextEl: section.querySelector(".carousel-control-right")
22
    },
23
    pagination: {
24
      el: section.querySelector(".swiper-pagination"),
25
      clickable: true,
26
      renderBullet: function (index, className) {
27
        return `<div class=${className}>

28
            <span class="number">${index + 1}</span>

29
            <span class="line"></span>

30
        </div>`;
31
      }
32
    },
33
    breakpoints: {
34
      768: {
35
        slidesPerView: slidesPerView[1]
36
      },
37
      1200: {
38
        slidesPerView: slidesPerView[2]
39
      }
40
    }
41
  });
42
}

As you can see, we pass in an array the number of slides that should appear depending on the viewport width. By using, not only integers but also decimals, we’ll be able to show just a portion of a slide.

Even though it isn’t necessary, the breakpoint values that determine when the number of visible slides changes will match Bootstrap’s breakpoints. Anyhow, be sure to read the API documentation to get a better understanding of what all these configuration parameters do. 

Conclusion

And we’re done, folks! In this tutorial, we created an asymmetric page layout with just a few lines of JavaScript code and the power of Swiper.js.

We only covered just the very basics of this plugin. There are so many more advanced sliders that you can build with minimal effort. Just get some inspiration from a source like Dribbble and practice yourselves! This is the best way to learn!

Let’s look again at what we built:

As always, thanks a lot for reading!

Swiper.js Video Tutorial

Now you’ve learned the fundamentals of Swiper, why not try your hand at a couple of other Swiper.js carousels? Follow Adi over on the Tuts+ YouTube channel (and don’t forget to subscribe for more videos!)

Watch on Youtube

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.