Carousel
Cycles through multiple screens of content in the same viewport, with manual switching and autoplay support.
Basic Usage
Basic carousel
Click the dots at the bottom to switch screens; autoplay is off by default.
Touch adaptation: under coarse pointers the arrow / pause buttons grow to the 44px touch target (larger button, same icon size); the dots stay visually 12px and gain an invisible 44px hit area, with dot spacing widened to prevent adjacent hit areas from overlapping.
Initial Index
Controlled index
index specifies the current screen (starting from 0).
Autoplay
Autoplay
Setting autoplay enables autoplay, and interval controls the interval (in milliseconds).
Arrow Modes
The left/right arrows support three display modes, controlled by the arrows attribute: always (always shown) / hover (shown on hover, default) / never (hidden). Clicking an arrow switches to the previous / next screen, looping around at the ends.
Always shown (always)
Shown on hover (hover)
Hidden (never)
The default (when arrows is not specified) is the hover mode: arrows are hidden by default and smoothly fade in when the mouse hovers over or the keyboard focuses the carousel area. Not specifying arrows is equivalent to arrows="hover".
Image Carousel
Carousel items are not limited to color blocks — putting in an <img> or SVG makes an image banner.
Image banner (SVG)
Image carousel (img + autoplay)
Events
Change event
Current slide: 1
Indicators
Indicators support hiding, outside placement, and a line shape via indicators / indicator-position / indicator-type. Dot colors use component-level CSS variables --oas-carousel-dot-bg / --oas-carousel-dot-active-bg (white by default, suited for dark slides; override on the host for light slides).
Hidden indicators (indicators=false)
Outside indicators (indicator-position=outside)
Line indicators (indicator-type=line)
Fade
Set effect="fade" for a full-screen crossfade between slides (default slide translates the track). Under prefers-reduced-motion it degrades to an instant switch.
Crossfade (effect=fade)
Switching Methods
The component exposes imperative methods next() / prev() / goTo(index), and the oas-change event (detail carries index and prevIndex) — together they enable custom interactions such as thumbnails driving the main carousel.
Imperative switching (next / prev / goTo)
Loop Toggle
Looping is on by default; with loop="false" the carousel stops at the ends (the previous arrow is disabled on the first slide and the next arrow on the last), which suits step-by-step guides or banners with an end call-to-action.
No loop (loop=false)
Autoplay Pause
While autoplaying, hovering or keyboard-focusing the carousel pauses it, and it resumes when the pointer/focus leaves; the carousel also stops when the page becomes hidden and continues when visible again (WCAG 2.2.2 pause requirement). Use pause-on-hover="false" to disable hover pausing.
Pause on hover (default)
Hover (or Tab-focus) the carousel area above and autoplay pauses on the current slide; it continues from the next tick after you leave.
Disable hover pause (pause-on-hover=false)
Vertical
Set direction="vertical" to switch along the vertical axis. The vertical viewport is 200px tall by default; override it with the CSS variable --oas-carousel-height. Indicators move to the right side and the arrows rotate 90°.
Vertical (direction=vertical)
Multiple Slides per View
slides-per-view sets how many slides are shown per screen, and gap sets the spacing between them (px). Indicators and stepping follow "page" semantics (one group per step). When the last page holds fewer slides than a full group, it aligns to the track end without exposing a blank area.
Two slides per view (slides-per-view=2 + gap)
Drag to Switch
Press and drag horizontally (vertically in vertical mode) — the track follows your pointer; release past the threshold (25% of the viewport, or a quick flick) to switch, release before it and the track springs back. Touch and mouse are unified via Pointer Events; horizontal dragging leaves vertical page scrolling intact (touch-action: pan-y) so it never fights the page scroll gesture. The transition animation pauses while dragging and resumes on release; the autoplay timer resets after a drag ends.
Dragging is enabled per device by default: touch devices (pointer: coarse) allow dragging, PCs do not. Add the draggable attribute to enable it on PCs explicitly; draggable="false" disables it on touch devices explicitly.
Drag to switch (draggable, press and drag)
Current slide: 1 (the track follows your drag; release to switch or spring back)
Card Mode
Set type="card" for a card-style carousel: the current card is centered as the main body (60% of the width by default) while the neighboring cards peek out on both sides, scaled down and dimmed. Click any neighbor card to switch to it directly, or use the arrow keys while focus is inside a slide. In non-loop mode (loop="false") the first/last cards sit flush against the edges — the first card sticks to the left showing the right neighbor, and the last card sticks to the right showing the left neighbor, so no edge is left hanging. Card width, card gap, and neighbor scale are controlled by the CSS variables --oas-carousel-card-width / --oas-carousel-card-gap / --oas-carousel-card-scale. Card mode is horizontal-only and mutually exclusive with slides-per-view / effect / direction (card mode wins when both are set); arrows / indicators / autoplay / drag / loop all compose with it.
Card mode (type=card, click a side card to switch)
Explicit Pause Button
Besides the automatic hover/focus pause, pause-button renders an explicit pause/play button (pinned to the top-right corner). The explicit pause takes priority: once paused, moving the mouse away will not resume autoplay; clicking play while autoplay is off enables autoplay. The button's aria-pressed and label follow the paused state.
Explicit pause button (pause-button)
Indicator Trigger
trigger controls when indicators switch slides: click (default, click to switch) / hover (hovering a dot switches immediately; click still works); invalid values fall back to click. Handy for fast browsing in image carousels.
trigger=hover
Thumbnail indicators (thumbs)
thumbs replaces the dots with a thumbnail strip: each thumbnail's source is taken from an <img> inside the slide, the slide's data-thumb attribute, or a JSON array of URLs given to the thumbs attribute (priority: array > data-thumb > <img>); when none is available an index placeholder is rendered. The current thumbnail is highlighted with a primary-color border; clicking switches slides, and keyboard navigation / trigger behave the same as with dots.
Thumbnail indicators (thumbs, from slide img)
Thumbnail source (thumbs JSON array)
API
oas-carousel
Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
arrows | Arrow display mode: always (always shown) / hover (shown on hover) / never (hidden) | string | hover |
autoplay | Whether to autoplay | boolean | — |
direction | Direction: horizontal (default) / vertical (fixed-height viewport via --oas-carousel-height) | string | horizontal |
draggable | Pointer/touch drag switching: flip past 25% of the viewport or on a quick flick, spring back otherwise; on by default on touch devices, off on PC; "false" disables explicitly | string | — |
effect | Transition effect: slide (default) / fade (stacked cross-fade, degrades to instant under reduced-motion) | string | slide |
gap | Gap between slides in px (with slides-per-view) | string | 0 |
index | Current screen index (starting from 0) | string | 0 |
indicator-position | Indicator position: inside (default, overlaid) / outside (in-flow, grows the container) | string | inside |
indicator-type | Indicator type: dot (default) / line (widens when active) | string | dot |
indicators | Indicator switch (default true; "false" hides them) | string | true |
interval | Autoplay interval (ms) | string | 3000 |
loop | Loop around (default on; "false" stops at the edges and disables the corresponding arrow) | string | — |
pause-button | Show an explicit pause/play button (default off; click toggles autoplay pause/resume and takes priority over hover pausing; clicking play while autoplay is off enables it) | boolean | — |
pause-on-hover | Pause autoplay on hover/focus (default true; "false" disables; always pauses when the page is hidden) | string | true |
slides-per-view | Slides per page (default 1; index is page-based, last page aligns to the track end) | string | 1 |
thumbs | Replaces dots with a thumbnail strip (sources from a JSON array / data-thumb / child img); the current thumbnail gets a primary-color border | string | — |
trigger | Indicator activation: click (default) / hover (hover switches, click still works) | string | click |
type | Carousel layout type: "card" enables card mode — the current card is centered as the main body with neighboring cards peeking on both sides (scaled down, dimmed); clicking a neighbor card switches to it directly; mutually exclusive with slides-per-view/effect/direction (card mode wins); card width/gap/neighbor scale via --oas-carousel-card-width / --oas-carousel-card-gap / --oas-carousel-card-scale | string | — |
Events
| Event | Description |
|---|---|
oas-change | Current screen changed, detail: { index } |
Slots
| Name | Description |
|---|---|
| default | Carousel slides |
CSS Variables
| CSS Variable | Default |
|---|---|
--oas-carousel-card-gap | var(--oas-space-3) |
--oas-carousel-card-scale | 0.85 |
--oas-carousel-card-width | 60% |
--oas-carousel-dot-active-bg | #ffffff |
--oas-carousel-dot-bg | rgba(255, 255, 255, 0.5) |
--oas-carousel-height | 200px |
Parts (::part())
| Part | Description |
|---|---|
viewport / track | Viewport and sliding track |
dots / dot | Bottom indicator container and a single dot |
arrow-prev / arrow-next | Left/right arrow buttons, absolutely positioned at the vertical center of the two sides of the carousel; can be styled independently |
pause-button | Autoplay pause/resume button |
thumb | Thumbnail navigation item (thumbs) |