Hero Slider
Full-bleed single-slide carousel for the top of a page. Use this when each slide is a marketing message, banner, or call to action that should fill the hero area.
<div class="nds-swiper nds-hero nds-oncolor">
<div class="nds-swiper-wrapper">
<div class="nds-swiper-slide">
<div class="slide-content"
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 400px; display: flex; align-items: center; justify-content: center; padding: 2rem; border-radius: 8px;">
<div style="max-width: 800px; text-align: center;">
<h2 style="color: white; font-size: 2.5rem; font-weight: 700; margin-bottom: 1rem;">Welcome to Our Platform</h2>
<p style="color: white; font-size: 1.25rem; margin-bottom: 2rem; opacity: 0.95;">Discover innovative solutions for your digital needs</p>
<button class="nds-btn nds-primary nds-lg nds-oncolor">
<span class="nds-label">Get Started</span>
</button>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="slide-content"
style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); min-height: 400px; display: flex; align-items: center; justify-content: center; padding: 2rem; border-radius: 8px;">
<div style="max-width: 800px; text-align: center;">
<h2 style="color: white; font-size: 2.5rem; font-weight: 700; margin-bottom: 1rem;">Powerful Features</h2>
<p style="color: white; font-size: 1.25rem; margin-bottom: 2rem; opacity: 0.95;">Built with the latest technology and best practices</p>
<button class="nds-btn nds-primary nds-lg nds-oncolor">
<span class="nds-label">Learn More</span>
</button>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="slide-content"
style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); min-height: 400px; display: flex; align-items: center; justify-content: center; padding: 2rem; border-radius: 8px;">
<div style="max-width: 800px; text-align: center;">
<h2 style="color: white; font-size: 2.5rem; font-weight: 700; margin-bottom: 1rem;">Start Your Journey</h2>
<p style="color: white; font-size: 1.25rem; margin-bottom: 2rem; opacity: 0.95;">Join thousands of satisfied users today</p>
<button class="nds-btn nds-primary nds-lg nds-oncolor">
<span class="nds-label">Join Now</span>
</button>
</div>
</div>
</div>
</div>
<div class="nds-swiper-navigation">
<div class="nds-swiper-buttons">
<button class="nds-btn nds-subtle nds-icon-only nds-oncolor nds-prev" aria-label="Previous slide"></button>
<button class="nds-btn nds-subtle nds-icon-only nds-oncolor nds-next" aria-label="Next slide"></button>
</div>
<div class="nds-swiper-pagination"></div>
</div>
</div>
Hero with Images
Hero slider where each slide is a full-bleed image. Pick this when the imagery itself carries the message: photo galleries, campaign banners, or visual storytelling at the top of a page.
<div class="nds-swiper nds-hero nds-oncolor">
<div class="nds-swiper-wrapper">
<div class="nds-swiper-slide">
<img data-src="https://picsum.photos/id/1015/800/450" alt="Landscape 1"
style="width: 100%; height: 450px; object-fit: cover; border-radius: 8px;">
</div>
<div class="nds-swiper-slide">
<img data-src="https://picsum.photos/id/1018/800/450" alt="Landscape 2"
style="width: 100%; height: 450px; object-fit: cover; border-radius: 8px;">
</div>
<div class="nds-swiper-slide">
<img data-src="https://picsum.photos/id/1039/800/450" alt="Landscape 3"
style="width: 100%; height: 450px; object-fit: cover; border-radius: 8px;">
</div>
<div class="nds-swiper-slide">
<img data-src="https://picsum.photos/id/1043/800/450" alt="Landscape 4"
style="width: 100%; height: 450px; object-fit: cover; border-radius: 8px;">
</div>
<div class="nds-swiper-slide">
<img data-src="https://picsum.photos/id/870/800/450" alt="Landscape 5"
style="width: 100%; height: 450px; object-fit: cover; border-radius: 8px;">
</div>
</div>
<div class="nds-swiper-navigation">
<div class="nds-swiper-buttons">
<button class="nds-btn nds-subtle nds-icon-only nds-oncolor nds-prev" aria-label="Previous slide"></button>
<button class="nds-btn nds-subtle nds-icon-only nds-oncolor nds-next" aria-label="Next slide"></button>
</div>
<div class="nds-swiper-pagination"></div>
</div>
</div>
Responsive Multi-Slide
Display multiple slides at once with responsive breakpoints: 4 slides on large desktop, 3 on desktop, and 1 on mobile/tablet.
<div class="nds-swiper" hidden slides-max="4" slides-mid="3" slides-min="1" peek="0">
<div class="nds-swiper-wrapper">
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 1</h4>
<p class="nds-card-description">Multi-slide example with responsive breakpoints.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 2</h4>
<p class="nds-card-description">Resize the browser to see responsive behavior.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 3</h4>
<p class="nds-card-description">Drag or use arrows to navigate.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 4</h4>
<p class="nds-card-description">Native scroll-snap behavior.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 5</h4>
<p class="nds-card-description">Full RTL/LTR support.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 6</h4>
<p class="nds-card-description">Touch and keyboard navigation.</p>
</div>
</div>
</div>
</div>
<div class="nds-swiper-navigation">
<div class="nds-swiper-buttons">
<button class="nds-btn nds-primary nds-icon-only nds-circle nds-md nds-prev" type="button" aria-label="Previous slide"></button>
<button class="nds-btn nds-primary nds-icon-only nds-circle nds-md nds-next" type="button" aria-label="Next slide"></button>
</div>
<div class="nds-swiper-pagination"></div>
</div>
</div>
Peek Mode
Show partial next/previous slides to indicate more content. Use the peek attribute to set the visible amount in pixels.
<div class="nds-swiper" hidden slides-max="3" slides-mid="2" slides-min="1" peek="40">
<div class="nds-swiper-wrapper">
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 1</h4>
<p class="nds-card-description">Peek mode shows partial adjacent slides.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 2</h4>
<p class="nds-card-description">Users can see there's more content.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 3</h4>
<p class="nds-card-description">This encourages scrolling/navigation.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 4</h4>
<p class="nds-card-description">Configurable peek amount in pixels.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 5</h4>
<p class="nds-card-description">Works with any slides-per-view.</p>
</div>
</div>
</div>
<div class="nds-swiper-slide">
<div class="nds-card nds-stroke nds-shadow">
<div class="nds-card-content">
<h4 class="nds-card-title">Card 6</h4>
<p class="nds-card-description">Last slide in the carousel.</p>
</div>
</div>
</div>
</div>
<div class="nds-swiper-navigation">
<div class="nds-swiper-buttons">
<button class="nds-btn nds-primary nds-icon-only nds-circle nds-md nds-prev" type="button" aria-label="Previous slide"></button>
<button class="nds-btn nds-primary nds-icon-only nds-circle nds-md nds-next" type="button" aria-label="Next slide"></button>
</div>
<div class="nds-swiper-pagination"></div>
</div>
</div>
Built-in Features
Every nds-swiper on the page initializes automatically on load with no setup code required.
Slides snap into place using CSS scroll-snap, giving smooth drag-to-scroll on desktop and natural swipe gestures on touch devices.
Three-tier slide counts (slides-max, slides-mid, slides-min) adjust the visible slides at 960px and 600px breakpoints.
Images with data-src or data-srcset load automatically as slides approach the viewport, reducing initial page weight.
Arrow keys navigate between slides, Home jumps to the first, and End to the last. All keys are direction-aware for RTL layouts.
Set a peek value in pixels to reveal partial adjacent slides, signaling that more content is available.
Swipers inside hidden containers like tabs or modals re-measure and render correctly when they become visible.
Access any swiper instance via element._ndsSwiper to call slideTo(), prev(), next(), or destroy().
Usage Guidelines
Best Practices
- Use the swiper for horizontally browsable collections like featured services, image galleries, or card carousels where showing everything at once would overwhelm the layout
- Use the hero variant (
nds-hero) for full-width banner sliders with background images or gradient slides at the top of a page - Use
data-srcanddata-srcsetfor lazy loading images rather than standardsrcto reduce initial page weight - Do not use swiper for content that should be visible all at once. Use Grid for static card layouts or Tabs for switchable content panels
- Do not place interactive form controls inside slides. Keep slide content to display elements: text, images, cards, and links
- Add
peek="40"when the slide count exceeds the visible slots, giving users a visual cue that more content is available - Set
hiddenon thends-swiperelement for multi-slide swipers to prevent a flash of unstyled content before JS initializes - Keep slide heights consistent within a swiper. Mix uneven heights and the tallest slide will define the row height for all others
- Always include
aria-labelon navigation buttons with clear directional text like "Previous slide" and "Next slide" - For full-width section breakouts, place the swiper inside a
nds-section-body nds-max-widthcontainer so it can span beyond the content padding
Modifier Classes
| Class | Applied to | Description |
|---|---|---|
nds-hero | .nds-swiper | Full-width single-slide hero mode with overlay navigation absolutely positioned at the bottom |
nds-oncolor | .nds-swiper | Adjusts pagination bullets and navigation contrast for dark or image backgrounds |
nds-center | .nds-swiper-navigation | Centers the bullets and pushes the prev/next buttons to the outer edges of the navigation row |
Data Attributes
| Attribute | Description |
|---|---|
slides-max="3" | Slides visible at large breakpoint (viewport >= 960px). Default: 1 |
slides-mid="2" | Slides visible at medium breakpoint (600px to 959px). Default: 1 |
slides-min="1" | Slides visible at small breakpoint (viewport < 600px). Default: 1 |
peek="40" | Pixels of adjacent slides to reveal. Only applies when there are multiple pages. Default: 0 |
hidden | Prevents flash of unstyled content. The swiper removes it after initialization |
CSS Custom Properties
Set these on .nds-swiper (or .nds-bullet) to override the defaults. Resolved tokens like --swiper-gap, --swiper-peek, --swiper-slides, and --swiper-total are managed by the component and should not be set directly.
| Property | Default | Description |
|---|---|---|
--gap | var(--spacing-xl) | Gap between slides |
--bullet-default | var(--colors-neutral-200) | Inactive pagination bullet color (light theme); auto-shifts to neutral-700 in dark mode and to a translucent white on hero/on-color backgrounds |
--bullet-active | var(--colors-primary-sa-flag-600-primary) | Active pagination bullet color; switches to base white on hero/on-color backgrounds |
--bullet-border | transparent | Border color around the pagination bullets |
JavaScript API
All nds-swiper elements initialize automatically. Access an instance via element._ndsSwiper.