<div class="carousel-container">
<div class="carousel" data-behavior="carousel">
<div>
<div style="border:2px solid; height: 300px;"> 1 </div>
</div>
<div>
<div style="border:2px solid; height: 300px;"> 2 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 3 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 4 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 5 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 6 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 7 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 8 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 9 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 10 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 11</div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 12 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 13 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 14 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 15 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 16 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 17 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 18 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 19 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 20 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 21 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 22 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 23 </div>
</div>
</div>
<div class="carousel-nav-block">
<div class="carousel-nav-wrapper">
<div role="tablist" class="carousel__pagination"></div>
<div class="carousel-navigation">
<button aria-label="Previous" class="carousel__cta carousel__prev"><span class="visually-hidden">Previous
page</span><svg fill="none" viewBox="0 0 10 17" xmlns="http://www.w3.org/2000/svg">
<path d="m9.2722 9.3355-6.75 6.75c-0.46089 0.4609-1.2087 0.4609-1.6706 0-0.46089-0.4609-0.46089-1.2097 0-1.6706l5.9146-5.9146-5.9146-5.9146c-0.46089-0.46089-0.46089-1.2097 0-1.6706 0.46194-0.46089 1.2097-0.46089 1.6706 0l6.75 6.75c0.46194 0.46089 0.46194 1.2097 0 1.6706v-1.4e-4z" fill="currentColor" />
</svg></button>
<button aria-label="Next" class="carousel__cta carousel__next"><span class="visually-hidden">Next
page</span><svg fill="none" viewBox="0 0 10 17" xmlns="http://www.w3.org/2000/svg">
<path d="m9.2722 9.3355-6.75 6.75c-0.46089 0.4609-1.2087 0.4609-1.6706 0-0.46089-0.4609-0.46089-1.2097 0-1.6706l5.9146-5.9146-5.9146-5.9146c-0.46089-0.46089-0.46089-1.2097 0-1.6706 0.46194-0.46089 1.2097-0.46089 1.6706 0l6.75 6.75c0.46194 0.46089 0.46194 1.2097 0 1.6706v-1.4e-4z" fill="currentColor" />
</svg></button>
</div>
</div>
</div>
</div>
No notes defined.
/* No context defined. */
import debounce from 'lodash.debounce';
import Glide from '@glidejs/glide';
export default ({ carouselGlideElement, responsive = [], ...options }) => {
const slides = carouselGlideElement.querySelectorAll('.glide__slides > li');
const carouselLoop = carouselGlideElement.getAttribute('data-carousel-loop');
const MOBILE_BREAKPOINT = 820;
let glide;
const glideType4 = slides.length <= 4 ? 'slider' : 'carousel';
const glideType2 = slides.length <= 2 ? 'slider' : 'carousel';
// eslint-disable-next-line no-unneeded-ternary
const isSwipe4 = slides.length <= 4 ? false : true;
// eslint-disable-next-line no-unneeded-ternary
const isSwipe2 = slides.length <= 2 ? false : true;
const breakpointSettings = {
500: {
perView: 1,
peek: { before: 40, after: 30 },
},
900: {
perView: 2,
type: glideType2,
swipeThreshold: isSwipe2,
dragThreshold: isSwipe2,
},
1200: {
perView: 4,
type: glideType4,
swipeThreshold: isSwipe4,
dragThreshold: isSwipe4,
},
...responsive,
};
const getCurrentSettings = () => {
const screenWidth = window.innerWidth;
// Because the `perView` changes at different breakpoints, find
// the relevant setting for the current screensize.
// Filter out any settings that are smaller than the current size, and
// then use the first in the list, as this will be the most relevant.
// If none are available, assume we are using the biggest setting.
// TODO: We should be able to reuse this, if we want to change the pagination
// to scroll full pages, rather than individual items
const breakpointSettingsForCurrentSize =
Object.keys(breakpointSettings).filter(
i => parseInt(i, 10) > screenWidth
)[0] || Object.keys(breakpointSettings).slice(-1);
return breakpointSettings[breakpointSettingsForCurrentSize];
};
const enablePrevButton = () => {
carouselGlideElement
.querySelector('.carousel__prev')
.classList.remove('disabled');
carouselGlideElement
.querySelector('.carousel__prev')
.removeAttribute('disabled');
};
const enableNextButton = () => {
carouselGlideElement
.querySelector('.carousel__next')
.classList.remove('disabled');
carouselGlideElement
.querySelector('.carousel__next')
.removeAttribute('disabled');
};
const disablePrevButton = () => {
carouselGlideElement
.querySelector('.carousel__prev')
.classList.add('disabled');
carouselGlideElement
.querySelector('.carousel__prev')
.setAttribute('disabled', true);
};
const disableNextButton = () => {
carouselGlideElement
.querySelector('.carousel__next')
.classList.add('disabled');
carouselGlideElement
.querySelector('.carousel__next')
.setAttribute('disabled', true);
};
const showPaginationByPage = () => {
// Glide shows a pagination button for each item, and doesn't provide
// an option to navigate whole pages at a time.
// This function hides extra individual dots, so that only the first item of
// each page is shown. (Based on the `perView` setting).
const { perView } = getCurrentSettings();
const paginationElements = carouselGlideElement.querySelectorAll(
`.glide-carousel__pagination button:not(:nth-child(${perView}n + 1))`
);
paginationElements.forEach(item => {
item.classList.add('hidden');
});
if (carouselLoop && window.innerWidth > MOBILE_BREAKPOINT) {
return;
}
// disabling prev button by default
disablePrevButton();
};
const slideToNext = () => {
const maxPerView = getCurrentSettings().perView;
carouselGlideElement
.querySelector('.carousel__next')
.addEventListener('click', event => {
const { target } = event;
let activeDots = 0;
carouselGlideElement
.querySelectorAll('.glide-carousel__pagination > *')
.forEach((dot, index) => {
if (dot.getAttribute('class') === 'glide__bullet--active') {
activeDots = index;
}
});
const nextSlide = activeDots + maxPerView;
if (carouselLoop && window.innerWidth > MOBILE_BREAKPOINT) {
if (nextSlide >= slides.length) {
glide.go(`=0`);
} else {
glide.go(`=${nextSlide}`);
}
} else {
glide.go(`=${nextSlide}`);
if (nextSlide + maxPerView >= slides.length) {
target.closest('button').classList.add('disabled');
target.closest('button').setAttribute('disabled', true);
}
enablePrevButton();
}
});
};
const slideToPrevious = () => {
const maxPerView = getCurrentSettings().perView;
carouselGlideElement
.querySelector('.carousel__prev')
.addEventListener('click', event => {
const { target } = event;
let activeDots = 0;
carouselGlideElement
.querySelectorAll('.glide-carousel__pagination > *')
.forEach((dot, index) => {
if (dot.getAttribute('class') === 'glide__bullet--active') {
activeDots = index;
}
});
const prevSlide = activeDots - maxPerView;
if (carouselLoop && window.innerWidth > MOBILE_BREAKPOINT) {
if (prevSlide < 0) {
const lastslide =
Math.floor(slides.length / maxPerView) * maxPerView;
glide.go(`=${lastslide}`);
} else {
glide.go(`=${prevSlide}`);
}
} else {
if (prevSlide >= 0) {
glide.go(`=${prevSlide}`);
}
if (prevSlide - maxPerView < 0) {
target.closest('button').classList.add('disabled');
target.closest('button').setAttribute('disabled', true);
}
enableNextButton();
}
});
};
const enableNextPrev = () => {
const maxPerView = getCurrentSettings().perView;
carouselGlideElement
.querySelectorAll('.glide-carousel__pagination > *')
.forEach((dot, index) => {
dot.addEventListener('click', () => {
if (index > 0) {
enablePrevButton();
}
if (index === 0) {
enableNextButton();
disablePrevButton();
}
if (index + maxPerView >= slides.length) {
disableNextButton();
}
if (index + maxPerView < slides.length) {
enableNextButton();
}
});
});
};
const showHideNavigation = () => {
const maxPerView = getCurrentSettings().perView;
const navigationElements = carouselGlideElement.querySelectorAll(
'[data-glide-dir]'
);
if (!slides || slides.length <= maxPerView) {
navigationElements.forEach(item => item.classList.add('hidden'));
// eslint-disable-next-line no-param-reassign
carouselGlideElement.querySelector('.carousel-navigation').style.display =
'none';
return;
}
navigationElements.forEach(item => item.classList.remove('hidden'));
showPaginationByPage();
// added manual arrow next/previous button action
slideToNext();
slideToPrevious();
enableNextPrev();
};
const createPagination = () => {
const bulletContainer = document.createElement('div');
bulletContainer.classList.add('glide-carousel__pagination');
bulletContainer.dataset.glideEl = 'controls[nav]';
slides.forEach((slide, index) => {
const button = document.createElement('button');
button.dataset.glideDir = `=${index}`;
bulletContainer.appendChild(button);
});
carouselGlideElement
.querySelector('.carousel-nav-wrapper')
.appendChild(bulletContainer);
showHideNavigation();
};
createPagination();
window.addEventListener(
'resize',
debounce(() => {
// Hide the navigation when we don't have more items than we can show on screen
showHideNavigation();
}, 250)
);
glide = new Glide(carouselGlideElement, {
perView: 4,
breakpoints: breakpointSettings,
type: glideType4,
swipeThreshold: isSwipe4,
dragThreshold: isSwipe4,
...options,
}).mount();
return glide;
};
import debounce from 'lodash.debounce';
import Glide from '@glidejs/glide';
export default ({ imageGalleryElement, responsive = [], ...options }) => {
const slides = imageGalleryElement.querySelectorAll('.glide__slides > li');
let glide = '';
let transformCount = 0;
const breakpointSettings = {
500: {
perView: 1,
peek: { before: 0, after: 0 },
},
954: {
perView: 1,
},
1200: {
perView: 1,
peek: { before: 'auto', after: 'auto' },
slideWidth: 954,
},
...responsive,
};
const getCurrentSettings = () => {
const screenWidth = window.innerWidth;
// Because the `perView` changes at different breakpoints, find
// the relevant setting for the current screensize.
// Filter out any settings that are smaller than the current size, and
// then use the first in the list, as this will be the most relevant.
// If none are available, assume we are using the biggest setting.
// TODO: We should be able to reuse this, if we want to change the pagination
// to scroll full pages, rather than individual items
const breakpointSettingsForCurrentSize =
Object.keys(breakpointSettings).filter(
i => parseInt(i, 10) > screenWidth
)[0] || Object.keys(breakpointSettings).slice(-1);
return breakpointSettings[breakpointSettingsForCurrentSize];
};
const updateBulletSize = (dot, action) => {
if (action === 'add') {
imageGalleryElement
.querySelector(`.glide-carousel__pagination > [data-slide-no='${dot}']`)
.classList.add('small');
} else {
imageGalleryElement
.querySelector(`.glide-carousel__pagination > [data-slide-no='${dot}']`)
.classList.remove('small');
}
};
const setBulletDefaultSize = () => {
const maxDots = 5;
const totalCount = slides.length;
const navigationElements = imageGalleryElement.querySelectorAll(
`.glide-carousel__pagination > [data-slide-no]`
);
if (totalCount > maxDots) {
navigationElements.forEach(item => {
item.classList.remove('small');
});
transformCount = 0;
// eslint-disable-next-line no-param-reassign
imageGalleryElement.querySelector(
'.glide-carousel__pagination'
).style.transform = 'translateX(0)';
updateBulletSize(4, 'add');
}
};
const setBulletSize = (currentSlide, nextSlide) => {
const maxDots = 5;
const transformXIntervalNext = -24;
const transformXIntervalPrev = 24;
const totalCount = slides.length;
if (totalCount > maxDots) {
if (nextSlide > currentSlide) {
if (
imageGalleryElement
.querySelector(
`.glide-carousel__pagination > [data-slide-no='${nextSlide}']`
)
.classList.contains('small')
) {
if (
!imageGalleryElement
.querySelector(
`.glide-carousel__pagination > [data-slide-no]:last-child`
)
.classList.contains('small')
) {
// eslint-disable-next-line operator-assignment
transformCount = transformCount + transformXIntervalNext;
updateBulletSize(nextSlide, 'remove');
const nextSlidePlusOne = nextSlide + 1;
updateBulletSize(nextSlidePlusOne, 'add');
// eslint-disable-next-line no-param-reassign
imageGalleryElement.querySelector(
'.glide-carousel__pagination'
).style.transform = `translateX(${transformCount}px)`;
const pPointer = nextSlide - 3;
const pPointerMinusOne = pPointer - 1;
updateBulletSize(pPointerMinusOne, 'remove');
updateBulletSize(pPointer, 'add');
}
} else {
// eslint-disable-next-line no-lonely-if
if (nextSlide === slides.length - 1) {
const navigationElements = imageGalleryElement.querySelectorAll(
`.glide-carousel__pagination > [data-slide-no]`
);
navigationElements.forEach(item => {
item.classList.remove('small');
});
updateBulletSize(slides.length - 5, 'add');
transformCount = (slides.length - 5) * transformXIntervalNext;
// eslint-disable-next-line no-param-reassign
imageGalleryElement.querySelector(
'.glide-carousel__pagination'
).style.transform = `translateX(${transformCount}px)`;
}
}
} else {
// eslint-disable-next-line no-lonely-if
if (
imageGalleryElement
.querySelector(
`.glide-carousel__pagination > [data-slide-no='${nextSlide}']`
)
.classList.contains('small')
) {
if (
!imageGalleryElement
.querySelector(
`.glide-carousel__pagination > [data-slide-no]:first-child`
)
.classList.contains('small')
) {
// eslint-disable-next-line operator-assignment
transformCount = transformCount + transformXIntervalPrev;
updateBulletSize(nextSlide, 'remove');
const nextSlidePlusOne = nextSlide - 1;
updateBulletSize(nextSlidePlusOne, 'add');
// eslint-disable-next-line no-param-reassign
imageGalleryElement.querySelector(
'.glide-carousel__pagination'
).style.transform = `translateX(${transformCount}px)`;
const nPointer = currentSlide + 3;
const nPointerMinusOne = nPointer - 1;
// console.log(`${nPointer} - ${nPointerMinusOne}`);
updateBulletSize(nPointer, 'remove');
updateBulletSize(nPointerMinusOne, 'add');
}
} else {
// eslint-disable-next-line no-lonely-if
if (nextSlide === 0) {
setBulletDefaultSize();
}
}
}
}
};
const countLeftPad = number => {
const slideCount = number.toString();
// eslint-disable-next-line no-undef
return slideCount.padStart(2, '0');
};
const setSlideCount = currentIndex => {
const slideCountBlock = imageGalleryElement.querySelector(
'.image-gallery__totalslides--count'
);
slideCountBlock.innerHTML = `${countLeftPad(
currentIndex + 1
)}/${countLeftPad(slides.length)}`;
};
const showPaginationByPage = () => {
// Glide shows a pagination button for each item, and doesn't provide
// an option to navigate whole pages at a time.
// This function hides extra individual dots, so that only the first item of
// each page is shown. (Based on the `perView` setting).
const { perView } = getCurrentSettings();
const paginationElements = imageGalleryElement.querySelectorAll(
`.glide-carousel__pagination button:not(:nth-child(${perView}n + 1))`
);
paginationElements.forEach(item => {
item.classList.add('hidden');
});
setSlideCount(0);
setBulletDefaultSize();
};
const showHideNavigation = () => {
const maxPerView = getCurrentSettings().perView;
const navigationElements = imageGalleryElement.querySelectorAll(
'[data-slide-no]'
);
if (!slides || slides.length <= maxPerView) {
navigationElements.forEach(item => item.classList.add('hidden'));
// eslint-disable-next-line no-param-reassign
imageGalleryElement.querySelector(
'.image-gallery__navigation'
).style.display = 'none';
// eslint-disable-next-line no-param-reassign
imageGalleryElement.querySelector(
'.image-gallery__totalslides'
).style.display = 'none';
imageGalleryElement
.querySelector('.glide__slides')
.classList.add('singleslide');
return;
}
navigationElements.forEach(item => item.classList.remove('hidden'));
showPaginationByPage();
};
const createPagination = () => {
const bulletContainer = document.createElement('div');
bulletContainer.classList.add('glide-carousel__pagination');
bulletContainer.dataset.glideEl = 'controls[nav]';
slides.forEach((slide, index) => {
const button = document.createElement('button');
button.dataset.slideNo = `${index}`;
button.tabIndex = '-1';
bulletContainer.appendChild(button);
});
imageGalleryElement
.querySelector('.carousel-nav-wrapper')
.appendChild(bulletContainer);
showHideNavigation();
};
const setPeekVal = () => {
let peekVal = 0;
if (document.body.clientWidth > 954) {
peekVal = (document.body.clientWidth - 954) / 2;
}
glide.update({
peek: { before: peekVal, after: peekVal },
});
};
createPagination();
window.addEventListener(
'resize',
debounce(() => {
// Hide the navigation when we don't have more items than we can show on screen
showHideNavigation();
setPeekVal();
}, 250)
);
glide = new Glide(imageGalleryElement, {
perView: 1,
type: 'carousel',
breakpoints: breakpointSettings,
peek: { before: 100, after: 100 },
...options,
}).mount();
glide.on('run', () => {
const currentSlide = imageGalleryElement
.querySelector(
'.glide-carousel__pagination > [data-slide-no].glide__bullet--active'
)
.getAttribute('data-slide-no');
const nextSlide = glide.index;
// console.log(`${currentSlide} - ${nextSlide}`);
// eslint-disable-next-line radix
setBulletSize(parseInt(currentSlide), nextSlide);
setSlideCount(nextSlide);
updateBulletSize(nextSlide, 'remove');
});
if (slides.length === 1) {
glide.update({
type: 'slider',
peek: { before: 0, after: 0 },
});
} else {
setPeekVal();
}
return glide;
};
import Glider from '../../behaviours/carousel/glider/glider';
export default ({ carouselElement, responsive = [], ...options }) => {
const defaultOptions = {
slidesToShow: 1,
slidesToScroll: 1,
scrollLock: true,
draggable: true,
arrows: {
prev: '.carousel__prev',
next: '.carousel__next',
},
dots: '.carousel__pagination',
responsive: [
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
},
},
{
breakpoint: 900,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
},
},
{
breakpoint: 1200,
settings: {
slidesToShow: 4,
slidesToScroll: 4,
},
},
...responsive,
],
};
return new Glider(carouselElement, {
...defaultOptions,
...options,
});
};
.glide__slides {
margin: 0 auto;
> li {
display: flex;
justify-content: center;
}
}
[data-glide-el='track'] {
overflow: hidden;
}
@mixin carousel-cta {
align-items: center;
appearance: none;
background-color: $grey;
border: none;
border-radius: 50%;
color: #fff;
display: flex;
height: 0.8rem;
justify-content: center;
transition: background-color 0.2s ease-in;
width: 0.8rem;
white-space: nowrap;
}
.glider-track {
margin: auto;
}
// TODO: Review this once more usecases established
// We should look to remove markup based selectors and
// this style might be better placed on individual usages.
.glider-slide > * {
margin-left: auto;
margin-right: auto;
}
.carousel-nav-block {
text-align: center;
padding-bottom: 2.5rem;
}
.carousel-nav-wrapper {
position: relative;
display: inline-flex;
align-items: center;
}
.carousel {
&-navigation {
display: flex;
justify-content: flex-end;
margin-bottom: 2rem;
}
&__cta {
@include text-s--narrow;
@include carousel-cta;
svg {
width: 0.8rem;
height: 1.5rem;
}
}
&__prev {
position: absolute;
left: -50px;
transform: rotate(180deg);
margin-right: $spacing-m;
width: 4.4rem !important;
height: 4.4rem !important;
border: 1px solid $color-disabled !important;
background-color: transparent !important;
color: $blue !important;
&:hover {
border: 1px solid $blue !important;
}
}
&__next {
position: absolute;
right: -50px;
width: 4.4rem !important;
height: 4.4rem !important;
border: 1px solid $color-disabled !important;
background-color: transparent !important;
color: $blue !important;
&:hover {
border: 1px solid $blue !important;
}
}
&__pagination {
display: flex;
justify-content: center;
margin-top: $spacing-xxl;
transition: all 0.25s;
button {
background-color: $grey;
border: none;
border-radius: 50%;
height: 0.8rem;
padding: 0;
margin: 0 $spacing-s;
width: 0.8rem;
&.active {
background-color: $blue;
}
&.glide__bullet--active {
background-color: $blue;
}
&.small {
transform: scale(0.5);
transition: transform 300ms;
}
&.inactive {
transform: scale(0);
transition: transform 300ms;
display: none;
}
}
}
@media screen and (min-width: $mq-medium) {
&__pagination {
counter-reset: pagination;
button {
@include carousel-cta;
@include text-m;
cursor: pointer;
&:not(.active):not(.glide__bullet--active) {
opacity: 0.7;
}
/* &::before {
counter-increment: pagination;
content: counter(pagination);
} */
}
}
&__cta {
@include text-s--narrow;
@include carousel-cta;
svg {
width: 0.8rem;
height: 1.5rem;
}
&:not(.disabled) {
cursor: pointer;
}
&:hover {
background-color: darken($color-interactive, 10%);
}
&.disabled {
background-color: #fff;
color: $color-primary;
border-color: $color-disabled !important;
}
}
}
}
//
@media screen and (min-width: $mq-medium) {
.carousel-container {
max-width: 114rem;
}
.carousel-navigation {
margin-bottom: 0;
}
.carousel--desktop-reset {
.glider-track {
width: 100% !important; // important used to override js
flex-wrap: wrap;
}
[data-glide-el='track'] {
width: 100% !important; // important used to override js
flex-wrap: wrap;
}
.carousel {
&__pagination,
&-navigation {
display: none;
}
}
}
.carousel__prev {
position: absolute;
left: -75px;
}
.carousel__next {
position: absolute;
right: -75px;
}
}
@media (min-width: $mq-large) {
.glider-track .glider-slide {
float: left;
width: 25% !important;
}
}
.glide-carousel__pagination {
@extend .carousel__pagination;
}
.image-gallery {
.carousel-nav-wrapper {
width: 11.5rem;
overflow: hidden;
}
}
<div class="carousel-container">
<div class="carousel" data-behavior="carousel">
<div>
<div style="border:2px solid; height: 300px;"> 1 </div>
</div>
<div>
<div style="border:2px solid; height: 300px;"> 2 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 3 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 4 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 5 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 6 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 7 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 8 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 9 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 10 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 11</div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 12 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 13 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 14 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 15 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 16 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 17 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 18 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 19 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 20 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 21 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 22 </div>
</div>
<div>
<div style="border:2px solid ; height: 300px;"> 23 </div>
</div>
</div>
<div class="carousel-nav-block">
<div class="carousel-nav-wrapper">
<div role="tablist" class="carousel__pagination"></div>
<div class="carousel-navigation">
<button aria-label="Previous" class="carousel__cta carousel__prev"><span class="visually-hidden">Previous
page</span><svg fill="none" viewBox="0 0 10 17" xmlns="http://www.w3.org/2000/svg">
<path
d="m9.2722 9.3355-6.75 6.75c-0.46089 0.4609-1.2087 0.4609-1.6706 0-0.46089-0.4609-0.46089-1.2097 0-1.6706l5.9146-5.9146-5.9146-5.9146c-0.46089-0.46089-0.46089-1.2097 0-1.6706 0.46194-0.46089 1.2097-0.46089 1.6706 0l6.75 6.75c0.46194 0.46089 0.46194 1.2097 0 1.6706v-1.4e-4z"
fill="currentColor" />
</svg></button>
<button aria-label="Next" class="carousel__cta carousel__next"><span class="visually-hidden">Next
page</span><svg fill="none" viewBox="0 0 10 17" xmlns="http://www.w3.org/2000/svg">
<path
d="m9.2722 9.3355-6.75 6.75c-0.46089 0.4609-1.2087 0.4609-1.6706 0-0.46089-0.4609-0.46089-1.2097 0-1.6706l5.9146-5.9146-5.9146-5.9146c-0.46089-0.46089-0.46089-1.2097 0-1.6706 0.46194-0.46089 1.2097-0.46089 1.6706 0l6.75 6.75c0.46194 0.46089 0.46194 1.2097 0 1.6706v-1.4e-4z"
fill="currentColor" />
</svg></button>
</div>
</div>
</div>
</div>