kopia lustrzana https://github.com/shoelace-style/shoelace
591 wiersze
19 KiB
Markdown
591 wiersze
19 KiB
Markdown
# Carousel
|
|
|
|
[component-header:sl-carousel]
|
|
|
|
Carousels consist of optional navigation arrows to go backwards and forwards, as well as optional pagination indicators.
|
|
|
|
```html preview
|
|
<sl-carousel loop pagination navigation autoplay mouse-dragging>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
</sl-carousel>
|
|
<sl-divider></sl-divider>
|
|
<div class="carousel-options">
|
|
<div class="carousel-options">
|
|
<sl-switch checked name="loop"> Loop </sl-switch>
|
|
<sl-switch checked name="navigation"> Show navigation </sl-switch>
|
|
<sl-switch checked name="pagination"> Show pagination </sl-switch>
|
|
<sl-switch checked name="autoplay"> Autoplay (3s) </sl-switch>
|
|
<sl-switch checked name="mouseDragging"> Mouse dragging </sl-switch>
|
|
</div>
|
|
<div class="carousel-options">
|
|
<sl-input type="number" label="Slides per page" name="slidesPerPage" value="1"></sl-input>
|
|
<sl-input type="number" label="Slides per move" name="slidesPerMove" value="1"></sl-input>
|
|
<sl-select label="Orientation" name="orientation" value="horizontal">
|
|
<sl-menu-item value="horizontal">Horizontal</sl-menu-item>
|
|
<sl-menu-item value="vertical">Vertical</sl-menu-item>
|
|
</sl-select>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
sl-carousel {
|
|
--aspect-ratio: 3 / 2;
|
|
}
|
|
|
|
.carousel-options {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: end;
|
|
gap: 1rem;
|
|
}
|
|
</style>
|
|
<script>
|
|
(() => {
|
|
const options = document.querySelector('.carousel-options');
|
|
const carousel = document.querySelector('sl-carousel');
|
|
const loop = options.querySelector('sl-switch[name="loop"]');
|
|
const navigation = options.querySelector('sl-switch[name="navigation"]');
|
|
const pagination = options.querySelector('sl-switch[name="pagination"]');
|
|
const autoplay = options.querySelector('sl-switch[name="autoplay"]');
|
|
const mouseDragging = options.querySelector('sl-switch[name="mouseDragging"]');
|
|
const slidesPerMove = options.querySelector('sl-input[name="slidesPerMove"]');
|
|
const slidesPerPage = options.querySelector('sl-input[name="slidesPerPage"]');
|
|
const orientation = options.querySelector('sl-select[name="orientation"]');
|
|
|
|
loop.addEventListener('sl-change', () => (carousel.loop = loop.checked));
|
|
navigation.addEventListener('sl-change', () => (carousel.navigation = navigation.checked));
|
|
pagination.addEventListener('sl-change', () => (carousel.pagination = pagination.checked));
|
|
autoplay.addEventListener('sl-change', () => (carousel.autoplay = autoplay.checked));
|
|
slidesPerMove.addEventListener('sl-change', () => (carousel.slidesPerMove = slidesPerMove.valueAsNumber));
|
|
slidesPerPage.addEventListener('sl-change', () => (carousel.slidesPerPage = slidesPerPage.valueAsNumber));
|
|
orientation.addEventListener('sl-change', () => (carousel.orientation = orientation.value));
|
|
mouseDragging.addEventListener('sl-change', () => (carousel.mouseDragging = mouseDragging.checked));
|
|
|
|
document.addEventListener('sl-slide-change', e => {
|
|
console.log('Slide changed:', e.detail);
|
|
});
|
|
})();
|
|
</script>
|
|
```
|
|
|
|
## Examples
|
|
|
|
### Multiple slides per view
|
|
|
|
Setting the attribute `slides-per-view` is it possible to specify how many items are shown at a given time.
|
|
Using this feature, it may be also useful to advance multiple slides at once, even though not strictly necessary.
|
|
This can be done by using the `slides-per-move` attribute.
|
|
|
|
```html preview
|
|
<sl-carousel class="multi-carousel" loop navigation pagination slides-per-page="3" slides-per-move="3">
|
|
<sl-carousel-item style="background: #204ed8;">Slide 1</sl-carousel-item>
|
|
<sl-carousel-item style="background: #be133d;">Slide 2</sl-carousel-item>
|
|
<sl-carousel-item style="background: #6e28d9;">Slide 3</sl-carousel-item>
|
|
<sl-carousel-item style="background: #c2420d;">Slide 4</sl-carousel-item>
|
|
<sl-carousel-item style="background: #4d7c0f;">Slide 5</sl-carousel-item>
|
|
<sl-carousel-item style="background: #4338cb;">Slide 6</sl-carousel-item>
|
|
</sl-carousel>
|
|
```
|
|
|
|
### Adding/removing slides
|
|
|
|
The content of the carousel can be changed by either appending or removing items, the carousel will update itself automatically.
|
|
|
|
```html preview
|
|
<sl-carousel class="dynamic-carousel" pagination navigation>
|
|
<sl-carousel-item style="background: #204ed8;">Slide 1</sl-carousel-item>
|
|
<sl-carousel-item style="background: #be133d;">Slide 2</sl-carousel-item>
|
|
<sl-carousel-item style="background: #6e28d9;">Slide 3</sl-carousel-item>
|
|
</sl-carousel>
|
|
<sl-divider></sl-divider>
|
|
<div class="carousel-options">
|
|
<sl-button id="dynamic-add">Add slide</sl-button>
|
|
<sl-button id="dynamic-remove">Remove slide</sl-button>
|
|
</div>
|
|
<style>
|
|
.dynamic-carousel {
|
|
--aspect-ratio: 3 / 2;
|
|
}
|
|
|
|
.dynamic-carousel sl-carousel-item {
|
|
flex: 0 0 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: white;
|
|
font-size: var(--sl-font-size-2x-large);
|
|
}
|
|
</style>
|
|
<script>
|
|
(() => {
|
|
const dynamicCarousel = document.querySelector('.dynamic-carousel');
|
|
const dynamicAdd = document.querySelector('#dynamic-add');
|
|
const dynamicRemove = document.querySelector('#dynamic-remove');
|
|
|
|
const rnd = (min, max) => Math.round(Math.random() * (max - min)) + min;
|
|
|
|
const getRandomColor = () => `rgb(${rnd(50, 150)}, ${rnd(50, 150)}, ${rnd(50, 150)})`;
|
|
|
|
const addSlide = () => {
|
|
const slide = document.createElement('sl-carousel-item');
|
|
slide.innerText = `Slide ${dynamicCarousel.children.length + 1}`;
|
|
slide.style.setProperty('background', getRandomColor());
|
|
|
|
dynamicCarousel.appendChild(slide);
|
|
};
|
|
|
|
const removeSlide = () => {
|
|
const slide = dynamicCarousel.children[dynamicCarousel.children.length - 1];
|
|
slide.remove();
|
|
};
|
|
|
|
dynamicAdd.addEventListener('click', addSlide);
|
|
dynamicRemove.addEventListener('click', removeSlide);
|
|
})();
|
|
</script>
|
|
```
|
|
|
|
### Vertical scrolling
|
|
|
|
Setting the `orientation` attribute to `vertical`, will make the carousel laying out vertically, making it
|
|
possible for the user to scroll it up and down. In case of heterogeneous content, for example images of different sizes,
|
|
it's important to specify a predefined height to the carousel through CSS.
|
|
|
|
```html preview
|
|
<sl-carousel class="vertical" loop pagination orientation="vertical">
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
</sl-carousel>
|
|
<style>
|
|
.vertical {
|
|
max-height: 400px;
|
|
}
|
|
|
|
.vertical::part(base) {
|
|
grid-template-areas: 'slides slides pagination';
|
|
}
|
|
|
|
.vertical::part(pagination) {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.vertical::part(navigation) {
|
|
transform: rotate(90deg);
|
|
display: flex;
|
|
}
|
|
</style>
|
|
```
|
|
|
|
### Aspect ratio
|
|
|
|
Use the `--aspect-ratio` custom property to customize the size of viewport in order to make it match a particular aspect ratio.
|
|
|
|
```html preview
|
|
<sl-carousel class="aspect-ratio" navigation pagination style="--aspect-ratio: 3 / 2">
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
</sl-carousel>
|
|
|
|
<sl-divider></sl-divider>
|
|
<sl-select label="Aspect ratio" name="aspect" value="3 / 2">
|
|
<sl-menu-item value="1 / 1">1 / 1</sl-menu-item>
|
|
<sl-menu-item value="3 / 2">3 / 2</sl-menu-item>
|
|
<sl-menu-item value="16 / 9">16 / 9</sl-menu-item>
|
|
</sl-select>
|
|
|
|
<script>
|
|
(() => {
|
|
const carousel = document.querySelector('sl-carousel.aspect-ratio');
|
|
const aspect = document.querySelector('sl-select[name="aspect"]');
|
|
|
|
aspect.addEventListener('sl-change', () => {
|
|
carousel.style.setProperty('--aspect-ratio', aspect.value);
|
|
});
|
|
})();
|
|
</script>
|
|
```
|
|
|
|
### Scroll hint
|
|
|
|
Use `--scroll-padding` to add inline padding in horizontal carousels and block padding in vertical carousels.
|
|
Setting a padding, will make the closest slides visible, suggesting to the user that there are items that can
|
|
be scrolled.
|
|
|
|
```html preview
|
|
<sl-carousel class="scroll-hint" navigation pagination style="--scroll-padding: calc(var(--slide-gap) + 10%);">
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
</sl-carousel>
|
|
|
|
<sl-divider></sl-divider>
|
|
<sl-range label="Size (%)" name="scroll-hint" value="5" min="0" max="15"></sl-range>
|
|
|
|
<script>
|
|
(() => {
|
|
const carousel = document.querySelector('sl-carousel.scroll-hint');
|
|
const scrollHint = document.querySelector('sl-range[name="scroll-hint"]');
|
|
|
|
scrollHint.addEventListener('sl-input', () => {
|
|
carousel.style.setProperty('--scroll-padding', `calc(var(--slide-gap) + ${scrollHint.value}%)`);
|
|
});
|
|
})();
|
|
</script>
|
|
```
|
|
|
|
### Custom layout
|
|
|
|
The appereance of the carousel can be easly customized through its slots or `part` attributes.
|
|
|
|
```html preview
|
|
<sl-carousel class="custom-layout" navigation pagination>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
|
|
<sl-icon name="arrow-right" slot="next-icon"></sl-icon>
|
|
<sl-icon name="arrow-left" slot="previous-icon"></sl-icon>
|
|
</sl-carousel>
|
|
|
|
<style>
|
|
.custom-layout::part(base) {
|
|
grid-template-areas:
|
|
'slides slides slides'
|
|
'slides slides slides';
|
|
}
|
|
|
|
.custom-layout::part(pagination) {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
padding: var(--sl-spacing-large);
|
|
background: linear-gradient(0deg, rgba(0, 0, 0, 0.8) 5%, rgba(0, 0, 0, 0.2) 75%, rgba(0, 0, 0, 0) 100%);
|
|
}
|
|
|
|
.custom-layout::part(pagination-item) {
|
|
height: 5px;
|
|
width: var(--sl-spacing-large);
|
|
border-radius: var(--sl-border-radius-pill);
|
|
background-color: #fff;
|
|
}
|
|
|
|
.custom-layout::part(pagination-item--active) {
|
|
background-color: var(--sl-color-primary-400);
|
|
width: var(--sl-spacing-x-large);
|
|
}
|
|
|
|
.custom-layout::part(navigation-button) {
|
|
margin: var(--sl-spacing-large);
|
|
border-radius: var(--sl-border-radius-circle);
|
|
font-weight: var(--sl-font-weight-bold);
|
|
color: var(--sl-color-neutral-1000);
|
|
background: var(--sl-color-neutral-0);
|
|
opacity: 0.6;
|
|
transition: var(--sl-transition-medium) opacity;
|
|
}
|
|
|
|
.custom-layout::part(navigation-button):focus,
|
|
.custom-layout::part(navigation-button):hover {
|
|
opacity: 1;
|
|
}
|
|
</style>
|
|
```
|
|
|
|
### Gallery example
|
|
|
|
The carousel has a set of API with which is possible to interact programmatically, for example it is possible to
|
|
use `next()` or `previous()` to go respectively to the next or the previous slide.
|
|
|
|
When the active slide is changed, the `sl-slide-change` event is emitted providing the `index` of the slide.
|
|
|
|
Using the API is possible to extend the carousel, for exmaple by syncing the active slide with a set of thumbnails, like in the example below.
|
|
|
|
```html preview
|
|
<sl-carousel class="carousel-thumbnails" navigation loop>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
<sl-carousel-item>
|
|
<img
|
|
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</sl-carousel-item>
|
|
</sl-carousel>
|
|
<div class="thumbnails">
|
|
<div class="thumbnails__scroller">
|
|
<img
|
|
alt="Thumbnail Photo by 1"
|
|
class="thumbnails__image active"
|
|
src="/assets/examples/carousel/adam-kool-ndN00KmbJ1c-unsplash.jpg"
|
|
/>
|
|
<img
|
|
alt="Thumbnail Photo by 2"
|
|
class="thumbnails__image"
|
|
Jeff
|
|
King
|
|
on
|
|
Unsplash
|
|
src="/assets/examples/carousel/thomas-kelley-JoH60FhTp50-unsplash.jpg"
|
|
/>
|
|
<img
|
|
alt="Thumbnail Photo by 3"
|
|
class="thumbnails__image"
|
|
Leonard
|
|
Cotte
|
|
on
|
|
Unsplash
|
|
src="/assets/examples/carousel/leonard-cotte-c1Jp-fo53U8-unsplash.jpg"
|
|
/>
|
|
<img
|
|
alt="Thumbnail Photo by 4"
|
|
class="thumbnails__image"
|
|
Lukasz
|
|
Szmigiel
|
|
on
|
|
Unsplash
|
|
src="/assets/examples/carousel/sapan-patel-i9Q9bc-WgfE-unsplash.jpg"
|
|
/>
|
|
<img
|
|
alt="Thumbnail Photo by 5"
|
|
class="thumbnails__image"
|
|
V2osk
|
|
on
|
|
Unsplash
|
|
src="/assets/examples/carousel/v2osk-1Z2niiBPg5A-unsplash.jpg"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<style>
|
|
.carousel-thumbnails {
|
|
--slide-aspect-ratio: 3 / 2;
|
|
}
|
|
|
|
.thumbnails {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.thumbnails__scroller {
|
|
display: flex;
|
|
gap: var(--sl-spacing-small);
|
|
overflow-x: auto;
|
|
scrollbar-width: none;
|
|
scroll-behavior: smooth;
|
|
scroll-padding: var(--sl-spacing-small);
|
|
}
|
|
|
|
.thumbnails__scroller::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.thumbnails__image {
|
|
width: 64px;
|
|
height: 64px;
|
|
object-fit: cover;
|
|
|
|
opacity: 0.3;
|
|
will-change: opacity;
|
|
transition: 250ms opacity;
|
|
|
|
cursor: pointer;
|
|
}
|
|
|
|
.thumbnails__image.active {
|
|
opacity: 1;
|
|
}
|
|
</style>
|
|
<script>
|
|
{
|
|
const carousel = document.querySelector('.carousel-thumbnails');
|
|
const scroller = document.querySelector('.thumbnails__scroller');
|
|
const thumbnails = document.querySelectorAll('.thumbnails__image');
|
|
|
|
scroller.addEventListener('click', e => {
|
|
const target = e.target;
|
|
|
|
if (target.matches('.thumbnails__image')) {
|
|
const index = [...thumbnails].indexOf(target);
|
|
carousel.goToSlide(index);
|
|
}
|
|
});
|
|
|
|
carousel.addEventListener('sl-slide-change', e => {
|
|
const slideIndex = e.detail.index;
|
|
|
|
[...thumbnails].forEach((thumb, i) => {
|
|
thumb.classList.toggle('active', i === slideIndex);
|
|
if (i === slideIndex) {
|
|
thumb.scrollIntoView({
|
|
block: 'nearest'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
</script>
|
|
```
|
|
|
|
[component-metadata:sl-carousel]
|