Font Face
Teva Sans Latin

Drafts & Templates
PBS Templates

Primitives & components context

Primitives & components: Teva Global

Image Carousel

v0.0.0

Image carousel to show multiple images.

The carousel is a combination of a controller (shown in page) and a modal (shown on click). The modal carousel can consist of an image, a video or a 3D-image.

  • Within both these elements there are 2 sliders: a footer with thumbs and a main slider
  • the elements in all these sliders must be in the same order
  • when an element is a video or 3D image, show an image variant in the controller and in the footer of the modal
  • when there are more slides than fit in a screen, the carousel has infinite loop and is centered
  • the element .vi-image-carousel__image in the controller main slider must have a data-target corresponding with id of the modal

3D-images images are displayed with the use of the <model-viewer> custom element.
(see https://modalviewer.dev/)

Add this script to the page, when using the custom element:
<script src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js" type="module"></script>

<div class="vi-image-carousel">
  <div class="vi-image-carousel__controller">
    <div class="vi-image-carousel__slider">
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="0" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="1" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg"></div>
          </a>
          <!-- Badge (mods: --xs) -->
          <span class="bg-neutral-70 px-0 position-absolute bottom-0 vi-badge vi-badge--xs" data-tooltip="true" title="This popup will open an interactive 3D image">3D</span>
        </div>
        <div class="vi-image-carousel__slide swiper-slide vi-image-carousel__slide--video">
          <a class="vi-image-carousel__image" data-index="2" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
          <!-- Badge (mods: --xs) -->
          <span class="bg-neutral-70 px-0 position-absolute bottom-0 vi-badge vi-badge--xs" data-tooltip="true" title="This popup will open a video"><!-- Icon video-play (mods: --button-start) -->
            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 12 12" sg-icons-dir="sg/components/icon/icons" role="img" class="vi-icon vi-icon--button-start" aria-label="video-play" width="12" height="12"><path d="M11.1 5.4c.5.3.5.8 0 1.1l-7.3 4.9c-.4.3-.8.1-.8-.5V1c0-.5.4-.7.8-.4l7.3 4.8z" fill-rule="evenodd"></path></svg></span>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="3" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="4" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="5" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="6" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="7" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="8" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="9" data-target="#sg-d983eb" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
      </div>
    </div>
    <div aria-labelledby="sg-916b3e" class="vi-image-carousel__footer" role="group">
      <span class="ariaLabel" id="sg-916b3e">
        Navigate through images with left &amp; right arrows
      </span>
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
      </div>
    </div>
    <div class="vi-image-carousel__counterbadgewrapper">
      <!-- Badge  -->
      <span class="vi-image-carousel__counterbadge vi-badge">+</span>
    </div>
  </div>
  <!-- Modal  -->
  <div class="modal fade vi-modal" id="sg-d983eb" role="dialog" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-body">
          <!-- Modal Layout (mods: --compact) -->
          <div class="vi-modal-layout vi-modal-layout--compact">
            <div class="vi-modal-layout__body">
              <div class="vi-modal-layout__section vi-modal-layout__section--header-close">
                <div class="vi-modal-layout__close">
                  <!-- Button type: close  -->
                  <button aria-label="Message dialog - click to close or navigate to the message content" data-dismiss="modal" type="button" class="vi-btn-close vi-btn-close--accent-1 vi-btn"><span class="vi-btn-close__label vi-btn__label">Close</span></button>
                </div>
              </div>
            </div>
          </div>
          <!-- Modal Layout (mods: --visual) -->
          <div class="vi-modal-layout vi-modal-layout--visual">
            <div class="vi-modal-layout__body">
              <div class="vi-image-carousel__modal pb-5">
                <div class="vi-image-carousel__slider">
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><model-viewer alt="product description" camera-controls environment-image="neutral" shadow-intensity="1" src="/assets/images/3d/Amalgel_susp_10ml.glb" tabindex="1"></model-viewer></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Video  -->
                        <div class="vi-video" data-google-key="AIzaSyCCT69wewvdxKePFXN40xeJmy5MQusd9uc" data-player-mode="inline" data-video-id="PiVcDIRF3V4" data-video-provider="youtube" role="button" tabindex="1">
                          <!-- Rectangular Image (mods: --video) -->
                          <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-1038x584.jpg"></div>
                        </div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--prev">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--white vi-btn__label">Previous</span></button>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--next">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--white vi-btn__label">Next</span></button>
                    </div>
                  </div>
                </div>
                <div aria-labelledby="footerLabelModal" class="vi-image-carousel__footer" role="group">
                  <span class="ariaLabel" id="footerLabelModal">
                    Navigate through images with left &amp; right arrows
                  </span>
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-image-carousel__slide--3d vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-image-carousel__slide--video vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

No count indicator is displayed when there are 5 or less items.

<div class="vi-image-carousel">
  <div class="vi-image-carousel__controller">
    <div class="vi-image-carousel__slider">
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="0" data-target="#sg-076ded" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="1" data-target="#sg-076ded" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg"></div>
          </a>
          <!-- Badge (mods: --xs) -->
          <span class="bg-neutral-70 px-0 position-absolute bottom-0 vi-badge vi-badge--xs" data-tooltip="true" title="This popup will open an interactive 3D image">3D</span>
        </div>
        <div class="vi-image-carousel__slide swiper-slide vi-image-carousel__slide--video">
          <a class="vi-image-carousel__image" data-index="2" data-target="#sg-076ded" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
          <!-- Badge (mods: --xs) -->
          <span class="bg-neutral-70 px-0 position-absolute bottom-0 vi-badge vi-badge--xs" data-tooltip="true" title="This popup will open a video"><!-- Icon video-play (mods: --button-start) -->
            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 12 12" sg-icons-dir="sg/components/icon/icons" role="img" class="vi-icon vi-icon--button-start" aria-label="video-play" width="12" height="12"><path d="M11.1 5.4c.5.3.5.8 0 1.1l-7.3 4.9c-.4.3-.8.1-.8-.5V1c0-.5.4-.7.8-.4l7.3 4.8z" fill-rule="evenodd"></path></svg></span>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="3" data-target="#sg-076ded" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="4" data-target="#sg-076ded" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
      </div>
    </div>
    <div aria-labelledby="sg-7c16dc" class="vi-image-carousel__footer" role="group">
      <span class="ariaLabel" id="sg-7c16dc">
        Navigate through images with left &amp; right arrows
      </span>
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
      </div>
    </div>
    <div class="vi-image-carousel__counterbadgewrapper">
      <!-- Badge  -->
      <span class="vi-image-carousel__counterbadge vi-badge">+</span>
    </div>
  </div>
  <!-- Modal  -->
  <div class="modal fade vi-modal" id="sg-076ded" role="dialog" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-body">
          <!-- Modal Layout (mods: --compact) -->
          <div class="vi-modal-layout vi-modal-layout--compact">
            <div class="vi-modal-layout__body">
              <div class="vi-modal-layout__section vi-modal-layout__section--header-close">
                <div class="vi-modal-layout__close">
                  <!-- Button type: close  -->
                  <button aria-label="Message dialog - click to close or navigate to the message content" data-dismiss="modal" type="button" class="vi-btn-close vi-btn-close--accent-1 vi-btn"><span class="vi-btn-close__label vi-btn__label">Close</span></button>
                </div>
              </div>
            </div>
          </div>
          <!-- Modal Layout (mods: --visual) -->
          <div class="vi-modal-layout vi-modal-layout--visual">
            <div class="vi-modal-layout__body">
              <div class="vi-image-carousel__modal pb-5">
                <div class="vi-image-carousel__slider">
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><model-viewer alt="product description" camera-controls environment-image="neutral" shadow-intensity="1" src="/assets/images/3d/Amalgel_susp_10ml.glb" tabindex="1"></model-viewer></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Video  -->
                        <div class="vi-video" data-google-key="AIzaSyCCT69wewvdxKePFXN40xeJmy5MQusd9uc" data-player-mode="inline" data-video-id="PiVcDIRF3V4" data-video-provider="youtube" role="button" tabindex="1">
                          <!-- Rectangular Image (mods: --video) -->
                          <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-1038x584.jpg"></div>
                        </div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--prev">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--white vi-btn__label">Previous</span></button>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--next">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--white vi-btn__label">Next</span></button>
                    </div>
                  </div>
                </div>
                <div aria-labelledby="footerLabelModal" class="vi-image-carousel__footer" role="group">
                  <span class="ariaLabel" id="footerLabelModal">
                    Navigate through images with left &amp; right arrows
                  </span>
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-image-carousel__slide--3d vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-image-carousel__slide--video vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Aligns to side when 4 or less items.

<div class="vi-image-carousel">
  <div class="vi-image-carousel__controller">
    <div class="vi-image-carousel__slider">
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="0" data-target="#sg-457a27" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="1" data-target="#sg-457a27" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg"></div>
          </a>
          <!-- Badge (mods: --xs) -->
          <span class="bg-neutral-70 px-0 position-absolute bottom-0 vi-badge vi-badge--xs" data-tooltip="true" title="This popup will open an interactive 3D image">3D</span>
        </div>
        <div class="vi-image-carousel__slide swiper-slide vi-image-carousel__slide--video">
          <a class="vi-image-carousel__image" data-index="2" data-target="#sg-457a27" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
          <!-- Badge (mods: --xs) -->
          <span class="bg-neutral-70 px-0 position-absolute bottom-0 vi-badge vi-badge--xs" data-tooltip="true" title="This popup will open a video"><!-- Icon video-play (mods: --button-start) -->
            <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 12 12" sg-icons-dir="sg/components/icon/icons" role="img" class="vi-icon vi-icon--button-start" aria-label="video-play" width="12" height="12"><path d="M11.1 5.4c.5.3.5.8 0 1.1l-7.3 4.9c-.4.3-.8.1-.8-.5V1c0-.5.4-.7.8-.4l7.3 4.8z" fill-rule="evenodd"></path></svg></span>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="3" data-target="#sg-457a27" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
      </div>
    </div>
    <div aria-labelledby="sg-c9e90d" class="vi-image-carousel__footer" role="group">
      <span class="ariaLabel" id="sg-c9e90d">
        Navigate through images with left &amp; right arrows
      </span>
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
      </div>
    </div>
    <div class="vi-image-carousel__counterbadgewrapper">
      <!-- Badge  -->
      <span class="vi-image-carousel__counterbadge vi-badge">+</span>
    </div>
  </div>
  <!-- Modal  -->
  <div class="modal fade vi-modal" id="sg-457a27" role="dialog" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-body">
          <!-- Modal Layout (mods: --compact) -->
          <div class="vi-modal-layout vi-modal-layout--compact">
            <div class="vi-modal-layout__body">
              <div class="vi-modal-layout__section vi-modal-layout__section--header-close">
                <div class="vi-modal-layout__close">
                  <!-- Button type: close  -->
                  <button aria-label="Message dialog - click to close or navigate to the message content" data-dismiss="modal" type="button" class="vi-btn-close vi-btn-close--accent-1 vi-btn"><span class="vi-btn-close__label vi-btn__label">Close</span></button>
                </div>
              </div>
            </div>
          </div>
          <!-- Modal Layout (mods: --visual) -->
          <div class="vi-modal-layout vi-modal-layout--visual">
            <div class="vi-modal-layout__body">
              <div class="vi-image-carousel__modal pb-5">
                <div class="vi-image-carousel__slider">
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><model-viewer alt="product description" camera-controls environment-image="neutral" shadow-intensity="1" src="/assets/images/3d/Amalgel_susp_10ml.glb" tabindex="1"></model-viewer></div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Video  -->
                        <div class="vi-video" data-google-key="AIzaSyCCT69wewvdxKePFXN40xeJmy5MQusd9uc" data-player-mode="inline" data-video-id="PiVcDIRF3V4" data-video-provider="youtube" role="button" tabindex="1">
                          <!-- Rectangular Image (mods: --video) -->
                          <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-1038x584.jpg"></div>
                        </div>
                      </div>
                    </div>
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--prev">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--white vi-btn__label">Previous</span></button>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--next">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--white vi-btn__label">Next</span></button>
                    </div>
                  </div>
                </div>
                <div aria-labelledby="footerLabelModal" class="vi-image-carousel__footer" role="group">
                  <span class="ariaLabel" id="footerLabelModal">
                    Navigate through images with left &amp; right arrows
                  </span>
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-image-carousel__slide--3d vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/3d/Amalgel_susp_10ml.square.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-image-carousel__slide--video vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Doesn't show navigation when there's only 1 item.

<div class="vi-image-carousel">
  <div class="vi-image-carousel__controller">
    <div class="vi-image-carousel__slider">
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <a class="vi-image-carousel__image" data-index="0" data-target="#sg-782c0a" data-toggle="modal" tabindex="-1">
            <div class="vi-circular-image"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg"></div>
          </a>
        </div>
      </div>
    </div>
    <div aria-labelledby="sg-27a414" class="vi-image-carousel__footer" role="group">
      <span class="ariaLabel" id="sg-27a414">
        Navigate through images with left &amp; right arrows
      </span>
      <div class="vi-image-carousel__wrapper swiper-wrapper">
        <div class="vi-image-carousel__slide swiper-slide">
          <button class="vi-image-carousel__image vi-circular-image vi-circular-footeritem" tabindex="-1">
            <img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-300x300.jpg">
          </button>
        </div>
      </div>
    </div>
    <div class="vi-image-carousel__counterbadgewrapper">
      <!-- Badge  -->
      <span class="vi-image-carousel__counterbadge vi-badge">+</span>
    </div>
  </div>
  <!-- Modal  -->
  <div class="modal fade vi-modal" id="sg-782c0a" role="dialog" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-body">
          <!-- Modal Layout (mods: --compact) -->
          <div class="vi-modal-layout vi-modal-layout--compact">
            <div class="vi-modal-layout__body">
              <div class="vi-modal-layout__section vi-modal-layout__section--header-close">
                <div class="vi-modal-layout__close">
                  <!-- Button type: close  -->
                  <button aria-label="Message dialog - click to close or navigate to the message content" data-dismiss="modal" type="button" class="vi-btn-close vi-btn-close--accent-1 vi-btn"><span class="vi-btn-close__label vi-btn__label">Close</span></button>
                </div>
              </div>
            </div>
          </div>
          <!-- Modal Layout (mods: --visual) -->
          <div class="vi-modal-layout vi-modal-layout--visual">
            <div class="vi-modal-layout__body">
              <div class="vi-image-carousel__modal pb-5">
                <div class="vi-image-carousel__slider">
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <div class="vi-image-carousel__slide swiper-slide">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --video) -->
                        <div class="vi-rectangular-image vi-rectangular-image--video"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--prev">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--white vi-btn__label">Previous</span></button>
                    </div>
                    <div class="vi-slider__navigation vi-slider__navigation--next">
                      <!-- Button type: pagination  -->
                      <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--white vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--white vi-btn__label">Next</span></button>
                    </div>
                  </div>
                </div>
                <div aria-labelledby="footerLabelModal" class="vi-image-carousel__footer" role="group">
                  <span class="ariaLabel" id="footerLabelModal">
                    Navigate through images with left &amp; right arrows
                  </span>
                  <div class="vi-image-carousel__wrapper swiper-wrapper">
                    <button class="vi-image-carousel__slide vi-image-carousel__slide--footer swiper-slide vi-circular-footeritem" tabindex="-1">
                      <div class="vi-image-carousel__image">
                        <!-- Rectangular Image (mods: --square, --transparent) -->
                        <div class="vi-rectangular-image vi-rectangular-image--square vi-rectangular-image--transparent"><img alt="alt text" draggable="false" loading="lazy" src="/assets/images/static/test-600x450.jpg"></div>
                      </div>
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Stylesheets #

The following stylesheets are required to display this component.

The following additional stylesheets are used to display the example(s).


JavaScript #

The following javascripts are required to display this component.


Usage documentation #

Usage documentation can be found here.


Changelog #

Changelog

Fix

  • 16 May 2024 - fix(image-carousel): adjust slide width calculation to include margins
  • 14 Feb 2022 - [TVB-11767] Focus opening element when using tabs (tweak)
  • 06 Feb 2022 - [TVB-11767] Focus opening element when using tabs
  • 25 Jan 2022 - [TVB-11571] Disable ability to drag, to prevent dragging outside to prevent disappearing images
  • 31 Oct 2022 - [TVB-11571] Image carousel - dragging images makes them disappear
  • 31 Oct 2022 - [TVB-11767] Image Carousel - wrong image outline while using tabulation
  • 31 Oct 2022 - [TVB-11570] Image carousel - closing expanded carousel returns user to wrong image

  • 23 Jan 2024 - Fixed sliding on empty carousel space to break the sliders.
  • 20 Sept 2022 - Incorrect return image when multiple instances.
  • 20 Sept 2022 - Fix navigation buttons
  • 20 Sept 2022 - Focus button when slided to
  • 20 Sept 2022 - Incorrect counter value
  • 20 Sept 2022 - RTL issue
  • 20 Sept 2022 - Dragging issue (also 3D-related)
  • 20 Sept 2022 - Use buttons instead of links
  • 20 Sept 2022 - Layout shift thumbnails
  • 20 Sept 2022 - Remove ‘next slide’ text
  • 20 Sept 2022 - Tab order
  • 20 Sept 2022 - Disappearing images

Added

  • 20 Sept 2022 - Close returns to same image
  • 15 Aug 2022 - Initial draft