
Syncfusion Angular Carousel
- 148 installs
- Updated August 4, 2026
- syncfusion/angular-ui-components-skills
Helps with ai & agent building tasks.
About
syncfusion-angular-carousel is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- syncfusion-angular-carousel
- AI & Agent Building
- AI-coding skill
Syncfusion Angular Carousel by the numbers
- 148 all-time installs (skills.sh)
- +5 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #3,363 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/angular-ui-components-skills --skill syncfusion-angular-carouselAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 148 |
|---|---|
| Last updated | August 4, 2026 |
| Repository | syncfusion/angular-ui-components-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Implementing Syncfusion Angular Carousel Component
When to Use This Skill
Use the Syncfusion Angular Carousel component when you need to:
- Display multiple items sequentially – Show images, products, or content in slide show format
- Create image galleries – Build responsive photo galleries with automatic or manual navigation
- Feature rotating content – Display featured articles, product highlights, or promotional banners
- Implement scroll-like navigation – Provide next/previous controls for content browsing
- Add animations and transitions – Create visually appealing slide effects with fade or slide animations
- Support touch interactions – Enable swipe gestures for mobile and touch devices
- Display progress indicators – Show users their position within carousel (dots, fractions, progress bars)
- Handle slide change events – Execute custom logic when slides transition
Component Overview
The Syncfusion Angular Carousel component allows users to display images with content, links, and other media in a slide show format. It provides:
- Multiple indicator types – Default dots, dynamic markers, fractions, progress bars
- Built-in animations – None, Slide, Fade, and custom animation support
- Navigation controls – Previous/next buttons with visibility options (Visible, Hidden, VisibleOnHover)
- Touch support – Swipe gestures for mobile and desktop navigation
- Auto-play functionality – Automatic slide transitions with configurable intervals
- Keyboard accessibility – Arrow key navigation and WAI-ARIA compliance
- Template support – Custom item rendering, button templates, indicator customization
- Event handling – Pre/post slide transition events (slideChanging, slideChanged) for custom logic
- Persistence – Save/restore carousel state across page reloads
- RTL support – Right-to-left layout for Arabic, Hebrew, and other RTL languages
---
Quick Start Example
Basic carousel with automatic slide transitions:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div class="carousel-container">
<ejs-carousel [autoPlay]="true" [animationEffect]="'Slide'">
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/cardinal.png" alt="Slide 1" />
<figcaption>Cardinal</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/hunei.png" alt="Slide 2" />
<figcaption>Kingfisher</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/costa-rica.png" alt="Slide 3" />
<figcaption>Keel-billed Toucan</figcaption>
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
</div>
`,
styles: [`
.carousel-container {
height: 400px;
margin: 20px 0;
}
`]
})
export class CarouselComponent {}Key result: Carousel automatically transitions between slides every 5000ms with slide animation.
---
Component Properties
30 Total Properties Organized by Category
1. Core Animation Properties
animationEffect
- Type:
'None' | 'Slide' | 'Fade' | 'Custom' - Default:
'Slide' - Description: Specifies animation effect when transitioning between slides.
// Fade animation
<ejs-carousel [animationEffect]="'Fade'">
<!-- Smooth fade in/out between slides -->
</ejs-carousel>
// No animation
<ejs-carousel [animationEffect]="'None'">
<!-- Instant slide transition -->
</ejs-carousel>
// Custom CSS animation
<ejs-carousel [animationEffect]="'Custom'" [cssClass]="'custom-animation'">
<!-- Define custom animation in CSS -->
</ejs-carousel>2. Auto-Play Properties
autoPlay
- Type:
boolean - Default:
true - Description: Enables automatic sliding through carousel items at intervals.
<ejs-carousel [autoPlay]="true" [interval]="3000">
<!-- Auto transitions every 3 seconds -->
</ejs-carousel>interval
- Type:
number - Default:
5000(milliseconds) - Description: Time between automatic slide transitions (milliseconds). Only applies when autoPlay is true.
<ejs-carousel [autoPlay]="true" [interval]="2000">
<!-- 2 second interval between slides -->
</ejs-carousel>pauseOnHover
- Type:
boolean - Default:
true - Description: Pauses auto-play when mouse hovers over carousel.
<ejs-carousel [autoPlay]="true" [pauseOnHover]="false">
<!-- Continue auto-play even on hover -->
</ejs-carousel>3. Navigation Properties
buttonsVisibility
- Type:
'Visible' | 'Hidden' | 'VisibleOnHover' - Default:
'Visible' - Description: Controls visibility of previous/next navigation buttons.
// Always visible
<ejs-carousel [buttonsVisibility]="'Visible'">
<!-- Buttons always shown -->
</ejs-carousel>
// Only on hover
<ejs-carousel [buttonsVisibility]="'VisibleOnHover'">
<!-- Buttons appear on mouse hover -->
</ejs-carousel>
// Never visible
<ejs-carousel [buttonsVisibility]="'Hidden'">
<!-- Use indicators or swipe instead -->
</ejs-carousel>previousButtonTemplate
- Type:
string | object - Default:
null - Description: Custom template for previous navigation button.
<ejs-carousel [previousButtonTemplate]="'#prevBtnTemplate'">
<ng-template #prevBtnTemplate>
<button class="custom-prev"><i class="icon-left"></i> Back</button>
</ng-template>
<e-carousel-items><!-- Items --></e-carousel-items>
</ejs-carousel>nextButtonTemplate
- Type:
string | object - Default:
null - Description: Custom template for next navigation button.
<ejs-carousel [nextButtonTemplate]="'#nextBtnTemplate'">
<ng-template #nextBtnTemplate>
<button class="custom-next">Next <i class="icon-right"></i></button>
</ng-template>
<e-carousel-items><!-- Items --></e-carousel-items>
</ejs-carousel>loop
- Type:
boolean - Default:
true - Description: Enables infinite looping - cycles back to first slide after last.
<ejs-carousel [loop]="true">
<!-- Last slide -> First slide -->
</ejs-carousel>
<ejs-carousel [loop]="false">
<!-- Last slide -> Navigation stops -->
</ejs-carousel>selectedIndex
- Type:
number - Default:
0 - Description: Initial slide index to display (0-based).
<ejs-carousel [selectedIndex]="2">
<!-- Start on third slide (index 2) -->
</ejs-carousel>4. Indicator Properties
showIndicators
- Type:
boolean - Default:
true - Description: Shows or hides position indicators.
<ejs-carousel [showIndicators]="true">
<!-- Indicators visible -->
</ejs-carousel>
<ejs-carousel [showIndicators]="false">
<!-- No indicators shown -->
</ejs-carousel>indicatorsType
- Type:
'Default' | 'Dynamic' | 'Fraction' | 'Progress' - Default:
'Default' - Description: Style of indicators displayed.
// Dot indicators
<ejs-carousel [indicatorsType]="'Default'">
<!-- Shows: ● ● ● ● ● -->
</ejs-carousel>
// Numeric format
<ejs-carousel [indicatorsType]="'Fraction'">
<!-- Shows: 1 / 5 -->
</ejs-carousel>
// Progress bar
<ejs-carousel [indicatorsType]="'Progress'">
<!-- Visual progress bar -->
</ejs-carousel>
// Animated
<ejs-carousel [indicatorsType]="'Dynamic'">
<!-- Animated indicator effect -->
</ejs-carousel>indicatorsTemplate
- Type:
string | object - Default:
null - Description: Custom template for indicators (e.g., thumbnail previews).
<ejs-carousel [indicatorsTemplate]="'#indicatorTemplate'" [showIndicators]="true">
<ng-template #indicatorTemplate let-data let-index="index">
<img [src]="items[index]?.thumbnail" class="thumb" />
</ng-template>
<e-carousel-items><!-- Items --></e-carousel-items>
</ejs-carousel>showPlayButton
- Type:
boolean - Default:
true - Description: Shows or hides play button to resume auto-play.
<ejs-carousel [autoPlay]="false" [showPlayButton]="true">
<!-- Users can click play to resume auto-play -->
</ejs-carousel>
<ejs-carousel [showPlayButton]="false">
<!-- No play button visible -->
</ejs-carousel>playButtonTemplate
- Type:
string | object - Default:
null - Description: Custom template for play button.
<ejs-carousel [playButtonTemplate]="'#playBtnTemplate'">
<ng-template #playBtnTemplate>
<button class="play-btn">▶ Resume</button>
</ng-template>
<e-carousel-items><!-- Items --></e-carousel-items>
</ejs-carousel>5. Data and Item Properties
dataSource
- Type:
any[] - Default:
null - Description: Array of data for dynamic carousel items (use with itemTemplate).
// Component
export class CarouselComponent {
public slides = [
{ id: 1, image: 'img1.jpg', title: 'Slide 1' },
{ id: 2, image: 'img2.jpg', title: 'Slide 2' },
{ id: 3, image: 'img3.jpg', title: 'Slide 3' }
];
}
// Template
<ejs-carousel [dataSource]="slides">
<ng-template #itemTemplate let-item>
<figure>
<img [src]="item.image" [alt]="item.title" />
<figcaption>{{item.title}}</figcaption>
</figure>
</ng-template>
</ejs-carousel>itemTemplate
- Type:
string | object - Default:
null - Description: Template for rendering each carousel item from dataSource.
<ejs-carousel [dataSource]="products">
<ng-template #itemTemplate let-product>
<div class="product-card">
<img [src]="product.image" />
<h3>{{product.name}}</h3>
<p>${{product.price}}</p>
</div>
</ng-template>
</ejs-carousel>items
- Type:
CarouselItem[] - Default:
[] - Description: Array of carousel items (use with e-carousel-item directive for static content).
<ejs-carousel>
<e-carousel-items>
<e-carousel-item>
<ng-template #template><img src="image1.jpg" /></ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template><img src="image2.jpg" /></ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>cssClass
- Type:
string - Default:
'' - Description: CSS class(es) for carousel container styling.
<ejs-carousel [cssClass]="'dark-theme full-width'">
<!-- Apply custom styles via CSS classes -->
</ejs-carousel>6. Interaction Properties
enableTouchSwipe
- Type:
boolean - Default:
true - Description: Enables swiping on touch devices to navigate slides.
<ejs-carousel [enableTouchSwipe]="true">
<!-- Touch swipe enabled -->
</ejs-carousel>
<ejs-carousel [enableTouchSwipe]="false">
<!-- Touch swipe disabled -->
</ejs-carousel>swipeMode
- Type:
'Touch' | 'Mouse' | 'Touch|Mouse' - Default:
'Touch|Mouse' - Description: Which interaction types enable swiping.
// Both touch and mouse
<ejs-carousel [swipeMode]="'Touch|Mouse'" [enableTouchSwipe]="true">
<!-- Both interactions work -->
</ejs-carousel>
// Touch only
<ejs-carousel [swipeMode]="'Touch'" [enableTouchSwipe]="true">
<!-- Only touch gestures work -->
</ejs-carousel>
// Mouse only
<ejs-carousel [swipeMode]="'Mouse'" [enableTouchSwipe]="true">
<!-- Only mouse drag works -->
</ejs-carousel>allowKeyboardInteraction
- Type:
boolean - Default:
true - Description: Allows arrow keys to navigate carousel.
<ejs-carousel [allowKeyboardInteraction]="true">
<!-- Arrow keys navigate slides -->
</ejs-carousel>
<ejs-carousel [allowKeyboardInteraction]="false">
<!-- Arrow keys disabled -->
</ejs-carousel>7. Dimension Properties
height
- Type:
string | number - Default:
'100%' - Description: Carousel container height (px, %, em, etc.).
// Fixed height
<ejs-carousel [height]="400">
<!-- 400px height -->
</ejs-carousel>
// Percentage
<ejs-carousel [height]="'100%'">
<!-- Full parent height -->
</ejs-carousel>width
- Type:
string | number - Default:
'100%' - Description: Carousel container width (px, %, em, etc.).
// Fixed width
<ejs-carousel [width]="800">
<!-- 800px width -->
</ejs-carousel>
// Full width
<ejs-carousel [width]="'100%'">
<!-- Full parent width -->
</ejs-carousel>partialVisible
- Type:
boolean - Default:
false - Description: Shows partial slides on sides for context.
<ejs-carousel [partialVisible]="true">
<!-- Shows portion of adjacent slides -->
</ejs-carousel>
<ejs-carousel [partialVisible]="false">
<!-- Only current slide fully visible -->
</ejs-carousel>8. Localization and Persistence
locale
- Type:
string - Default:
''(uses browser locale) - Description: Locale/language for carousel (affects aria-labels, accessibility text).
<ejs-carousel [locale]="'de-DE'">
<!-- German localization -->
</ejs-carousel>
<ejs-carousel [locale]="'fr-FR'">
<!-- French localization -->
</ejs-carousel>enablePersistence
- Type:
boolean - Default:
false - Description: Saves carousel state to localStorage (restores on page reload).
<ejs-carousel [enablePersistence]="true">
<!-- Current slide position saved and restored -->
</ejs-carousel>9. Accessibility Properties
enableRtl
- Type:
boolean - Default:
false - Description: Enables right-to-left layout for RTL languages.
<ejs-carousel [enableRtl]="true">
<!-- RTL layout for Arabic, Hebrew, etc. -->
</ejs-carousel>htmlAttributes
- Type:
Record<string, any> - Default:
null - Description: Additional HTML attributes for carousel root element.
<ejs-carousel [htmlAttributes]="{ 'data-type': 'hero', 'aria-label': 'Hero Carousel' }">
<!-- Custom attributes applied -->
</ejs-carousel>---
Component Methods
5 Total Methods
1. next()
- Signature:
next(): void - Description: Navigate to next slide programmatically.
import { Component, ViewChild } from "@angular/core";
import { CarouselComponent } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel-nav",
template: `
<button (click)="goNext()">Next</button>
<ejs-carousel #carousel>
<e-carousel-items>
<e-carousel-item><ng-template #template><img src="img1.jpg" /></ng-template></e-carousel-item>
<e-carousel-item><ng-template #template><img src="img2.jpg" /></ng-template></e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class CarouselNavComponent {
@ViewChild("carousel") carousel!: CarouselComponent;
goNext() {
this.carousel.next();
}
}2. prev()
- Signature:
prev(): void - Description: Navigate to previous slide programmatically.
export class CarouselNavComponent {
@ViewChild("carousel") carousel!: CarouselComponent;
goPrev() {
this.carousel.prev();
}
}3. play()
- Signature:
play(): void - Description: Resume automatic slide transitions.
import { Component, ViewChild } from "@angular/core";
import { CarouselComponent } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel-controls",
template: `
<button (click)="playSlides()">Play</button>
<button (click)="pauseSlides()">Pause</button>
<ejs-carousel #carousel [autoPlay]="false">
<e-carousel-items>
<e-carousel-item><ng-template #template><img src="img1.jpg" /></ng-template></e-carousel-item>
<e-carousel-item><ng-template #template><img src="img2.jpg" /></ng-template></e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class CarouselControlsComponent {
@ViewChild("carousel") carousel!: CarouselComponent;
playSlides() {
this.carousel.play();
}
pauseSlides() {
this.carousel.pause();
}
}4. pause()
- Signature:
pause(): void - Description: Pause automatic slide transitions.
export class CarouselControlsComponent {
@ViewChild("carousel") carousel!: CarouselComponent;
pauseSlides() {
this.carousel.pause();
}
}5. destroy()
- Signature:
destroy(): void - Description: Destroy carousel component and release resources. Call before component removal.
import { Component, ViewChild, OnDestroy } from "@angular/core";
import { CarouselComponent } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel-cleanup",
template: `
<ejs-carousel #carousel>
<e-carousel-items>
<e-carousel-item><ng-template #template><img src="img1.jpg" /></ng-template></e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class CarouselCleanupComponent implements OnDestroy {
@ViewChild("carousel") carousel!: CarouselComponent;
ngOnDestroy() {
// Cleanup when component destroyed
this.carousel.destroy();
}
}---
Component Events
2 Total Events
1. slideChanging
- Event Args:
SlideChangingEventArgs - Description: Triggered before slide transition (can be prevented).
- Key Use: Validate or cancel slide changes
Event Arguments:
cancel: boolean– Set true to prevent transitioncurrentIndex: number– Current slide indexcurrentSlide: HTMLElement– Current slide DOM elementnextIndex: number– Next slide index to displaynextSlide: HTMLElement– Next slide DOM elementisSwiped: boolean– Whether triggered by swipeslideDirection: 'Next' | 'Previous'– Direction of changename: string– Event name ('slideChanging')
import { Component, ViewChild } from "@angular/core";
import { CarouselComponent, SlideChangingEventArgs } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel-event",
template: `
<div class="status">Cannot navigate to slide 2</div>
<ejs-carousel #carousel (slideChanging)="onSlideChanging($event)">
<e-carousel-items>
<e-carousel-item><ng-template #template><img src="img1.jpg" /><p>Slide 1</p></ng-template></e-carousel-item>
<e-carousel-item><ng-template #template><img src="img2.jpg" /><p>Slide 2 - BLOCKED</p></ng-template></e-carousel-item>
<e-carousel-item><ng-template #template><img src="img3.jpg" /><p>Slide 3</p></ng-template></e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class CarouselEventComponent {
onSlideChanging(args: SlideChangingEventArgs) {
console.log(`Transitioning from ${args.currentIndex} to ${args.nextIndex}`);
// Prevent navigating to slide 2
if (args.nextIndex === 1) {
args.cancel = true;
alert("Slide 2 is blocked");
}
}
}2. slideChanged
- Event Args:
SlideChangedEventArgs - Description: Triggered after slide transition completes.
- Key Use: Track slide changes, update UI, log analytics
Event Arguments:
currentIndex: number– Current slide indexcurrentSlide: HTMLElement– Current slide DOM elementpreviousIndex: number– Previous slide indexpreviousSlide: HTMLElement– Previous slide DOM elementisSwiped: boolean– Whether triggered by swipeslideDirection: 'Next' | 'Previous'– Direction of changename: string– Event name ('slideChanged')
import { Component, ViewChild } from "@angular/core";
import { CarouselComponent, SlideChangedEventArgs } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel-tracking",
template: `
<div class="slide-counter">Slide {{currentSlide}} of {{totalSlides}}</div>
<ejs-carousel #carousel (slideChanged)="onSlideChanged($event)">
<e-carousel-items>
<e-carousel-item><ng-template #template><img src="img1.jpg" /></ng-template></e-carousel-item>
<e-carousel-item><ng-template #template><img src="img2.jpg" /></ng-template></e-carousel-item>
<e-carousel-item><ng-template #template><img src="img3.jpg" /></ng-template></e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class CarouselTrackingComponent {
currentSlide = 1;
totalSlides = 3;
onSlideChanged(args: SlideChangedEventArgs) {
this.currentSlide = args.currentIndex + 1;
console.log(`Now on slide ${args.currentIndex}`);
console.log(`Direction: ${args.slideDirection}`);
console.log(`Swiped: ${args.isSwiped}`);
}
}---
Default Values Reference
Complete table of default values for all 30 properties:
| Property | Default | Type |
|---|---|---|
| allowKeyboardInteraction | true | boolean |
| animationEffect | 'Slide' | string |
| autoPlay | true | boolean |
| buttonsVisibility | 'Visible' | string |
| cssClass | '' | string |
| dataSource | null | any[] |
| enablePersistence | false | boolean |
| enableRtl | false | boolean |
| enableTouchSwipe | true | boolean |
| height | '100%' | string/number |
| htmlAttributes | null | Record |
| indicatorsTemplate | null | string/object |
| indicatorsType | 'Default' | string |
| interval | 5000 | number (ms) |
| itemTemplate | null | string/object |
| items | [] | CarouselItem[] |
| locale | '' | string |
| loop | true | boolean |
| nextButtonTemplate | null | string/object |
| partialVisible | false | boolean |
| pauseOnHover | true | boolean |
| playButtonTemplate | null | string/object |
| previousButtonTemplate | null | string/object |
| selectedIndex | 0 | number |
| showIndicators | true | boolean |
| showPlayButton | true | boolean |
| swipeMode | 'Touch\ | Mouse' |
| width | '100%' | string/number |
---
Common Patterns and Use Cases
Pattern 1: Data-Bound Carousel with Dynamic Content
When to use: Loading carousel items from an API or dynamic data source.
import { Component, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";
@Component({
selector: "app-data-carousel",
template: `
<ejs-carousel [dataSource]="items" [selectedIndex]="0">
<ng-template #itemTemplate let-item>
<figure class="img-container">
<img [src]="item.image" [alt]="item.title" />
<figcaption>{{item.title}}</figcaption>
</figure>
</ng-template>
</ejs-carousel>
`
})
export class DataCarouselComponent implements OnInit {
items: any[] = [];
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get<any>('/api/carousel-items')
.subscribe(data => this.items = data);
}
}Pattern 2: Manual Navigation with Buttons
When to use: Users control slide transitions with custom buttons instead of auto-play.
import { Component, ViewChild } from "@angular/core";
import { CarouselComponent } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-manual-nav",
template: `
<div class="carousel-controls">
<button (click)="prevSlide()" class="control-btn">← Previous</button>
<span class="slide-counter">{{currentSlide}} / {{totalSlides}}</span>
<button (click)="nextSlide()" class="control-btn">Next →</button>
</div>
<ejs-carousel
#carousel
[autoPlay]="false"
[buttonsVisibility]="'Hidden'"
(slideChanged)="onSlideChanged($event)"
>
<e-carousel-items>
<e-carousel-item *ngFor="let item of items">
<ng-template #template>
<img [src]="item.image" />
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class ManualNavCarouselComponent {
@ViewChild("carousel") carousel!: CarouselComponent;
items = [
{ image: 'image1.jpg' },
{ image: 'image2.jpg' },
{ image: 'image3.jpg' }
];
currentSlide = 1;
totalSlides = this.items.length;
prevSlide() { this.carousel.prev(); }
nextSlide() { this.carousel.next(); }
onSlideChanged(event: any) {
this.currentSlide = event.currentIndex + 1;
}
}Pattern 3: Event-Driven Carousel with Custom Handlers
When to use: Execute custom logic on slide transitions, track analytics, or prevent certain actions.
import { Component, ViewChild } from "@angular/core";
import { CarouselComponent, SlideChangingEventArgs, SlideChangedEventArgs } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-event-carousel",
template: `
<div class="carousel-stats">
<p>Total Views: {{viewCount}}</p>
<p>Current: {{lastViewedSlide}}</p>
</div>
<ejs-carousel
#carousel
(slideChanging)="onSlideChanging($event)"
(slideChanged)="onSlideChanged($event)"
>
<e-carousel-items>
<e-carousel-item *ngFor="let item of slides">
<ng-template #template>
<img [src]="item.image" />
<h3>{{item.title}}</h3>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`
})
export class EventCarouselComponent {
@ViewChild("carousel") carousel!: CarouselComponent;
slides = [
{ title: 'Slide 1', image: 'image1.jpg' },
{ title: 'Slide 2', image: 'image2.jpg' },
{ title: 'Slide 3', image: 'image3.jpg' }
];
viewCount = 0;
lastViewedSlide = '';
onSlideChanging(args: SlideChangingEventArgs) {
// Example: Prevent returning to first slide
if (args.previousIndex === 1 && args.nextIndex === 0) {
console.log("Blocking return to first slide");
// args.cancel = true; // Uncomment to prevent
}
}
onSlideChanged(args: SlideChangedEventArgs) {
this.viewCount++;
this.lastViewedSlide = this.slides[args.currentIndex].title;
// Log analytics
console.log(`Viewed slide ${args.currentIndex} via ${args.slideDirection}`);
}
}---
Implementation Guides
For detailed implementation on specific topics, see:
- [Getting Started](references/getting-started.md) – Installation, setup, CSS imports, basic configuration
- [Item Population & Data](references/item-templates-and-content.md) – dataSource, templates, data binding, navigation
- [Navigation & Indicators](references/navigation-and-indicators.md) – Button controls, indicator types, customization
- [Animations & Transitions](references/animations-and-transitions.md) – Animation effects, auto-play, event handling
- [Styling & Appearance](references/styling-and-appearance.md) – CSS customization, themes, WebP, responsive
---
Next Steps
1. Choose your data approach: Use items binding for static content, dataSource for dynamic data 2. Select navigation style: Buttons, indicators, or both 3. Decide on animations: None, Slide (default), Fade, or custom CSS effects 4. Configure auto-play: Set interval and pause behavior 5. Handle events: Listen to slideChanging and slideChanged for custom logic 6. Style your carousel: Apply CSS classes and responsive design 7. Test interactions: Verify touch/keyboard navigation and event handling
See reference files for detailed implementation examples and best practices.
Animations and Transitions
Table of Contents
Animation Effects
No Animation (None)
Slides change instantly without any animation effect:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
import { CarouselAnimationEffect } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel [animationEffect]="'None'">
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/cardinal.png"
alt="Cardinal"
style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/hunei.png"
alt="Kingfisher"
style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {
public animationEffect: CarouselAnimationEffect = "None";
}Use case: Fast slide transitions without animation overhead, ideal for rapid navigation or simple galleries
Slide Animation (Default)
Slides move horizontally from one position to another:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
import { CarouselAnimationEffect } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel [animationEffect]="animationEffect">
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/cardinal.png"
alt="Cardinal"
style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/hunei.png"
alt="Kingfisher"
style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {
public animationEffect: CarouselAnimationEffect = "Slide";
}Fade Animation
Current slide fades out while next slide fades in:
@Component({
template: `
<ejs-carousel [animationEffect]="'Fade'">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Use case: Elegant transitions for image galleries or photo galleries
Custom Animation
Apply custom CSS animation effects:
@Component({
template: `
<ejs-carousel [animationEffect]="'Custom'" cssClass="parallax-carousel">
<!-- carousel items -->
</ejs-carousel>
`,
styles: [`
:host ::ng-deep .parallax-carousel {
/* Custom animation styles applied here */
}
:host ::ng-deep .parallax-carousel .e-carousel-item {
animation: parallax 0.6s ease-in-out;
}
@keyframes parallax {
0% {
opacity: 0;
transform: translateX(30px) scale(0.95);
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
transform: translateX(0) scale(1);
}
}
`],
})
export class CarouselComponent {}Switch Animation Effect
Toggle between animations:
@Component({
template: `
<div class="controls">
<button (click)="animationEffect = 'Slide'">Slide</button>
<button (click)="animationEffect = 'Fade'">Fade</button>
<button (click)="animationEffect = 'Custom'">Custom</button>
</div>
<ejs-carousel [animationEffect]="animationEffect">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
public animationEffect: CarouselAnimationEffect = "Slide";
}Transition Timing
Configure Auto-Play Interval
Set the time each slide displays (in milliseconds):
@Component({
template: `
<ejs-carousel [autoPlay]="true" [interval]="4000">
<!-- carousel items display for 4 seconds each -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Per-Item Intervals
Each carousel item can have its own display duration:
@Component({
template: `
<ejs-carousel>
<e-carousel-items>
<e-carousel-item [interval]="2000">
<ng-template #template>
<div class="slide">Quick slide (2 sec)</div>
</ng-template>
</e-carousel-item>
<e-carousel-item [interval]="4000">
<ng-template #template>
<div class="slide">Medium slide (4 sec)</div>
</ng-template>
</e-carousel-item>
<e-carousel-item [interval]="6000">
<ng-template #template>
<div class="slide">Longer slide (6 sec)</div>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`,
})
export class CarouselComponent {}Note: Per-item intervals require item directives; not available with dataSource binding
Dynamic Interval Adjustment
Change intervals programmatically:
export class CarouselComponent {
public interval = 5000;
setFastSpeed() {
this.interval = 2000; // 2 seconds
}
setNormalSpeed() {
this.interval = 5000; // 5 seconds
}
setSlowSpeed() {
this.interval = 8000; // 8 seconds
}
}Auto-Play Control
Enable/Disable Auto-Play
Control automatic slide progression:
@Component({
template: `
<div class="controls">
<button (click)="autoPlay = true">Start</button>
<button (click)="autoPlay = false">Stop</button>
</div>
<ejs-carousel [autoPlay]="autoPlay">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
public autoPlay = true;
}Pause on Hover
Automatically pause when user hovers over carousel (enabled by default):
@Component({
template: `
<ejs-carousel [pauseOnHover]="true">
<!-- carousel pauses when hovering -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Disable Pause on Hover
Continue auto-play during hover:
@Component({
template: `
<ejs-carousel [pauseOnHover]="false">
<!-- carousel continues during hover -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Looping Control
Enable or disable infinite slide cycling:
@Component({
template: `
<ejs-carousel [loop]="true">
<!-- loops back to first slide after last -->
</ejs-carousel>
`,
})
export class CarouselComponent {
public loop = true; // Enable continuous looping
}With loop=false: Last slide is the end; next button disabled at last slide
Event Handling
Listen to Slide Transitions
Capture events before and after slide changes:
import { Component } from "@angular/core";
import { SlideChangingEventArgs, SlideChangedEventArgs } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `
<ejs-carousel (slideChanging)="onSlideChanging($event)"
(slideChanged)="onSlideChanged($event)">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
onSlideChanging(args: SlideChangingEventArgs) {
console.log("Transitioning from slide", args.currentIndex, "to", args.nextIndex);
// Perform any setup before slide change
}
onSlideChanged(args: SlideChangedEventArgs) {
console.log("Transitioned to slide", args.currentIndex);
// Perform any cleanup after slide change
}
}Event Arguments Reference
SlideChangingEventArgs (Before Transition)
Triggered before a slide change occurs. Can be cancelled to prevent transition.
Available Properties:
{
cancel: boolean; // Set to true to prevent slide change
currentIndex: number; // Current slide index (0-based)
currentSlide: HTMLElement; // DOM element of current slide
nextIndex: number; // Index of slide about to display
nextSlide: HTMLElement; // DOM element of next slide
isSwiped: boolean; // Whether transition triggered by swipe/drag
slideDirection: 'Next' | 'Previous'; // Direction of transition
name: string; // Event name: 'slideChanging'
}SlideChangedEventArgs (After Transition)
Triggered after slide change completes.
Available Properties:
{
currentIndex: number; // Current slide index (0-based)
currentSlide: HTMLElement; // DOM element of current slide
previousIndex: number; // Index of previous slide
previousSlide: HTMLElement; // DOM element of previous slide
isSwiped: boolean; // Whether transition triggered by swipe/drag
slideDirection: 'Next' | 'Previous'; // Direction of transition
name: string; // Event name: 'slideChanged'
}Track Current Slide Index
Update component state when slide changes:
export class CarouselComponent {
public currentSlideIndex = 0;
onSlideChanged(args: SlideChangedEventArgs) {
this.currentSlideIndex = args.currentSlide;
console.log(`Now viewing slide ${this.currentSlideIndex + 1}`);
}
}Cancel Slide Transition
Prevent slide change in slideChanging event:
export class CarouselComponent {
onSlideChanging(args: SlideChangingEventArgs) {
// Example: Prevent transition if form has unsaved changes
if (this.hasUnsavedChanges) {
args.cancel = true;
console.log("Slide change prevented due to unsaved changes");
}
}
private hasUnsavedChanges = false;
}Custom Actions on Slide Change
Execute logic when specific slides load:
export class CarouselComponent {
onSlideChanged(args: SlideChangedEventArgs) {
const currentSlide = args.currentSlide;
if (currentSlide === 0) {
// First slide logic
console.log("Loading first slide");
} else if (currentSlide === this.totalSlides - 1) {
// Last slide logic
console.log("Loading last slide");
}
}
private totalSlides = 5;
}Swipe and Touch
Enable Touch Swipe
Allow swiping to change slides on touch devices (enabled by default):
@Component({
template: `
<ejs-carousel [enableTouchSwipe]="true">
<!-- users can swipe to navigate -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Disable Touch Swipe
Prevent swiping navigation:
@Component({
template: `
<ejs-carousel [enableTouchSwipe]="false">
<!-- swipe navigation disabled -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Configure Swipe Modes
Control which input methods (touch/mouse) trigger slide transitions:
import { CarouselSwipeMode } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `
<ejs-carousel [swipeMode]="swipeMode">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
// Touch only
public swipeMode1 = CarouselSwipeMode.Touch;
// Mouse only
public swipeMode2 = CarouselSwipeMode.Mouse;
// Both touch and mouse
public swipeMode3 = CarouselSwipeMode.Touch & CarouselSwipeMode.Mouse;
// Disable both
public swipeMode4 = ~CarouselSwipeMode.Touch & ~CarouselSwipeMode.Mouse;
// Default (all modes enabled)
public swipeMode = this.swipeMode3;
}Swipe Mode Options:
| Mode | Behavior |
|---|---|
CarouselSwipeMode.Touch | Swipe transitions via touch only |
CarouselSwipeMode.Mouse | Drag transitions via mouse only |
Touch & Mouse | Both touch and mouse trigger transitions |
~Touch & ~Mouse | Disable all swipe/drag interactions |
Responsive Swipe Configuration
Enable different swipe modes based on device:
export class CarouselComponent implements OnInit {
public swipeMode: CarouselSwipeMode;
ngOnInit() {
if (this.isTouchDevice()) {
this.swipeMode = CarouselSwipeMode.Touch;
} else {
this.swipeMode = CarouselSwipeMode.Mouse;
}
}
private isTouchDevice(): boolean {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(
navigator.userAgent
);
}
}Animation Best Practices
1. Choose animation based on content: Slide for continuous flow, Fade for artistic galleries 2. Balance intervals: Too fast = hard to read, too slow = boring (3-5 seconds ideal) 3. Pause on hover: Enable for content users might want to read 4. Swipe support: Always enable for mobile users 5. Event handlers: Use slideChanged for analytics or state updates, slideChanging for validation
Getting Started with Angular Carousel
Table of Contents
Installation and Setup
Dependencies
The Carousel component requires the following packages:
|-- @syncfusion/ej2-angular-navigations
|-- @syncfusion/ej2-angular-base
|-- @syncfusion/ej2-navigations
|-- @syncfusion/ej2-base
|-- @syncfusion/ej2-buttonsInstall the Package
Add the Syncfusion navigations package to your Angular project:
npm install @syncfusion/ej2-angular-navigationsImport the Module
In your component, import the CarouselModule:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `<!-- carousel content -->`,
})
export class CarouselComponent {}CSS Theme Setup
Import the required CSS themes in your styles.css or styles.scss:
/* Material theme */
@import "@syncfusion/ej2-angular-navigations/styles/material.css";
/* Or use other available themes:
@import "@syncfusion/ej2-angular-navigations/styles/bootstrap.css";
@import "@syncfusion/ej2-angular-navigations/styles/tailwind.css";
@import "@syncfusion/ej2-angular-navigations/styles/highcontrast.css";
*/Basic Implementation
Minimal Example
Create a basic carousel with static items:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel>
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/cardinal.png"
alt="Cardinal"
style="height:100%;width:100%;" />
<figcaption>Cardinal</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/hunei.png"
alt="Kingfisher"
style="height:100%;width:100%;" />
<figcaption>Kingfisher</figcaption>
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {}Result: Carousel displays two slides with automatic transitions every 5 seconds.
Data Binding Approaches
Approach 1: Item Binding (Static Items)
Use <e-carousel-items> for static or individually configured slides:
@Component({
template: `
<ejs-carousel>
<e-carousel-items>
<e-carousel-item [interval]="3000">
<ng-template #template>
<div class="slide-content">Slide 1</div>
</ng-template>
</e-carousel-item>
<e-carousel-item [interval]="4000">
<ng-template #template>
<div class="slide-content">Slide 2</div>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`,
})
export class CarouselComponent {}Advantage: Individual interval control per slide
Approach 2: DataSource Binding (Dynamic Content)
Use [dataSource] with itemTemplate for data-driven carousels:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel [dataSource]="products">
<ng-template #itemTemplate let-data>
<figure class="img-container">
<img [src]="data.image" [alt]="data.name" style="height:100%;width:100%;" />
<figcaption class="img-caption">{{data.name}}</figcaption>
</figure>
</ng-template>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {
public products = [
{ name: "Cardinal", image: "https://ej2.syncfusion.com/products/images/carousel/cardinal.png" },
{ name: "Kingfisher", image: "https://ej2.syncfusion.com/products/images/carousel/hunei.png" },
{ name: "Keel-billed-toucan", image: "https://ej2.syncfusion.com/products/images/carousel/costa-rica.png" },
];
}Advantage: Reusable with dynamic data, cleaner template syntax
Initial Configuration
Set Starting Slide
Use selectedIndex to specify which slide displays first:
@Component({
template: `
<ejs-carousel [selectedIndex]="2">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
selectedIndex = 2; // Start at third slide (0-indexed)
}Disable Auto-Play
Set autoPlay to false for manual-only navigation:
<ejs-carousel [autoPlay]="false">
<!-- carousel items -->
</ejs-carousel>Set Custom Intervals
Configure auto-play timing (in milliseconds):
@Component({
template: `
<ejs-carousel [autoPlay]="true" [interval]="7000">
<!-- carousel items transition every 7 seconds -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Container Sizing
Always set explicit height on the carousel container:
<div style="height: 400px; width: 100%;">
<ejs-carousel>
<!-- carousel items -->
</ejs-carousel>
</div>Why: The carousel fills its container, so container dimensions control the display size.
First Render and Initialization
The carousel initializes automatically when the component loads. All properties are set at component creation and update reactively.
To access the carousel instance for programmatic control:
import { ViewChild } from "@angular/core";
import { CarouselComponent as SyncCarousel } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `<ejs-carousel #myCarousel></ejs-carousel>`,
})
export class MyComponent {
@ViewChild("myCarousel") carousel!: SyncCarousel;
ngAfterViewInit() {
// Access carousel instance after it's initialized
console.log(this.carousel.selectedIndex);
}
}Common Issues
Issue: Carousel not displaying
- Solution: Ensure container has explicit height and carousel items have content
Issue: Images not loading
- Solution: Verify image URLs are correct and accessible; check CORS if cross-origin
Issue: Auto-play not starting
- Solution: Confirm
autoPlay="true"and container is visible in DOM
Item Population and Templating
Table of Contents
- Populating with Item Directives
- Data Source Binding
- Item Templates
- Selection and Navigation
- Partial Visible Slides
Populating with Item Directives
Static Items with Templates
Use <e-carousel-item> to manually define each slide with individual templates:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel>
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/cardinal.png"
alt="Cardinal"
style="height:100%;width:100%;" />
<figcaption class="img-caption">Cardinal</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/hunei.png"
alt="Kingfisher"
style="height:100%;width:100%;" />
<figcaption class="img-caption">Kingfisher</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/keel-billed-toucan.png"
alt="Keel-billed-toucan"
style="height:100%;width:100%;" />
<figcaption class="img-caption">Keel-billed-toucan</figcaption>
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {}Per-Item Intervals
Each item can have its own auto-play interval:
@Component({
template: `
<ejs-carousel>
<e-carousel-items>
<e-carousel-item [interval]="3000">
<ng-template #template>
<div class="slide">Quick slide (3 sec)</div>
</ng-template>
</e-carousel-item>
<e-carousel-item [interval]="5000">
<ng-template #template>
<div class="slide">Normal slide (5 sec)</div>
</ng-template>
</e-carousel-item>
<e-carousel-item [interval]="8000">
<ng-template #template>
<div class="slide">Longer slide (8 sec)</div>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`,
})
export class CarouselComponent {}Use case: Variable content length requires different view times
Data Source Binding
Basic DataSource Binding
Bind a data array to the carousel and define a common template:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel [dataSource]="birds">
<ng-template #itemTemplate let-data>
<figure class="img-container">
<img [src]="getImageUrl(data.imageName)"
[alt]="data.name"
style="height:100%;width:100%;" />
<figcaption class="img-caption">{{data.name}}</figcaption>
</figure>
</ng-template>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {
public birds = [
{ id: 1, name: "Cardinal", imageName: "cardinal" },
{ id: 2, name: "Kingfisher", imageName: "hunei" },
{ id: 3, name: "Keel-billed-toucan", imageName: "costa-rica" },
{ id: 4, name: "Yellow-warbler", imageName: "kaohsiung" },
{ id: 5, name: "Bee-eater", imageName: "bee-eater" },
];
getImageUrl(imageName: string): string {
return `https://ej2.syncfusion.com/products/images/carousel/${imageName}.png`;
}
}Dynamic Data with API
Load carousel items from an API:
import { Component, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel [dataSource]="products">
<ng-template #itemTemplate let-data>
<div class="product-slide">
<img [src]="data.imageUrl" [alt]="data.name" />
<h3>{{data.name}}</h3>
<p>${{data.price}}</p>
</div>
</ng-template>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent implements OnInit {
public products: any[] = [];
constructor(private http: HttpClient) {}
ngOnInit() {
this.http
.get("/api/products")
.subscribe((data: any) => {
this.products = data;
});
}
}Item Templates
Rich Content Templates
Templates support any HTML/Angular content:
@Component({
template: `
<ejs-carousel [dataSource]="articles" [autoPlay]="false">
<ng-template #itemTemplate let-article>
<div class="article-slide">
<img [src]="article.thumbnail" />
<div class="article-content">
<h2>{{article.title}}</h2>
<p>{{article.excerpt}}</p>
<span class="date">{{article.publishDate | date: 'MMM d, y'}}</span>
</div>
</div>
</ng-template>
</ejs-carousel>
`,
})
export class CarouselComponent {
public articles = [
{
title: "Breaking News 1",
excerpt: "Important update...",
thumbnail: "news1.jpg",
publishDate: new Date(),
},
// ... more articles
];
}Conditional Rendering in Templates
Show/hide content based on data:
<ng-template #itemTemplate let-data>
<div class="slide-content">
<img [src]="data.image" />
<div *ngIf="data.featured" class="featured-badge">Featured</div>
<h3>{{data.title}}</h3>
<p *ngIf="data.description">{{data.description}}</p>
</div>
</ng-template>Template with Event Handlers
Add interactivity within templates:
<ng-template #itemTemplate let-product>
<div class="product-slide">
<img [src]="product.image" />
<h3>{{product.name}}</h3>
<button (click)="addToCart(product)">Add to Cart</button>
</div>
</ng-template>export class CarouselComponent {
addToCart(product: any) {
console.log("Added to cart:", product);
// Handle cart logic
}
}Selection and Navigation
Set Initial Slide with selectedIndex
Display a specific slide when carousel initializes:
@Component({
template: `
<ejs-carousel [selectedIndex]="2">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
selectedIndex = 2; // Start at index 2 (third slide)
}Programmatic Navigation with prev() and next()
Navigate slides using component methods:
import { ViewChild } from "@angular/core";
import { CarouselComponent as SyncCarousel } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `
<button (click)="previousSlide()">Previous</button>
<ejs-carousel #carousel>
<!-- carousel items -->
</ejs-carousel>
<button (click)="nextSlide()">Next</button>
`,
})
export class CarouselComponent {
@ViewChild("carousel") carousel!: SyncCarousel;
previousSlide() {
this.carousel.prev();
}
nextSlide() {
this.carousel.next();
}
}Auto-Play Control with play() and pause()
Resume or pause automatic slide transitions programmatically:
import { ViewChild } from "@angular/core";
import { CarouselComponent as SyncCarousel } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `
<button (click)="pauseSlideshow()">Pause</button>
<button (click)="playSlideshow()">Play</button>
<ejs-carousel #carousel [autoPlay]="true">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
@ViewChild("carousel") carousel!: SyncCarousel;
pauseSlideshow() {
this.carousel.pause();
}
playSlideshow() {
this.carousel.play();
}
}Use case: Allow users to control auto-play independently from pauseOnHover setting
Component Cleanup with destroy()
Clean up carousel resources when component is destroyed:
import { ViewChild, OnDestroy } from "@angular/core";
import { CarouselComponent as SyncCarousel } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `
<ejs-carousel #carousel>
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent implements OnDestroy {
@ViewChild("carousel") carousel!: SyncCarousel;
ngOnDestroy() {
// Cleanup carousel before component is destroyed
if (this.carousel) {
this.carousel.destroy();
}
}
}Use case: Proper resource cleanup when carousel component is removed from DOM
Jump to Specific Slide
Set selectedIndex to jump to any slide:
export class CarouselComponent {
@ViewChild("carousel") carousel!: SyncCarousel;
goToSlide(index: number) {
this.carousel.selectedIndex = index;
}
goToFirstSlide() {
this.carousel.selectedIndex = 0;
}
goToLastSlide() {
this.carousel.selectedIndex = this.carousel.items.length - 1;
}
}Partial Visible Slides
Enable Partial Visibility
Show adjacent slides partially alongside the main slide:
@Component({
template: `
<ejs-carousel [partialVisible]="true">
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="slide1.jpg" style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="slide2.jpg" style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`,
})
export class CarouselComponent {}Partial Visibility with Looping
Combine partialVisible with loop control:
@Component({
template: `
<ejs-carousel [partialVisible]="true" [loop]="false">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Behavior:
- With
loop=true: Last slide shows as partial at the end - With
loop=false: Previous slide doesn't appear on first render
Customizing Partial Slides Size
Control the width of visible partial slides via CSS:
.e-carousel .e-carousel-items .e-carousel-item {
/* Adjust partial slide size */
}See styling-and-appearance.md for detailed CSS customization.
Edge Cases
Issue: Data hasn't loaded when carousel initializes
- Solution: Use
*ngIf="dataSource.length > 0"wrapper or check in ngOnInit
Issue: Updating dataSource doesn't refresh carousel
- Solution: Trigger change detection:
this.dataSource = [...this.dataSource]
Issue: Item intervals ignored with dataSource
- Solution: Use item directives (not dataSource) for per-item interval control
Navigation Controls and Indicators
Table of Contents
Navigator Buttons
Show or Hide Buttons
Control button visibility with buttonsVisibility property:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
import { CarouselButtonVisibility } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel [buttonsVisibility]="buttonVisibility">
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://ej2.syncfusion.com/products/images/carousel/cardinal.png"
alt="Cardinal"
style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
<!-- additional items -->
</e-carousel-items>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {
public buttonVisibility: CarouselButtonVisibility = "Visible";
// Options: "Visible" | "Hidden" | "VisibleOnHover"
}Button Visibility Options:
| Option | Behavior |
|---|---|
Visible | Previous/next buttons always visible |
Hidden | Buttons not displayed (use keyboard/swipe navigation) |
VisibleOnHover | Buttons appear only when mouse hovers over carousel |
Change Button Visibility
Toggle buttons dynamically:
export class CarouselComponent {
public buttonVisibility: CarouselButtonVisibility = "Visible";
toggleButtons() {
this.buttonVisibility =
this.buttonVisibility === "Visible" ? "Hidden" : "Visible";
}
}Indicators
Show or Hide Indicators
Control position indicator visibility:
@Component({
template: `
<ejs-carousel [showIndicators]="true">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
public showIndicators = true;
}Indicators display:
- Current position within the slide sequence
- Total number of slides
- Interactive navigation (click to jump to slide)
Custom Indicator Templates
Replace default indicators with custom markup:
@Component({
template: `
<ejs-carousel>
<ng-template #indicatorsTemplate let-data>
<div class="custom-indicator">
<span class="indicator-dot"
[class.active]="data.index === currentIndex"></span>
</div>
</ng-template>
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="slide1.jpg" style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
<!-- additional items -->
</e-carousel-items>
</ejs-carousel>
`,
styles: [`
.custom-indicator .indicator-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: rgba(255,255,255,0.5);
margin: 0 4px;
cursor: pointer;
transition: all 0.3s;
}
.custom-indicator .indicator-dot.active {
background: white;
width: 16px;
}
`],
})
export class CarouselComponent {
public currentIndex = 0;
}Indicator with Slide Preview
Show thumbnail previews in indicators:
@Component({
template: `
<ejs-carousel [dataSource]="slides">
<ng-template #indicatorsTemplate let-data>
<div class="indicator-preview">
<img [src]="slides[data.index]?.thumbnail"
class="preview-image"
alt="Preview" />
</div>
</ng-template>
<ng-template #itemTemplate let-data>
<figure class="img-container">
<img [src]="data.fullImage" style="height:100%;width:100%;" />
</figure>
</ng-template>
</ejs-carousel>
`,
styles: [`
.indicator-preview {
width: 60px;
height: 60px;
border-radius: 4px;
overflow: hidden;
}
.preview-image {
width: 100%;
height: 100%;
object-fit: cover;
}
`],
})
export class CarouselComponent {
public slides = [
{
fullImage: "full1.jpg",
thumbnail: "thumb1.jpg"
},
{
fullImage: "full2.jpg",
thumbnail: "thumb2.jpg"
},
// ... more slides
];
}Indicator Types
Default Indicator
Simple dots showing position (default type):
@Component({
template: `
<ejs-carousel [indicatorsType]="'Default'">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Appearance: Dots at bottom of carousel, clickable to navigate
Dynamic Indicator
Animated indicator that emphasizes current slide:
@Component({
template: `
<ejs-carousel [indicatorsType]="'Dynamic'">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Appearance: Indicator grows/animates to show active slide
Fraction Indicator
Shows current position as fraction (e.g., "2 of 5"):
@Component({
template: `
<ejs-carousel [indicatorsType]="'Fraction'">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Use case: Clear numerical position feedback
Progress Indicator
Visual progress bar showing position:
@Component({
template: `
<ejs-carousel [indicatorsType]="'Progress'">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Use case: Visual representation of progress through slides
Switch Indicator Types
Toggle between indicator types:
@Component({
template: `
<div class="controls">
<button (click)="indicatorsType = 'Default'">Dots</button>
<button (click)="indicatorsType = 'Fraction'">Fraction</button>
<button (click)="indicatorsType = 'Progress'">Progress</button>
</div>
<ejs-carousel [indicatorsType]="indicatorsType">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
public indicatorsType: "Default" | "Dynamic" | "Fraction" | "Progress" = "Default";
}Custom Templates
Previous Button Template
Customize the previous navigation button:
@Component({
template: `
<ejs-carousel>
<ng-template #previousButtonTemplate>
<button ejs-button
cssClass="e-flat e-round"
iconCss="e-icons e-chevron-left-double">
</button>
</ng-template>
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="slide.jpg" style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`,
})
export class CarouselComponent {}Next Button Template
Customize the next navigation button:
@Component({
template: `
<ejs-carousel>
<ng-template #nextButtonTemplate>
<button ejs-button
cssClass="e-flat e-round"
iconCss="e-icons e-chevron-right-double">
</button>
</ng-template>
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {}Button Templates with Icons
Create custom styled navigation buttons:
@Component({
template: `
<ejs-carousel>
<ng-template #previousButtonTemplate>
<div class="custom-nav-button">
<i class="fa fa-arrow-left"></i>
</div>
</ng-template>
<ng-template #nextButtonTemplate>
<div class="custom-nav-button">
<i class="fa fa-arrow-right"></i>
</div>
</ng-template>
<!-- carousel items -->
</ejs-carousel>
`,
styles: [`
.custom-nav-button {
background: rgba(0, 0, 0, 0.5);
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background 0.3s;
}
.custom-nav-button:hover {
background: rgba(0, 0, 0, 0.8);
}
`],
})
export class CarouselComponent {}Play Button Control
Show or Hide Play Button
Control auto-play button visibility:
@Component({
template: `
<ejs-carousel [showPlayButton]="true">
<!-- carousel items -->
</ejs-carousel>
`,
})
export class CarouselComponent {
public showPlayButton = true; // Toggle auto-play control
}Dependency: buttonsVisibility must not be "Hidden" for play button to appear
Play Button Template
Customize play/pause button:
import { ViewChild } from "@angular/core";
import { CarouselComponent as SyncCarousel } from "@syncfusion/ej2-angular-navigations";
@Component({
template: `
<ejs-carousel [showPlayButton]="true" #carousel>
<ng-template #playButtonTemplate>
<button class="custom-play-btn"
(click)="togglePlayPause()">
{{isPlaying ? 'Pause' : 'Play'}}
</button>
</ng-template>
<!-- carousel items -->
</ejs-carousel>
`,
styles: [`
.custom-play-btn {
padding: 8px 16px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
}
.custom-play-btn:hover {
background: #0056b3;
}
`],
})
export class CarouselComponent {
@ViewChild("carousel") carousel!: SyncCarousel;
public isPlaying = true;
togglePlayPause() {
this.carousel.autoPlay = !this.carousel.autoPlay;
this.isPlaying = this.carousel.autoPlay;
}
}Play Button State Management
Track play/pause state from component:
export class CarouselComponent {
@ViewChild("carousel") carousel!: SyncCarousel;
public playButtonLabel = "Pause";
toggleAutoPlay() {
this.carousel.autoPlay = !this.carousel.autoPlay;
this.updatePlayButtonLabel();
}
private updatePlayButtonLabel() {
this.playButtonLabel = this.carousel.autoPlay ? "Pause" : "Play";
}
}Navigation Best Practices
1. Button visibility for touch devices: Use "VisibleOnHover" on desktop, "Visible" on mobile 2. Indicator clarity: Choose type based on user need (dots for simple, fraction for position, progress for visual feedback) 3. Template consistency: Match button and indicator styling to carousel design 4. Accessibility: Ensure buttons have proper contrast and labels for screen readers 5. Play button dependency: Keep showPlayButton aligned with autoPlay setting
Styling, Appearance, and Performance
Table of Contents
- CSS Customization
- Theme Integration
- Responsive Design
- WebP Image Format
- Customizing Partial Slides
- Accessibility Styling
CSS Customization
Custom Carousel Container Styles
Apply custom CSS classes to the carousel wrapper:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div class="custom-carousel-wrapper">
<ejs-carousel cssClass="my-custom-carousel">
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="image1.jpg" style="height:100%;width:100%;" />
</figure>
</ng-template>
</e-carousel-item>
<!-- additional items -->
</e-carousel-items>
</ejs-carousel>
</div>
`,
styles: [`
:host ::ng-deep .my-custom-carousel {
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
overflow: hidden;
}
:host ::ng-deep .my-custom-carousel .e-carousel-item {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
:host ::ng-deep .my-custom-carousel .e-carousel-item img {
object-fit: cover;
}
`],
})
export class CarouselComponent {}Style Navigation Buttons
Customize previous/next button appearance:
@Component({
styles: [`
:host ::ng-deep .my-carousel .e-prev,
:host ::ng-deep .my-carousel .e-next {
background: rgba(255, 255, 255, 0.8);
color: #333;
border: none;
border-radius: 50%;
width: 48px;
height: 48px;
transition: all 0.3s ease;
}
:host ::ng-deep .my-carousel .e-prev:hover,
:host ::ng-deep .my-carousel .e-next:hover {
background: rgba(255, 255, 255, 1);
transform: scale(1.1);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
`],
})
export class CarouselComponent {}Style Indicators
Customize indicator appearance:
@Component({
styles: [`
:host ::ng-deep .my-carousel .e-indicators {
bottom: 20px;
}
:host ::ng-deep .my-carousel .e-indicator-item {
width: 12px;
height: 12px;
background: rgba(255, 255, 255, 0.5);
border-radius: 50%;
margin: 0 6px;
cursor: pointer;
transition: all 0.3s;
}
:host ::ng-deep .my-carousel .e-indicator-item.e-active {
background: white;
width: 36px;
border-radius: 6px;
}
:host ::ng-deep .my-carousel .e-indicator-item:hover {
background: rgba(255, 255, 255, 0.8);
}
`],
})
export class CarouselComponent {}Style Item Captions
Customize text overlays on carousel items:
@Component({
template: `
<ejs-carousel>
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="image.jpg" />
<figcaption class="custom-caption">
<h2>Beautiful Landscape</h2>
<p>Enjoy nature's finest</p>
</figcaption>
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
`,
styles: [`
:host ::ng-deep .custom-caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);
color: white;
padding: 40px 20px 20px;
margin: 0;
}
:host ::ng-deep .custom-caption h2 {
margin: 0;
font-size: 24px;
font-weight: bold;
}
:host ::ng-deep .custom-caption p {
margin: 8px 0 0;
font-size: 14px;
opacity: 0.9;
}
`],
})
export class CarouselComponent {}Theme Integration
Available Themes
Syncfusion provides multiple pre-built themes:
/* Material Theme (default) */
@import "@syncfusion/ej2-angular-navigations/styles/material.css";
/* Bootstrap Theme */
@import "@syncfusion/ej2-angular-navigations/styles/bootstrap.css";
/* Tailwind Theme */
@import "@syncfusion/ej2-angular-navigations/styles/tailwind.css";
/* High Contrast Theme */
@import "@syncfusion/ej2-angular-navigations/styles/highcontrast.css";
/* Fabric Theme */
@import "@syncfusion/ej2-angular-navigations/styles/fabric.css";Override Theme Colors
Customize theme colors via CSS variables:
:root {
/* Material theme color variables */
--control-primary: #0066cc;
--control-secondary: #f5f5f5;
--control-border: #e0e0e0;
}
/* Override specific carousel colors */
.my-carousel .e-carousel-item {
background: var(--control-secondary);
}
.my-carousel .e-prev,
.my-carousel .e-next {
background: var(--control-primary);
}Dark Mode Theme
Implement dark mode variant:
@media (prefers-color-scheme: dark) {
:root {
--carousel-bg: #1a1a1a;
--carousel-text: #ffffff;
--carousel-border: #333333;
}
.e-carousel {
background: var(--carousel-bg);
color: var(--carousel-text);
}
.e-carousel .e-prev,
.e-carousel .e-next {
background: rgba(255, 255, 255, 0.1);
border: 1px solid var(--carousel-border);
}
}Responsive Design
Mobile Responsive Carousel
Adapt carousel layout for different screen sizes:
@Component({
template: `
<div [ngClass]="{'carousel-mobile': isMobile, 'carousel-desktop': !isMobile}">
<ejs-carousel [buttonsVisibility]="buttonVisibility"
[showIndicators]="showIndicators">
<e-carousel-items>
<!-- carousel items -->
</e-carousel-items>
</ejs-carousel>
</div>
`,
styles: [`
/* Desktop layout */
.carousel-desktop {
height: 500px;
border-radius: 8px;
}
/* Mobile layout */
.carousel-mobile {
height: 300px;
border-radius: 4px;
}
/* Tablet layout */
@media (max-width: 768px) {
.carousel-desktop {
height: 350px;
}
}
/* Small mobile */
@media (max-width: 480px) {
.carousel-mobile {
height: 200px;
}
}
`],
})
export class CarouselComponent implements OnInit {
public isMobile = false;
public buttonVisibility: "Visible" | "Hidden" | "VisibleOnHover" = "Visible";
public showIndicators = true;
ngOnInit() {
this.adjustForScreenSize();
window.addEventListener("resize", () => this.adjustForScreenSize());
}
private adjustForScreenSize() {
this.isMobile = window.innerWidth <= 768;
this.buttonVisibility = this.isMobile ? "VisibleOnHover" : "Visible";
}
}Flexible Container Sizing
Make carousel responsive with CSS:
.carousel-container {
width: 100%;
max-width: 900px;
margin: 0 auto;
}
.carousel-container::before {
content: "";
display: block;
padding-bottom: 66.67%; /* 3:2 aspect ratio */
}
.carousel-container .e-carousel {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}WebP Image Format
Load WebP Images for Performance
Use WebP format for better compression and faster loading:
import { Component } from "@angular/core";
import { CarouselModule } from "@syncfusion/ej2-angular-navigations";
@Component({
selector: "app-carousel",
standalone: true,
imports: [CarouselModule],
template: `
<div style="height: 400px;">
<ejs-carousel>
<e-carousel-items>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://www.gstatic.com/webp/gallery/1.webp"
alt="Majestic Valley View"
style="height:100%;width:100%;" />
<figcaption>Majestic Valley View</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://www.gstatic.com/webp/gallery/2.webp"
alt="Thrilling Rapids Adventure"
style="height:100%;width:100%;" />
<figcaption>Thrilling Rapids Adventure</figcaption>
</figure>
</ng-template>
</e-carousel-item>
<e-carousel-item>
<ng-template #template>
<figure class="img-container">
<img src="https://www.gstatic.com/webp/gallery/3.webp"
alt="Snowy Stroll"
style="height:100%;width:100%;" />
<figcaption>Snowy Stroll</figcaption>
</figure>
</ng-template>
</e-carousel-item>
</e-carousel-items>
</ejs-carousel>
</div>
`,
})
export class CarouselComponent {}WebP with Fallback Support
Use picture element for browser compatibility:
<ng-template #itemTemplate let-data>
<figure class="img-container">
<picture>
<!-- WebP format for modern browsers -->
<source [srcset]="data.imageWebP" type="image/webp">
<!-- Fallback for older browsers -->
<img [src]="data.imageJpg" [alt]="data.title" style="height:100%;width:100%;" />
</picture>
<figcaption>{{data.title}}</figcaption>
</figure>
</ng-template>export class CarouselComponent {
public images = [
{
title: "Image 1",
imageWebP: "image1.webp",
imageJpg: "image1.jpg"
},
{
title: "Image 2",
imageWebP: "image2.webp",
imageJpg: "image2.jpg"
},
];
}Benefits of WebP
| Aspect | Benefit |
|---|---|
| File Size | 25-35% smaller than JPEG/PNG |
| Load Speed | Faster initial render and transitions |
| Bandwidth | Reduced data usage on mobile |
| Quality | Maintains visual fidelity at lower file sizes |
Customizing Partial Slides
Adjust Partial Slide Width
Control the visibility of adjacent slides when partialVisible is enabled:
:host ::ng-deep .e-carousel {
/* Default partial slide size - 30% of container width */
}
:host ::ng-deep .e-carousel.custom-partial .e-carousel-item {
/* Adjust width to show more or less of adjacent slides */
width: 70%; /* Shows partial 30% of adjacent slide */
}Partial Slides Styling
Style partial slides differently from active slide:
:host ::ng-deep .e-carousel-item {
opacity: 1;
transition: opacity 0.3s ease;
}
/* Partial (non-active) slides */
:host ::ng-deep .e-carousel-item:not(.e-active) {
opacity: 0.6;
filter: blur(2px);
}Accessibility Styling
High Contrast Mode
Ensure carousel is readable in high contrast:
@media (prefers-contrast: more) {
:host ::ng-deep .e-carousel {
border: 2px solid currentColor;
}
:host ::ng-deep .e-carousel .e-prev,
:host ::ng-deep .e-carousel .e-next {
border: 2px solid currentColor;
background: white;
color: black;
}
:host ::ng-deep .e-carousel .e-indicator-item {
border: 1px solid currentColor;
}
}Focus Indicators
Highlight focusable elements for keyboard navigation:
:host ::ng-deep .e-carousel .e-prev:focus,
:host ::ng-deep .e-carousel .e-next:focus {
outline: 3px solid #4A90E2;
outline-offset: 2px;
}
:host ::ng-deep .e-carousel .e-indicator-item:focus {
outline: 2px solid #4A90E2;
border-radius: 50%;
}Color Contrast
Ensure text/buttons have sufficient contrast:
/* Minimum WCAG AA contrast ratio: 4.5:1 for text */
:host ::ng-deep .e-carousel .custom-caption {
background: rgba(0, 0, 0, 0.8); /* Darker overlay for contrast */
color: #ffffff; /* White text on dark background */
}
:host ::ng-deep .e-carousel .e-prev,
:host ::ng-deep .e-carousel .e-next {
background: #0066cc; /* Strong color contrast */
color: white;
}Performance Tips
1. Use WebP images: Reduce file sizes and load times 2. Lazy load images: Load only visible/adjacent slides 3. Optimize container height: Avoid reflows with explicit sizing 4. Minimize CSS: Reduce style calculations 5. Debounce resize events: Avoid constant recalculations on resize 6. Use requestAnimationFrame: Smooth animations aligned with browser refresh