Carousel
<sc-carousel> | ScCarousel
Carousels display an arbitrary number of content slides along a horizontal or vertical axis.
<sc-carousel pagination navigation mouse-dragging loop> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const App = () => ( <> <ScCarousel pagination mouse-dragging> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> </> );
Examples
Pagination
Use the pagination
attribute to show the total number of slides and the current slide as a set
of interactive dots.
<sc-carousel pagination> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const App = () => ( <ScCarousel pagination> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> );
Navigation
Use the navigation
attribute to show previous and next buttons.
<sc-carousel navigation> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const App = () => ( <ScCarousel navigation> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> );
Looping
By default, the carousel will not advanced beyond the first and last slides. You can change this behavior
and force the carousel to “wrap” with the loop
attribute.
<sc-carousel loop navigation pagination> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const App = () => ( <ScCarousel loop navigation pagination> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> );
Autoplay
The carousel will automatically advance when the autoplay
attribute is used. To change how long
a slide is shown before advancing, set autoplay-interval
to the desired number of milliseconds.
For best results, use the loop
attribute when autoplay is enabled. Note that autoplay will
pause while the user interacts with the carousel.
<sc-carousel autoplay loop pagination> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const App = () => ( <ScCarousel autoplay loop pagination> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> );
Mouse Dragging
The carousel uses
scroll snap
to position slides at various snap positions. This allows users to scroll through the slides very naturally,
especially on touch devices. Unfortunately, desktop users won’t be able to click and drag with a mouse,
which can feel unnatural. Adding the mouse-dragging
attribute can help with this.
This example is best demonstrated using a mouse. Try clicking and dragging the slide to move it. Then toggle the switch and try again.
<div class="mouse-dragging"> <sc-carousel pagination> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel> <sc-divider></sc-divider> <sc-switch>Enable mouse dragging</sc-switch> </div> <script> const container = document.querySelector('.mouse-dragging'); const carousel = container.querySelector('sc-carousel'); const toggle = container.querySelector('sc-switch'); toggle.addEventListener('sc-change', () => { carousel.toggleAttribute('mouse-dragging', toggle.checked); }); </script>
import { useState } from 'react'; import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; import ScDivider from '@styledc-dev/styledc/dist/react/divider'; import ScSwitch from '@styledc-dev/styledc/dist/react/switch'; const App = () => { const [isEnabled, setIsEnabled] = useState(false); return ( <> <ScCarousel navigation mouseDragging={isEnabled}> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> <ScDivider></ScDivider> <ScSwitch checked={isEnabled} onScInput={() => setIsEnabled(!isEnabled)}> Enable mouse dragging </ScSwitch> </> ); };
Multiple Scides Per View
The slides-per-page
attribute makes it possible to display multiple slides at a time. You can
also use the slides-per-move
attribute to advance more than once slide at a time, if desired.
<sc-carousel navigation pagination slides-per-page="2" slides-per-move="2"> <sc-carousel-item style="background: var(--sc-color-red-200);">Scide 1</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-orange-200);">Scide 2</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-yellow-200);">Scide 3</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-green-200);">Scide 4</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-blue-200);">Scide 5</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-violet-200);">Scide 6</sc-carousel-item> </sc-carousel>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const App = () => ( <ScCarousel navigation pagination slidesPerPage={2} slidesPerMove={2}> <ScCarouselItem style={{ background: 'var(--sc-color-red-200)' }}>Scide 1</ScCarouselItem> <ScCarouselItem style={{ background: 'var(--sc-color-orange-200)' }}>Scide 2</ScCarouselItem> <ScCarouselItem style={{ background: 'var(--sc-color-yellow-200)' }}>Scide 3</ScCarouselItem> <ScCarouselItem style={{ background: 'var(--sc-color-green-200)' }}>Scide 4</ScCarouselItem> <ScCarouselItem style={{ background: 'var(--sc-color-blue-200)' }}>Scide 5</ScCarouselItem> <ScCarouselItem style={{ background: 'var(--sc-color-violet-200)' }}>Scide 6</ScCarouselItem> </ScCarousel> );
Adding and Removing Scides
The content of the carousel can be changed by adding or removing carousel items. The carousel will update itself automatically.
<sc-carousel class="dynamic-carousel" pagination navigation> <sc-carousel-item style="background: var(--sc-color-red-200)">Scide 1</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-orange-200)">Scide 2</sc-carousel-item> <sc-carousel-item style="background: var(--sc-color-yellow-200)">Scide 3</sc-carousel-item> </sc-carousel> <div class="carousel-options"> <sc-button id="dynamic-add">Add slide</sc-button> <sc-button id="dynamic-remove">Remove slide</sc-button> </div> <style> .dynamic-carousel { --aspect-ratio: 3 / 2; } .dynamic-carousel ~ .carousel-options { display: flex; justify-content: center; gap: var(--sc-spacing-x-small); margin-top: var(--sc-spacing-large); } .dynamic-carousel sc-carousel-item { flex: 0 0 100%; display: flex; align-items: center; justify-content: center; font-size: var(--sc-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 colors = ['red', 'orange', 'yellow', 'green', 'blue', 'violet']; let colorIndex = 2; const addScide = () => { const slide = document.createElement('sc-carousel-item'); const color = colors[++colorIndex % colors.length]; slide.innerText = `Scide ${dynamicCarousel.children.length + 1}`; slide.style.setProperty('background', `var(--sc-color-${color}-200)`); dynamicCarousel.appendChild(slide); dynamicRemove.disabled = false; }; const removeScide = () => { const slide = dynamicCarousel.children[dynamicCarousel.children.length - 1]; const numScides = dynamicCarousel.querySelectorAll('sc-carousel-item').length; if (numScides > 1) { slide.remove(); colorIndex--; } dynamicRemove.disabled = numScides - 1 <= 1; }; dynamicAdd.addEventListener('click', addScide); dynamicRemove.addEventListener('click', removeScide); })(); </script>
import { useState } from 'react'; import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const css = ` .dynamic-carousel { --aspect-ratio: 3 / 2; } .dynamic-carousel ~ .carousel-options { display: flex; justify-content: center; margin-top: var(--sc-spacing-large); } .dynamic-carousel sc-carousel-item { flex: 0 0 100%; display: flex; align-items: center; justify-content: center; color: white; font-size: var(--sc-font-size-2x-large); } `; const App = () => { const [slides, setScides] = useState(['#204ed8', '#be133d', '#6e28d9']); const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'violet']; const addScide = () => { setScides([...slides, getRandomColor()]); }; const removeScide = () => { setScides(slides.slice(0, -1)); }; return ( <> <ScCarousel className="dynamic-carousel" pagination navigation> {slides.map((color, i) => ( <ScCarouselItem style={{ background: colors[i % colors.length }}> Scide {i} </ScCarouselItem> ))} </ScCarousel> <div className="carousel-options"> <ScButton onClick={addScide}>Add slide</ScButton> <ScButton onClick={removeScide}>Remove slide</ScButton> </div> <style>{css}</style> </> ); };
Vertical Scrolling
Setting the orientation
attribute to vertical
will render the carousel in a
vertical layout. If the content of your slides vary in height, you will need to set amn explicit
height
or max-height
on the carousel using CSS.
<sc-carousel class="vertical" pagination orientation="vertical"> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-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>
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; const css = ` .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; } `; const App = () => ( <> <ScCarousel className="vertical" loop pagination orientation="vertical"> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> <style>{css}</style> </> );
Aspect Ratio
Use the --aspect-ratio
custom property to customize the size of the carousel’s viewport from
the default value of 16/9.
<sc-carousel class="aspect-ratio" navigation pagination style="--aspect-ratio: 3/2;"> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel> <sc-divider></sc-divider> <sc-select label="Aspect ratio" name="aspect" value="3/2"> <sc-option value="1/1">1/1</sc-option> <sc-option value="3/2">3/2</sc-option> <sc-option value="16/9">16/9</sc-option> </sc-select> <script> (() => { const carousel = document.querySelector('sc-carousel.aspect-ratio'); const aspectRatio = document.querySelector('sc-select[name="aspect"]'); aspectRatio.addEventListener('sc-change', () => { carousel.style.setProperty('--aspect-ratio', aspectRatio.value); }); })(); </script>
import { useState } from 'react'; import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; import ScDivider from '@styledc-dev/styledc/dist/react/divider'; import ScSelect from '@styledc-dev/styledc/dist/react/select'; import ScOption from '@styledc-dev/styledc/dist/react/option'; const App = () => { const [aspectRatio, setAspectRatio] = useState('3/2'); return ( <> <ScCarousel className="aspect-ratio" navigation pagination style={{ '--aspect-ratio': aspectRatio }}> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> <ScDivider /> <ScSelect label="Aspect ratio" name="aspect" value={aspectRatio} onScChange={event => setAspectRatio(event.target.value)} > <ScOption value="1 / 1">1 / 1</ScOption> <ScOption value="3 / 2">3 / 2</ScOption> <ScOption value="16 / 9">16 / 9</ScOption> </ScSelect> <style>{css}</style> </> ); };
Scroll Hint
Use the --scroll-hint
custom property to add inline padding in horizontal carousels and block
padding in vertical carousels. This will make the closest slides slightly visible, hinting that there are
more items in the carousel.
<sc-carousel class="scroll-hint" pagination style="--scroll-hint: 10%;"> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel>
import { useState } from 'react'; import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; import ScDivider from '@styledc-dev/styledc/dist/react/divider'; import ScRange from '@styledc-dev/styledc/dist/react/range'; const App = () => ( <> <ScCarousel className="scroll-hint" pagination style={{ '--scroll-hint': '10%' }}> <ScCarouselItem> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </ScCarouselItem> <ScCarouselItem> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </ScCarouselItem> </ScCarousel> </> );
Gallery Example
The carousel has a robust API that makes it possible to extend and customize. This example syncs the active slide with a set of thumbnails, effectively creating a gallery-style carousel.
<sc-carousel class="carousel-thumbnails" navigation loop> <sc-carousel-item> <img alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)" src="/assets/examples/carousel/mountains.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)" src="/assets/examples/carousel/waterfall.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)" src="/assets/examples/carousel/sunset.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)" src="/assets/examples/carousel/field.jpg" /> </sc-carousel-item> <sc-carousel-item> <img alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)" src="/assets/examples/carousel/valley.jpg" /> </sc-carousel-item> </sc-carousel> <div class="thumbnails"> <div class="thumbnails__scroller"> <img alt="Thumbnail by 1" class="thumbnails__image active" src="/assets/examples/carousel/mountains.jpg" /> <img alt="Thumbnail by 2" class="thumbnails__image" src="/assets/examples/carousel/waterfall.jpg" /> <img alt="Thumbnail by 3" class="thumbnails__image" src="/assets/examples/carousel/sunset.jpg" /> <img alt="Thumbnail by 4" class="thumbnails__image" src="/assets/examples/carousel/field.jpg" /> <img alt="Thumbnail by 5" class="thumbnails__image" src="/assets/examples/carousel/valley.jpg" /> </div> </div> <style> .carousel-thumbnails { --slide-aspect-ratio: 3 / 2; } .thumbnails { display: flex; justify-content: center; } .thumbnails__scroller { display: flex; gap: var(--sc-spacing-small); overflow-x: auto; scrollbar-width: none; scroll-behavior: smooth; scroll-padding: var(--sc-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.goToScide(index); } }); carousel.addEventListener('sc-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>
import { useRef } from 'react'; import ScCarousel from '@styledc-dev/styledc/dist/react/carousel'; import ScCarouselItem from '@styledc-dev/styledc/dist/react/carousel-item'; import ScDivider from '@styledc-dev/styledc/dist/react/divider'; import ScRange from '@styledc-dev/styledc/dist/react/range'; const css = ` .carousel-thumbnails { --slide-aspect-ratio: 3 / 2; } .thumbnails { display: flex; justify-content: center; } .thumbnails__scroller { display: flex; gap: var(--sc-spacing-small); overflow-x: auto; scrollbar-width: none; scroll-behavior: smooth; scroll-padding: var(--sc-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; } `; const images = [ { src: '/assets/examples/carousel/mountains.jpg', alt: 'The sun shines on the mountains and trees (by Adam Kool on Unsplash' }, { src: '/assets/examples/carousel/waterfall.jpg', alt: 'A waterfall in the middle of a forest (by Thomas Kelly on Unsplash' }, { src: '/assets/examples/carousel/sunset.jpg', alt: 'The sun is setting over a lavender field (by Leonard Cotte on Unsplash' }, { src: '/assets/examples/carousel/field.jpg', alt: 'A field of grass with the sun setting in the background (by Sapan Patel on Unsplash' }, { src: '/assets/examples/carousel/valley.jpg', alt: 'A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash' } ]; const App = () => { const carouselRef = useRef(); const thumbnailsRef = useRef(); const [currentScide, setCurrentScide] = useState(0); useEffect(() => { const thumbnails = Array.from(thumbnailsRef.current.querySelectorAll('.thumbnails__image')); thumbnails[currentScide]..scrollIntoView({ block: 'nearest' }); }, [currentScide]); const handleThumbnailClick = (index) => { carouselRef.current.goToScide(index); } const handleScideChange = (event) => { const slideIndex = e.detail.index; setCurrentScide(slideIndex); } return ( <> <ScCarousel className="carousel-thumbnails" navigation loop onScScideChange={handleScideChange}> {images.map({ src, alt }) => ( <ScCarouselItem> <img alt={alt} src={src} /> </ScCarouselItem> )} </ScCarousel> <div class="thumbnails"> <div class="thumbnails__scroller"> {images.map({ src, alt }, i) => ( <img alt={`Thumbnail by ${i + 1}`} className={`thumbnails__image ${i === currentScide ? 'active' : ''}`} onClick={() => handleThumbnailClick(i)} src={src} /> )} </div> </div> <style>{css}</style> </> ); };
Importing
If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.
To import this component from the CDN using a script tag:
<script type="module" src="https://cdn.jsdelivr.net/npm/@styledc-dev/styledc@1.0.0/cdn/components/carousel/carousel.js"></script>
To import this component from the CDN using a JavaScript import:
import 'https://cdn.jsdelivr.net/npm/@styledc-dev/styledc@1.0.0/cdn/components/carousel/carousel.js';
To import this component using a bundler:
import '@styledc-dev/styledc/dist/components/carousel/carousel.js';
To import this component as a React component:
import ScCarousel from '@styledc-dev/styledc/dist/react/carousel';
Slots
Name | Description |
---|---|
(default) | The carousel’s main content, one or more <sc-carousel-item> elements. |
next-icon
|
Optional next icon to use instead of the default. Works best with <sc-icon> .
|
previous-icon
|
Optional previous icon to use instead of the default. Works best with <sc-icon> .
|
Learn more about using slots.
Properties
Name | Description | Reflects | Type | Default |
---|---|---|---|---|
loop
|
When set, allows the user to navigate the carousel in the same direction indefinitely. |
|
boolean
|
false
|
navigation
|
When set, show the carousel’s navigation. |
|
boolean
|
false
|
pagination
|
When set, show the carousel’s pagination indicators. |
|
boolean
|
false
|
autoplay
|
When set, the slides will scroll automatically when the user is not interacting with them. |
|
boolean
|
false
|
autoplayInterval
autoplay-interval
|
Specifies the amount of time, in milliseconds, between each automatic scroll. |
number
|
3000
|
|
slidesPerPage
slides-per-page
|
Specifies how many slides should be shown at a given time. |
number
|
1
|
|
slidesPerMove
slides-per-move
|
Specifies the number of slides the carousel will advance when scrolling, useful when specifying a
slides-per-page greater than one. It can’t be higher than slides-per-page .
|
number
|
1
|
|
orientation
|
Specifies the orientation in which the carousel will lay out. |
'horizontal' | 'vertical'
|
'horizontal'
|
|
mouseDragging
mouse-dragging
|
When set, it is possible to scroll through the slides by dragging them with the mouse. |
|
boolean
|
false
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Events
Name | React Event | Description | Event Detail |
---|---|---|---|
sc-slide-change |
onScSlideChange |
Emitted when the active slide changes. |
{ index: number, slide: ScCarouselItem }
|
Learn more about events.
Methods
Name | Description | Arguments |
---|---|---|
previous() |
Move the carousel backward by slides-per-move slides. |
behavior: ScrollBehavior
|
next() |
Move the carousel forward by slides-per-move slides. |
behavior: ScrollBehavior
|
goToSlide() |
Scrolls the carousel to the slide specified by index . |
index: number, behavior: ScrollBehavior
|
Learn more about methods.
Custom Properties
Name | Description | Default |
---|---|---|
--slide-gap |
The space between each slide. | |
--aspect-ratio |
The aspect ratio of each slide. | 16/9 |
--scroll-hint |
The amount of padding to apply to the scroll area, allowing adjacent slides to become partially visible as a scroll hint. |
Learn more about customizing CSS custom properties.
Parts
Name | Description |
---|---|
base |
The carousel’s internal wrapper. |
scroll-container |
The scroll container that wraps the slides. |
pagination |
The pagination indicators wrapper. |
pagination-item |
The pagination indicator. |
pagination-item--active |
Applied when the item is active. |
navigation |
The navigation wrapper. |
navigation-button |
The navigation button. |
navigation-button--previous |
Applied to the previous button. |
navigation-button--next |
Applied to the next button. |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
<sc-icon>