|
1 | 1 | ---
|
2 | 2 | description: "Display multiple items in a rotating view"
|
3 | 3 | icon: RotateCw
|
| 4 | +status: complete |
4 | 5 | ---
|
5 | 6 |
|
| 7 | +import { BrowserSupport } from "@app/_components/browser-support"; |
6 | 8 | import { Callout } from "nextra/components";
|
7 | 9 |
|
8 | 10 | # Carousel
|
9 | 11 |
|
10 |
| -<Callout type="warning"> |
11 |
| - This page is empty for now. Please help us by |
12 |
| - [contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md) |
13 |
| - to add content. |
14 |
| -</Callout> |
| 12 | +**_(Also called slider, slideshow, image rotator)_** |
| 13 | + |
| 14 | +## Overview |
| 15 | + |
| 16 | +A **carousel** is a UI component that displays a set of content or images in a rotating or sliding manner. Users can navigate through the content using arrows, dots, or swipe gestures on touch devices. |
| 17 | + |
| 18 | +Carousels are often used to showcase featured content, promotions, or image galleries in a limited space. |
| 19 | + |
| 20 | +## Use Cases |
| 21 | + |
| 22 | +### When to use: |
| 23 | + |
| 24 | +- When you have a series of related content or images to display in a limited space |
| 25 | +- To highlight featured content, promotions, or key messages |
| 26 | +- For storytelling or step-by-step guides that benefit from a linear progression |
| 27 | +- When you want to add visual interest and engagement to a page |
| 28 | + |
| 29 | +### When not to use: |
| 30 | + |
| 31 | +- When the content is critical for users to see or interact with immediately |
| 32 | +- If the content doesn't have a clear relationship or narrative flow |
| 33 | +- When users need to compare items side-by-side or view all options at once |
| 34 | +- If the carousel contains too many items, making navigation cumbersome |
| 35 | +- When the content is complex or requires significant reading time |
| 36 | + |
| 37 | +### Common scenarios and examples |
| 38 | + |
| 39 | +- Showcasing featured products or services on a homepage |
| 40 | +- Displaying a portfolio of work or case studies |
| 41 | +- Presenting customer testimonials or reviews |
| 42 | +- Guiding users through a multi-step process or tutorial |
| 43 | +- Highlighting event announcements or news updates |
| 44 | + |
| 45 | +## Benefits |
| 46 | + |
| 47 | +- Maximizes the use of limited screen space for featuring content |
| 48 | +- Helps guide users through a series of related items or messages |
| 49 | +- Can increase engagement and time spent on a page |
| 50 | +- Allows for visual storytelling and brand expression |
| 51 | +- Provides an interactive element for users to explore |
| 52 | + |
| 53 | +## Anatomy |
| 54 | + |
| 55 | +### Component Structure |
| 56 | + |
| 57 | +```mermaid |
| 58 | +graph TD |
| 59 | + A[Carousel] --> B[Container] |
| 60 | + B --> C[Content Wrapper] |
| 61 | + B --> D[Navigation Controls] |
| 62 | + B --> E[Pagination] |
| 63 | + B --> P[See All Link] |
| 64 | +
|
| 65 | + C --> F[Slides] |
| 66 | + F --> G[Slide 1] |
| 67 | + F --> H[Slide 2] |
| 68 | + F --> I[Slide n...] |
| 69 | +
|
| 70 | + D --> J[Previous Button] |
| 71 | + D --> K[Next Button] |
| 72 | +
|
| 73 | + E --> L[Pagination Dots] |
| 74 | +
|
| 75 | + G --> M[Image] |
| 76 | + G --> N[Caption] |
| 77 | + G --> O[Content] |
| 78 | +``` |
| 79 | + |
| 80 | +1. **Container** |
| 81 | + |
| 82 | +- Wraps the carousel content and controls |
| 83 | +- Defines the visible area and overall dimensions of the carousel |
| 84 | +- Can have a border, background color, or shadow to visually separate it from other content |
| 85 | + |
| 86 | +2. **Content Wrapper** |
| 87 | + |
| 88 | +- Contains the individual carousel slides or items |
| 89 | +- Allows for smooth transitioning between slides |
| 90 | +- Often uses CSS transforms or absolute positioning for slide placement |
| 91 | + |
| 92 | +3. **Slides** |
| 93 | + |
| 94 | +- The individual content items displayed within the carousel |
| 95 | +- Can contain images, text, videos, or other interactive elements |
| 96 | +- Should have consistent dimensions and styling for a cohesive appearance |
| 97 | + |
| 98 | +4. **Navigation Arrows** |
| 99 | + |
| 100 | +- Allow users to manually advance or go back through the carousel slides |
| 101 | +- Typically placed on the left and right sides of the carousel |
| 102 | +- Should have clear hover and focus states for accessibility |
| 103 | + |
| 104 | +5. **Pagination Dots** |
| 105 | + |
| 106 | +- Indicate the total number of slides and the current active slide |
| 107 | +- Allow users to quickly jump to a specific slide |
| 108 | +- Often placed below the carousel content for easy access |
| 109 | + |
| 110 | +6. **"See All" Link** |
| 111 | + |
| 112 | +- Provides a way for users to access more related content beyond what's shown in the carousel |
| 113 | +- Typically placed near the carousel, often below the slides or next to the pagination dots |
| 114 | +- Should have a clear and descriptive label indicating where it will take the user (e.g., "See All Products", "View More Cases") |
| 115 | + |
| 116 | +7. **Captions (Optional)** |
| 117 | + |
| 118 | +- Provide additional context or information about each slide |
| 119 | +- Can be overlaid on the slide image or placed below the slide |
| 120 | +- Should be concise and not obstruct the main slide content |
| 121 | + |
| 122 | +## Best Practices |
| 123 | + |
| 124 | +### Content |
| 125 | + |
| 126 | +**Do's ✅** |
| 127 | + |
| 128 | +- Keep slide content focused and concise for easy scanning |
| 129 | +- Use high-quality, visually compelling images that support the content message |
| 130 | +- Ensure slide content is mobile-friendly and legible on smaller screens |
| 131 | +- Provide meaningful alt text for slide images |
| 132 | +- Keep the number of slides manageable to avoid carousel fatigue |
| 133 | +- Include a "See All" link to direct users to a dedicated page with more related content (e.g., "See All Case Studies") |
| 134 | + |
| 135 | +**Don'ts ❌** |
| 136 | + |
| 137 | +- Don't rely solely on the carousel to convey critical information |
| 138 | +- Avoid using too much text or overly complex layouts within slides |
| 139 | +- Don't make the carousel autoplay without also providing pause/stop controls |
| 140 | +- Don't use the carousel as a primary navigation mechanism for your site |
| 141 | + |
| 142 | +### Accessibility & UX |
| 143 | + |
| 144 | +**Do's ✅** |
| 145 | + |
| 146 | +- Ensure all slide content and controls are keyboard accessible |
| 147 | +- Provide ARIA labels for navigation elements and slide content |
| 148 | +- Allow users to pause or stop auto-rotating carousels |
| 149 | +- Give users sufficient time to read and interact with each slide |
| 150 | +- Make navigation controls large enough for easy clicking or tapping |
| 151 | +- Ensure the "See All" link is keyboard accessible and has a clear focus state |
| 152 | +- Provide a meaningful ARIA label for the "See All" link that describes its purpose |
| 153 | + |
| 154 | +**Don'ts ❌** |
| 155 | + |
| 156 | +- Don't autoplay content that contains animation or video without user consent |
| 157 | +- Avoid using carousel designs that trap keyboard focus within the component |
| 158 | +- Don't hide navigation controls or make them difficult to find |
| 159 | +- Don't change slide content or position while the user is interacting with it |
| 160 | + |
| 161 | +### Visual Design |
| 162 | + |
| 163 | +**Do's ✅** |
| 164 | + |
| 165 | +- Use consistent design patterns and styling for all carousel elements |
| 166 | +- Provide ample visual contrast for text and interactive components |
| 167 | +- Ensure slide transitions are smooth and not visually jarring |
| 168 | +- Use navigation indicators that clearly convey the current slide position |
| 169 | +- Optimize slide images for fast loading and performance |
| 170 | + |
| 171 | +**Don'ts ❌** |
| 172 | + |
| 173 | +- Don't use overly distracting transition effects that detract from the content |
| 174 | +- Avoid using low contrast or hard-to-read text over busy background images |
| 175 | +- Don't make the carousel unnecessarily large or overwhelming on the page |
| 176 | + |
| 177 | +### Layout & Positioning |
| 178 | + |
| 179 | +**Do's ✅** |
| 180 | + |
| 181 | +- Position the carousel in a prominent location that supports its content purpose |
| 182 | +- Ensure the carousel scales and adapts responsively to different screen sizes |
| 183 | +- Provide ample spacing between the carousel and surrounding page elements |
| 184 | +- Left-align slide content for easier reading and scanning |
| 185 | +- Place navigation controls in intuitive and easy-to-reach locations |
| 186 | + |
| 187 | +**Don'ts ❌** |
| 188 | + |
| 189 | +- Don't place the carousel too low on the page where users might miss it |
| 190 | +- Avoid positioning the carousel in a way that obstructs other important content |
| 191 | +- Don't force users to scroll unnecessarily to view the full carousel on smaller screens |
| 192 | +- Don't overcrowd the carousel area with too many competing elements or CTAs |
| 193 | + |
| 194 | +## Code Examples |
| 195 | + |
| 196 | +### Basic Implementation |
| 197 | + |
| 198 | +```html |
| 199 | +<!-- Carousel --> |
| 200 | +<div class="carousel"> |
| 201 | + <div class="carousel-content"> |
| 202 | + <!-- Slides --> |
| 203 | + <div class="carousel-slide"> |
| 204 | + <img src="slide1.jpg" alt="Slide 1" /> |
| 205 | + <div class="carousel-caption">Caption for slide 1</div> |
| 206 | + </div> |
| 207 | + <div class="carousel-slide"> |
| 208 | + <img src="slide2.jpg" alt="Slide 2" /> |
| 209 | + <div class="carousel-caption">Caption for slide 2</div> |
| 210 | + </div> |
| 211 | + <!-- More slides... --> |
| 212 | + </div> |
| 213 | + |
| 214 | + <!-- Controls --> |
| 215 | + <button class="carousel-prev" aria-label="Previous slide"><</button> |
| 216 | + <button class="carousel-next" aria-label="Next slide">></button> |
| 217 | + |
| 218 | + <!-- Pagination --> |
| 219 | + <div class="carousel-pagination"> |
| 220 | + <button class="carousel-dot active" aria-current="true"></button> |
| 221 | + <button class="carousel-dot"></button> |
| 222 | + <!-- More dots... --> |
| 223 | + </div> |
| 224 | + |
| 225 | + <!-- "See All" Link --> |
| 226 | + <a href="/all-slides" class="carousel-see-all">See All</a> |
| 227 | +</div> |
| 228 | +``` |
| 229 | + |
| 230 | +## Browser Support |
| 231 | + |
| 232 | +<BrowserSupport |
| 233 | + features={[ |
| 234 | + "css.properties.scroll-snap-align", |
| 235 | + "css.properties.scroll-snap-stop", |
| 236 | + "css.properties.overscroll-behavior", |
| 237 | + ]} |
| 238 | +/> |
| 239 | + |
| 240 | +## Design Tokens |
| 241 | + |
| 242 | +These design tokens follow the [Design Tokens Format](https://design-tokens.github.io/community-group/format/) specification and can be used with various token transformation tools to generate platform-specific variables. |
| 243 | + |
| 244 | +### Carousel Tokens in DTF Format |
| 245 | + |
| 246 | +```json |
| 247 | +{ |
| 248 | + "$schema": "https://design-tokens.org/schema.json", |
| 249 | + "carousel": { |
| 250 | + "container": { |
| 251 | + "minHeight": { "value": "400px", "type": "dimension" }, |
| 252 | + "padding": { "value": "2rem", "type": "dimension" } |
| 253 | + }, |
| 254 | + "slide": { |
| 255 | + "gap": { "value": "1rem", "type": "dimension" }, |
| 256 | + "background": { "value": "{color.gray.100}", "type": "color" } |
| 257 | + }, |
| 258 | + "seeAllLink": { |
| 259 | + "fontWeight": { "value": "600", "type": "fontWeight" }, |
| 260 | + "fontSize": { "value": "1rem", "type": "dimension" }, |
| 261 | + "color": { |
| 262 | + "default": { "value": "{color.primary.600}", "type": "color" }, |
| 263 | + "hover": { "value": "{color.primary.700}", "type": "color" } |
| 264 | + }, |
| 265 | + "marginTop": { "value": "1rem", "type": "dimension" } |
| 266 | + }, |
| 267 | + "navigation": { |
| 268 | + "arrow": { |
| 269 | + "color": { "value": "{color.gray.700}", "type": "color" }, |
| 270 | + "background": { |
| 271 | + "default": { "value": "{color.white}", "type": "color" }, |
| 272 | + "hover": { "value": "{color.gray.200}", "type": "color" } |
| 273 | + }, |
| 274 | + "border": { "value": "none", "type": "borderStyle" }, |
| 275 | + "size": { "value": "3rem", "type": "dimension" }, |
| 276 | + "icon": { |
| 277 | + "previous": { "value": "{icon.chevronLeft}", "type": "icon" }, |
| 278 | + "next": { "value": "{icon.chevronRight}", "type": "icon" } |
| 279 | + } |
| 280 | + }, |
| 281 | + "dot": { |
| 282 | + "spacing": { "value": "0.75rem", "type": "dimension" }, |
| 283 | + "size": { |
| 284 | + "default": { "value": "0.75rem", "type": "dimension" }, |
| 285 | + "active": { "value": "1rem", "type": "dimension" } |
| 286 | + }, |
| 287 | + "color": { |
| 288 | + "default": { "value": "{color.gray.300}", "type": "color" }, |
| 289 | + "active": { "value": "{color.primary.500}", "type": "color" } |
| 290 | + }, |
| 291 | + "border": { |
| 292 | + "radius": { "value": "50%", "type": "borderRadius" } |
| 293 | + } |
| 294 | + } |
| 295 | + }, |
| 296 | + "caption": { |
| 297 | + "padding": { "value": "1rem", "type": "dimension" }, |
| 298 | + "fontSize": { "value": "1rem", "type": "dimension" }, |
| 299 | + "color": { "value": "{color.gray.700}", "type": "color" }, |
| 300 | + "background": { "value": "{color.white}", "type": "color" } |
| 301 | + }, |
| 302 | + "transition": { |
| 303 | + "duration": { "value": "600ms", "type": "duration" }, |
| 304 | + "timing": { |
| 305 | + "function": { "value": "ease-in-out", "type": "cubicBezier" } |
| 306 | + } |
| 307 | + } |
| 308 | + } |
| 309 | +} |
| 310 | +``` |
| 311 | + |
| 312 | +## Resources |
| 313 | + |
| 314 | +### Articles |
| 315 | + |
| 316 | +- [Carousel/Slider Design Best Practices](https://xd.adobe.com/ideas/process/ui-design/best-practices-for-carousels-sliders/) by Adobe |
| 317 | +- [Designing a User-Friendly Homepage Carousel](https://www.nngroup.com/articles/designing-homepage-carousel/) by Nielsen Norman Group |
| 318 | +- [How to Create a Responsive Carousel Component](https://css-tricks.com/how-to-create-a-responsive-carousel-component/) by CSS-Tricks |
0 commit comments