javascripthtmlcarouselfancyboxsplidejs

Why does the lightbox not count the number of images correctly when used inside a carousel?


Goal

I want to use the Splide carousel with a lightbox.

Problem

If I use a lightbox inside the Splide carousel, the lightbox doesn't count the number of images correctly.

Whereas, if I use the lightbox outside the Splide carousel, it works as expected.

What I've tried

I've tried the following three lightboxes:

All three of them count the number of images incorrectly when used inside the Splide carousel! What's more, it seems like if I have 3 images in the carousel, all three of them show 7 images. This doesn't seem like a coincidence to me. I've been trying to solve the problem for hours and haven't been successful.

Reproducible example

I used Fancybox to reproduce the problem.

Note: Click on any of the images to open the lightbox (i.e., Fancybox).

  1. Fancybox inside the Splide carousel <-- NOT WORKING (i.e., showing 7 images instead of 3)

document.addEventListener("DOMContentLoaded", function() {
  /* Splide */
  var splide1 = new Splide(".splide.splide-galerija", {
    type: "loop",
    perPage: 1,
    perMove: 1,
    arrows: false,
    pagination: true,
    lazyLoad: "nearby",
    padding: "60px",
    breakpoints: {
      1259: {
        gap: "21px",
      },
      1023: {
        perPage: 1,
        gap: "10px",
        padding: "20px",
      },
    },
  });

  splide1.mount();

  /* Fancybox */
  Fancybox.bind('[data-fancybox="gallery"]', {});
});
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>

<!-- Splide -->
<link href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js"></script>

<!-- Fancybox -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>

<div id="galerija-prenocisce" class="mx-auto">
  <div class="wrapper">
    <div class="row mx-auto px-xl-0 px-sm-3 px-2">
      <div class="col-12">
        <section class="splide splide-galerija mx-auto" aria-label="Splide Basic HTML Example">
          <div class="splide__track">
            <ul class="splide__list">
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" data-caption="Image 1">
                    <img class="w-100" src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" />
                  </a>
                </div>
              </li>
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" data-caption="Image 2">
                    <img class="w-100" src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" />
                  </a>
                </div>
              </li>
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
                    data-caption="Image 3">
                    <img class="w-100" src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
                    />
                  </a>
                </div>
              </li>
            </ul>
          </div>
        </section>
      </div>
    </div>
  </div>
</div>

  1. Fancybox outside the Splide carousel <-- WORKING (i.e., showing 3 images)

document.addEventListener("DOMContentLoaded", function() {
  /* Fancybox */
  Fancybox.bind('[data-fancybox="gallery"]', {});
});
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>

<!-- Fancybox -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>

<a data-fancybox="gallery" data-src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" data-caption="Image 1">
  <img class="w-100" src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" />
</a>
<a data-fancybox="gallery" data-src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" data-caption="Image 2">
  <img class="w-100" src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" />
</a>
<a data-fancybox="gallery" data-src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
  data-caption="Image 3">
  <img class="w-100" src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
  />
</a>


EDIT

Two possible solutions:

  1. If you don't need the loop for the carousel, turn it off. In the case of Splide, this means changing the type: "loop" to type: "slide".

document.addEventListener("DOMContentLoaded", function() {
  /* Splide */
  var splide1 = new Splide(".splide.splide-galerija", {
    type: "slide",
    perPage: 1,
    perMove: 1,
    arrows: false,
    pagination: true,
    lazyLoad: "nearby",
    padding: "60px",
    breakpoints: {
      1259: {
        gap: "21px",
      },
      1023: {
        perPage: 1,
        gap: "10px",
        padding: "20px",
      },
    },
  });

  splide1.mount();

  /* Fancybox */
  Fancybox.bind('[data-fancybox="gallery"]', {});
});
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>

<!-- Splide -->
<link href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js"></script>

<!-- Fancybox -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>

<div id="galerija-prenocisce" class="mx-auto">
  <div class="wrapper">
    <div class="row mx-auto px-xl-0 px-sm-3 px-2">
      <div class="col-12">
        <section class="splide splide-galerija mx-auto" aria-label="Splide Basic HTML Example">
          <div class="splide__track">
            <ul class="splide__list">
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" data-caption="Image 1">
                    <img class="w-100" src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" />
                  </a>
                </div>
              </li>
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" data-caption="Image 2">
                    <img class="w-100" src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" />
                  </a>
                </div>
              </li>
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
                    data-caption="Image 3">
                    <img class="w-100" src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
                    />
                  </a>
                </div>
              </li>
            </ul>
          </div>
        </section>
      </div>
    </div>
  </div>
</div>

  1. Use a custom selector to avoid including cloned elements in the lightbox.

document.addEventListener("DOMContentLoaded", function() {
  /* Splide */
  var splide1 = new Splide(".splide.splide-galerija", {
    type: "loop",
    perPage: 1,
    perMove: 1,
    arrows: false,
    pagination: true,
    lazyLoad: "nearby",
    padding: "60px",
    breakpoints: {
      1259: {
        gap: "21px",
      },
      1023: {
        perPage: 1,
        gap: "10px",
        padding: "20px",
      },
    },
  });

  splide1.mount();

  /* Fancybox */
  Fancybox.bind('li:not(.splide__slide--clone) [data-fancybox="gallery"]', {});
});
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>

<!-- Splide -->
<link href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js"></script>

<!-- Fancybox -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>

<div id="galerija-prenocisce" class="mx-auto">
  <div class="wrapper">
    <div class="row mx-auto px-xl-0 px-sm-3 px-2">
      <div class="col-12">
        <section class="splide splide-galerija mx-auto" aria-label="Splide Basic HTML Example">
          <div class="splide__track">
            <ul class="splide__list">
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" data-caption="Image 1">
                    <img class="w-100" src="https://optimise2.assets-servd.host/maniacal-finch/production/animals/reticulated-giraffe-01-01.jpg?w=1200&auto=compress%2Cformat&fit=crop&dm=1658951271&s=179de228b20aafcd748a5f0dc8fde776" />
                  </a>
                </div>
              </li>
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" data-caption="Image 2">
                    <img class="w-100" src="https://images.ctfassets.net/81iqaqpfd8fy/3r4flvP8Z26WmkMwAEWEco/870554ed7577541c5f3bc04942a47b95/78745131.jpg?w=1200&h=1200&fm=jpg&fit=fill" />
                  </a>
                </div>
              </li>
              <li class="splide__slide">
                <div class="img-wrapper position-relative">
                  <a data-fancybox="gallery" data-src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
                    data-caption="Image 3">
                    <img class="w-100" src="https://th-thumbnailer.cdn-si-edu.com/axHGv_G1wmyLZG1cXVDcxsl-oVg=/1072x720/filters:no_upscale()/https://tf-cmsv2-smithsonianmag-media.s3.amazonaws.com/filer/0c/5f/0c5fc6f8-1b9b-4510-8b15-163482a3e041/istock_6413768_medium.jpg"
                    />
                  </a>
                </div>
              </li>
            </ul>
          </div>
        </section>
      </div>
    </div>
  </div>
</div>


Solution

  • It is a well know issue when combining any Lightbox script with a Carousel that uses cloned elements for infinite navigation.

    There are two solutions:

    1. Use Fancybox and Carousel provided by Fancyapps UI as their carousel uses smart element positioning to provide infinite navigation without element cloning. In fact, you can combine Fancybox with Carousel without writing any additional JavaScript code, see https://fancyapps.com/carousel/#combine
    2. If your Lightbox script supports custom selector, then you have to use that to avoid including cloned elements, like Fancybox.bind('a:not(.cloned)) <- this is just an example, you have to tweak this selector to your needs.