ESL Carousel Autoplay
The esl-carousel-autoplay is a custom attribute (plugin/mixin) for ESLCarousel that provides autoplay functionality. It lets the carousel automatically navigate between slides on a timed cycle, issuing a navigation command at each interval. Attach the plugin directly on the esl-carousel element (it will self‑remove if applied elsewhere). The plugin supports ESL media rule syntax, enabling responsive configuration. Features include: hover/focus pause, separate external control/progress mixins, and per‑slide timeout overrides.
Configuration
The only configuration source is the esl-carousel-autoplay attribute value (plugin config system). Supports ESL media rule syntax (either unified arrow syntax or tuple form bound to the carousel media attribute).
Configuration properties:
duration(primary) – CSS time (1s,500ms) or number (ms). Required.> 0– base autoplay cycle duration0– no base cycle (autoplay stays enabled but inactive unless a slide overrides with a positive per‑slide timeout)- negative / invalid /
none– globally disable the plugin Defaults to10sif omitted.
command(optional, default:slide:next) – navigation command to execute each cycle.intersection(optional, default:0.25) – intersection ratio (0..1) required to run. Below threshold cycle is suspended.trackInteraction(optional, default:true) – pause while hovered or focus (keyboard focus‑visible) is within interaction scope.interactionScope(optional) – selector (ESLTraversingQuery) defining interaction tracking subscription scope (defaults to host carousel).interactionScopeExclude(optional) – CSS selector (Element.matches) applied to resolvedinteractionScopeitems to exclude them from hover/focus consideration without changing subscriptions.containerCls(optional) – CSS class applied to the carousel container while autoplay is enabled.blockerSelector(optional) – selector (ESLTraversingQuery) for items that, when activated, stop carousel autoplay. Defaults to::find(esl-share[active], esl-note[active]).watchEvents(optional) – space-separated list of event names that toggle blocking state on the carousel when fired. Defaults toesl:change:active.blockBehaviour(optional, default:stop) – how runtime blockers behave:stop– clear the current cycle and start a new one after unblockingpause– pause and resume the current cycle preserving the remaining time
Configuration notes:
interactionScopeExcludeis useful when the interaction scope is intentionally broad and dynamic. For example, a thumbnail navigation may expose all tabs asinteractionScopeso the plugin keeps subscriptions on every tab, whileinteractionScopeExclude: ':not([current])'fine-tunes the effective scope to the active tab only.
Public properties / state
enabled(boolean, read/write) – autoplay is enabled and not manually stopped.duration(number, readonly) – parsed global duration (ms). Negative / NaN means disabled.effectiveDuration(number, readonly) – current slide duration (per‑slide override or global).<= 0pauses only the current slide.remaining(number, readonly) – remaining time of the current cycle (ms).paused(boolean, readonly) – autoplay is paused explicitly by user action and can be resumed.blocked(boolean, readonly) – autoplay is temporarily suspended by external conditions (e.g. hidden viewport, user interaction, blockers).state('disabled' | 'active' | 'paused' | 'blocked' | 'idle', readonly) – exclusive summary of current autoplay state.active(boolean, readonly) – a timer is scheduled (cycle running).canRun(boolean, readonly) – runtime allowance for scheduling the autoplay timer.allowed(boolean, readonly) – backward-compatible alias ofcanRun.
Public methods
start(reason?)– starts autoplay or resumes the paused cycle.pause(reason?)– pauses autoplay preserving the remaining time.stop(reason?)– fully stops autoplay and clears the current cycle.
reason is an optional compact machine-readable token. Typical values are:
user:start:calluser:pause:calluser:stop:calluser:start:controluser:pause:controluser:stop:controlsystem:start:autosystem:pause:blocksystem:stop:blocksystem:stop:configsystem:stop:slide-changesystem:idle
Notes:
enabled = trueandactive = falseis normal when: base duration is0; current slide override is0/non‑positive; carousel not sufficiently visible; user is hovering or focused; navigation command currently not possible.- Base
duration = 0does NOT disable the plugin – it just suppresses default cycles unless a per‑slide timeout overrides it. - Negative / invalid duration disables the plugin until changed.
Manual control
Programmatic examples:
carousel.autoplay.enabled = false/truecarousel.autoplay.stop()/start()carousel.autoplay.pause()to preserve remaining time
Migration note for 6.2
In 6.2 autoplay controls are no longer configured through the esl-carousel-autoplay config object.
If you used:
<esl-carousel esl-carousel-autoplay="{control: '.btn', controlBehaviour: 'pause'}"></esl-carousel>
switch to a dedicated control mixin placed directly on the control element:
<div class="esl-carousel-nav-container">
<button esl-carousel-autoplay-control="pause">Pause autoplay</button>
<esl-carousel esl-carousel-autoplay="8s">...</esl-carousel>
</div>
In other words:
- remove
control,controlBehaviour, andcontrolClsfrom autoplay config - register
ESLCarouselAutoplayControlMixinwhere autoplay controls are needed - move control behaviour to the control host via
esl-carousel-autoplay-control
ESL Carousel Autoplay State Attribute
esl-carousel-autoplay-state is a read-only state mixin hosted directly on any element. It resolves a target carousel, listens for autoplay state changes and reflects current autoplay state on the host.
Configuration
esl-carousel-autoplay-target(target) – optional selector to find the target carousel. UsesESLTraversingQuery. Defaults to::parent(.esl-carousel-nav-container)::find(esl-carousel).
Usage
Register the mixin:
ESLCarouselAutoplayStateMixin.register();
Then attach it to any element that only needs the autoplay status:
<div class="esl-carousel-nav-container">
<span esl-carousel-autoplay-state></span>
<esl-carousel esl-carousel-autoplay="8s">...</esl-carousel>
</div>
Runtime State Attributes
When attached to an element the mixin manages the following state markers on the host:
disabled– autoplay plugin is not available on the target carouselautoplay-state– exclusive current state of the target autoplay instance. Possible values:unavailable– no autoplay plugin found on the target carouseldisabled– autoplay exists but is currently disabled/stoppedactive– autoplay cycle is runningpaused– autoplay is paused explicitly by user actionblocked– autoplay is currently blocked by viewport / interaction / blocker conditionsidle– autoplay is enabled but there is no active cycle right now
esl-carousel-autoplay-control and esl-carousel-autoplay-progress extend the same state model and add their own behaviour on top.
ESL Carousel Autoplay Control Attribute
esl-carousel-autoplay-control is a separate control mixin hosted directly on the control element. It extends esl-carousel-autoplay-state and adds action/a11y semantics.
Configuration
esl-carousel-autoplay-control(behaviour) – primary attribute. Supported values:stop(default) – toggle autoplay, resetting the cycle on each startpause– toggle autoplay, resuming the cycle from the same point
esl-carousel-autoplay-target(target) – optional selector to find the target carousel. UsesESLTraversingQuery. Defaults to::parent(.esl-carousel-nav-container)::find(esl-carousel).
Usage
Register the mixin:
ESLCarouselAutoplayControlMixin.register();
Then attach it to any external or internal control element:
<div class="esl-carousel-nav-container">
<button esl-carousel-autoplay-control="stop">Toggle autoplay</button>
<esl-carousel esl-carousel-autoplay="8s">...</esl-carousel>
</div>
Or with explicit targeting:
<button
esl-carousel-autoplay-control="pause"
esl-carousel-autoplay-target="::next">
Pause autoplay
</button>
<esl-carousel esl-carousel-autoplay="8s">...</esl-carousel>
Runtime State Attributes
When attached to an element the mixin manages the following state markers on the host:
disabled– autoplay plugin is not available on the target carousel (also useful for native<button>semantics)autoplay-state– exclusive current state of the target autoplay instance. Possible values:unavailable– no autoplay plugin found on the target carouseldisabled– autoplay exists but is currently disabled/stoppedactive– autoplay cycle is runningpaused– autoplay is paused explicitly by user actionblocked– autoplay is currently blocked by viewport / interaction / blocker conditionsidle– autoplay is enabled but there is no active cycle right now (for exampleduration: 0or current slide cannot auto-advance)
The mixin also manages aria-controls and aria-pressed for basic toggle accessibility.
Per‑Slide Timeout Customization
Use esl-carousel-autoplay-timeout on a slide to override the cycle duration for that slide. If omitted, the global duration (which may be 0) is used. If parsing fails or value is invalid, the global duration is used (NOT treated as pause unless that global duration itself is 0 / non‑positive). <= 0 per‑slide value pauses autoplay only while that slide is active.
Note: An intentionally invalid value in a media rule branch can be used to fallback to the global duration. Example:
<esl-carousel-slide esl-carousel-autoplay-timeout="0 | @desktop => inherit"></esl-carousel-slide>
Here 0 disables autoplay for this slide on non‑desktop breakpoints, while the invalid inherit token on @desktop resolves to the global autoplay duration (so autoplay runs there).
Example:
<esl-carousel esl-carousel-autoplay="3s">
<esl-carousel-slide>Default timeout (3s)</esl-carousel-slide>
<esl-carousel-slide esl-carousel-autoplay-timeout="5s">Custom (5s)</esl-carousel-slide>
<esl-carousel-slide esl-carousel-autoplay-timeout="1s">Fast (1s)</esl-carousel-slide>
<esl-carousel-slide esl-carousel-autoplay-timeout="0">Paused on this slide</esl-carousel-slide>
</esl-carousel>
Media Queries for per‑slide
<esl-carousel-slide esl-carousel-autoplay-timeout="2s | @XS => 4s | @LG => 0">
Adaptive durations (paused on @LG)
</esl-carousel-slide>
Tuple syntax variant (bound to carousel media):
<esl-carousel media="all | @XS | @SM" esl-carousel-autoplay="3s">
<esl-carousel-slide esl-carousel-autoplay-timeout="2s | 3s | 0"></esl-carousel-slide>
</esl-carousel>
Supported time formats:
- CSS times:
1s,500ms,2.5s - Plain numbers:
1000,2500 0or negative: pause for the slide- ESL media rule sets:
1s | @MD => 2s | @LG => 0
Events
esl:autoplay:change (non-bubbling, non-cancelable) emitted on the carousel when:
- Manual enable/disable changes
- Runtime allowance changes (intersection / interaction / navigation availability)
- Cycle (re)starts or stops (schedule cleared or created)
Event payload fields:
enabled– enabled state (autoplay not manually disabled and global duration is valid non‑negative value)paused– autoplay is paused explicitly by user action and may be resumedblocked– autoplay is currently blocked by runtime conditionsactive– timer scheduledstate– exclusive summary state (disabled,active,paused,blocked,idle)duration– full effective duration used for the current/next cycle (0 on idle state)remaining– remaining cycle duration (0 on finished cycle; equals full duration on reset)reason– compact machine-readable state transition token (see public methods section)
Use case examples: progress indicator, custom UI state, analytics.
ESL Carousel Autoplay Progress Attribute
esl-carousel-autoplay-progress is a read-only progress mixin hosted directly on any element. It extends esl-carousel-autoplay-state and adds autoplay progress CSS variables / animation markers.
Configuration
esl-carousel-autoplay-target(target) – optional selector to find the target carousel. UsesESLTraversingQuery. Defaults to::parent(.esl-carousel-nav-container)::find(esl-carousel).
Usage
Register the mixin:
ESLCarouselAutoplayProgressMixin.register();
Then attach it to any element that should reflect autoplay progress:
<div class="esl-carousel-nav-container">
<button esl-carousel-autoplay-progress></button>
<esl-carousel esl-carousel-autoplay="8s">...</esl-carousel>
</div>
Or with explicit targeting:
<button
esl-carousel-autoplay-progress
esl-carousel-autoplay-target="::next">
</button>
<esl-carousel esl-carousel-autoplay="8s">...</esl-carousel>
Runtime State Attributes
Like esl-carousel-autoplay-state, the progress mixin reflects the shared autoplay state model on the host:
disabled– autoplay plugin is not available on the target carouselautoplay-state– exclusive current state of the target autoplay instance. Possible values:unavailable– no autoplay plugin found on the target carouseldisabled– autoplay exists but is currently disabled/stoppedactive– autoplay cycle is runningpaused– autoplay is paused explicitly by user actionblocked– autoplay is currently blocked by viewport / interaction / blocker conditionsidle– autoplay is enabled but there is no active cycle right now
Progress Markers
The mixin also manages the following progress-specific markers on the host:
animate– pulsed on each autoplay cycle start to retrigger CSS animation--esl-autoplay-timeout– remaining cycle duration in milliseconds--esl-autoplay-duration– full cycle duration in milliseconds--esl-autoplay-progress– completed progress ratio in the0..1range
paused and blocked are intentionally separate here too:
autoplay-state="paused"means an explicit user pauseautoplay-state="blocked"means runtime blocking (viewport / interaction / blockers)- when blocking uses
blockBehaviour: 'pause', the progress mixin preserves the current remaining time while still exposingautoplay-state="blocked"
Examples
Basic autoplay
<esl-carousel esl-carousel-autoplay="10s">
<ul esl-carousel-slides>
<li esl-carousel-slide>Slide 1</li>
<li esl-carousel-slide>Slide 2</li>
<li esl-carousel-slide>Slide 3</li>
</ul>
</esl-carousel>
Base suppressed (duration 0) with per‑slide override
<esl-carousel esl-carousel-autoplay="0">
<ul esl-carousel-slides>
<li esl-carousel-slide esl-carousel-autoplay-timeout="4s">Only this slide auto advances</li>
<li esl-carousel-slide>Static (no cycle here)</li>
</ul>
</esl-carousel>
Disable below breakpoint
<esl-carousel esl-carousel-autoplay="8s | @XS => none">
(or use a negative value instead of none).
Responsive with controls and container class
<div class="esl-carousel-nav-container">
<button esl-carousel-autoplay-control="pause">Toggle autoplay</button>
<esl-carousel esl-carousel-autoplay="{duration: 0, containerCls: 'autoplay-enabled'} | @MD => 5s | @LG => 10s">
<ul esl-carousel-slides>
<li esl-carousel-slide>Slide 1</li>
<li esl-carousel-slide>Slide 2</li>
</ul>
</esl-carousel>
</div>
This keeps plugin ready (duration 0) on small screens and starts cycles only from @MD / @LG.
Short reference:
- Set global
duration = 0to keep autoplay enabled but idle until overridden per slide. - Use
none/ negative to fully disable. - Per‑slide
0pauses only that slide. enabledwritable for manual suspend/resume;activeshows scheduled timer.