` preferred, `` or `` acceptable)**
* Displays a **clear, specific message** when input is invalid.
* **Use `` for dynamic validation feedback** - semantically represents the result of user input.
* Use `` for static helper text that doesn't change.
* Should be **associated with the input using `aria-describedby`**.
* Appears below the input, replacing helper text if necessary.
7. **Character Counter (`p` or `span`, optional)**
* Displays **remaining or used character count** (e.g., "20/100 characters").
* Helps users stay within input length limits.
* Should update dynamically as the user types.
8. **Prefix (`span`, optional)**
* Static text **before the input** (e.g., `$` for currency, `@` for usernames).
* Should be **visually distinguishable** from user input.
9. **Suffix (`span`, optional)**
* Static text **after the input** (e.g., `.com` for domain fields).
* Helps users understand **expected input formats**.
#### Summary of Components
| Component | Required? | Purpose |
| ------------------------ | --------- | -------------------------------------------- |
| Label | ✅ Yes | Describes the input field's purpose. |
| Input Field | ✅ Yes | The main interactive element for user input. |
| Placeholder | ❌ No | Provides a hint but disappears on input. |
| Helper Text | ❌ No | Offers guidance or additional instructions. |
| Validation/Error Message | ❌ No | Provides feedback when input is invalid. |
| Character Counter | ❌ No | Tracks remaining/used characters. |
| Prefix | ❌ No | Displays static text before the input. |
| Suffix | ❌ No | Displays static text after the input. |
## Variations
### Basic Text Field
Simple single-line input with label and optional helper text.
```html
Email Address
```
### With Validation States
Text field showing different validation states (error, success, warning).
```html
Password
Password must be at least 8 characters
Username
Username is available
```
### With Character Counter
Text field that shows remaining character count.
```html
```
### With Prefix/Suffix
Text field with icons or text before or after the input.
```html
```
### With Helper Text
Text field with additional guidance below the input.
```html
```
### Search Text Field
Optimized for search with specific styling and behavior.
```html
```
## Examples
### Interactive Demo
### With Validation States
### With Helper Text
### With Character Counter
### With Icons
### Different Input Types
### Required Field Indicators
### Basic Implementation
```html
Username
Please enter a username
```
## Best Practices
### Content & Usability
**Do's ✅**
* Provide a **clear and descriptive label**.
* Use **placeholder text sparingly** and never as a replacement for a label.
* Indicate **required fields** clearly and provide helpful validation feedback.
* Use **real-time validation** to prevent errors early.
* Ensure sufficient **touch target size** for mobile users.
* Allow users to **copy, paste, and autocomplete** when appropriate.
* **Use input masks sparingly**—they can improve formatting but may frustrate users if too rigid.
* Offer **formatting hints** when users must follow a specific pattern (e.g., phone numbers, dates).
* Provide **default values** when applicable to reduce typing effort.
**Don'ts ❌**
* Don't use placeholder text instead of a visible label.
* Avoid long character limits without a counter.
* Don't require unnecessary or sensitive information without justification.
* Don't enforce **case sensitivity** unless absolutely necessary.
* Avoid disabling **copy-paste** for passwords or sensitive fields, as this can harm usability.
***
### Required Field Implementation Guidelines
#### 1️⃣ Best Practice: Explicit "Required" Label
✅ **Most accessible** – clear for all users, including screen readers.
```html
Username (Required)
```
**Pros ✅**
* Works for **all users**, including screen readers and color-blind users.
* No need for extra ARIA attributes.
**Cons ❌**
* Takes slightly more space in the UI.
#### 2️⃣ Alternative: Asterisk (\*) with ARIA Explanation
✅ **Common practice**, but needs `aria-describedby` for screen reader users.
```html
Username *
Fields marked with an asterisk are required.
```
**Pros ✅**
* Keeps UI cleaner while maintaining accessibility.
* Screen readers will announce **"Fields marked with an asterisk are required."**
**Cons ❌**
* **Requires additional explanation** (`aria-describedby`).
* **Without the extra message, asterisks alone are not accessible**.
#### 3️⃣ Alternative: Required Field with Visually Hidden Text
✅ **Keeps UI minimal while ensuring accessibility.**
```html
Email (Required)
```
**Pros ✅**
* **Looks clean visually** while still accessible.
* **Screen readers announce it as "Email Required"**.
**Cons ❌**
* **Not visible for sighted users** who rely on visual cues.
#### 4️⃣ Alternative: Required Field with an Inline Icon + Tooltip
✅ **More user-friendly**, provides additional guidance.
```html
Phone Number
*
Fields marked with an asterisk are required.
```
**Pros ✅**
* **Visually clear** while keeping text minimal.
* Works well when paired with a **tooltip on hover or focus**.
**Cons ❌**
* **Requires CSS for styling** (ensuring asterisks are not the only indicator).
* Users **might not see tooltip hints** if they don't hover over the icon.
#### 5️⃣ Alternative: Required Field with `required` Attribute Only
⚠ **Not recommended as a standalone solution!**
```html
Password
```
**Pros ✅**
* Works well for **basic validation**.
* Screen readers **will announce the field as required**.
**Cons ❌**
* No **visible indicator for sighted users** before form submission.
* **Errors only appear after submission**, which may confuse users.
* Some browsers may **not enforce required fields consistently**.
***
### Accessibility
**Do's ✅**
* Associate the text field with a `` element for screen readers.
* Use `aria-describedby` to connect inputs to error messages or hints.
* Ensure **high contrast** between text and background.
* Provide **keyboard navigation** and support tabbing.
* Allow **speech-to-text functionality** for accessibility.
* Use `aria-invalid="true"` when a validation error occurs.
* Ensure **error messages appear next to the field** and are **read aloud by screen readers**.
**Don'ts ❌**
* Don't remove focus outlines—they are essential for keyboard users.
* Don't rely solely on color to indicate errors.
* Avoid using `title` attributes for tooltips—use visible descriptions.
* Don't use `placeholder` as the only accessible text—it disappears when users start typing.
* Avoid **dynamic placeholder text changes** that may confuse assistive technologies.
***
### Visual Design
**Do's ✅**
* Use **sufficient padding and line height** for readability.
* Maintain a **clear distinction between active, focused, and disabled states**.
* Use **icons (optional)** for additional context (e.g., search icon in a search field).
* Ensure **error states are visually prominent** without being intrusive.
* **Use color contrast** that meets WCAG 2.2 AA standards (e.g., 4.5:1 ratio for text).
**Don'ts ❌**
* Avoid excessive borders or decorative elements.
* Don't make the input field too small, especially on mobile.
* Avoid low contrast text and background combinations.
* Don't rely solely on placeholder text for field instructions.
***
### Layout & Positioning
**Do's ✅**
* Align labels **above or beside** the text field for clarity.
* Keep **consistent spacing and alignment** with other form elements.
* Ensure sufficient **spacing between multiple input fields** for easy readability.
* Place **validation messages near the input field** to improve error recognition.
**Don'ts ❌**
* Don't position labels too far from the input.
* Avoid overly narrow text fields that cut off content.
* Don't place validation messages too far from the field.
* Avoid placing multiple fields **on the same line on mobile**, as this reduces readability.
### Input Description Placement: Above or Below the Text Field?
#### Best Practice: Place Input Descriptions Below the Field
In most cases, **input descriptions (helper text, formatting hints, and additional guidance) should be placed below the text field** for **consistency, readability, and accessibility**.
**✅ Why?**
* **Users scan from top to bottom** – The label is read first, then the input, then any additional help.
* **Aligns with error messages** – Since validation errors appear below the field, keeping all feedback in one place reduces cognitive load.
* **Screen reader order** – Screen readers will naturally announce the description **right after the field** when placed below.
* **Follows industry standards** – Major design systems (Google Material, IBM Carbon, Bootstrap) place helper text below.
***
#### 📍 When to Place Descriptions Above the Field?
⚠ **There are some exceptions where placing descriptions above is preferable:**
1. **When users must understand something before typing**
* Example: *"Enter your National Insurance number in the format QQ123456C"*
2. **Password requirements**
* Example: *"Password must be at least 8 characters and contain a number."*
3. **When there is no error message below the field**
* Helps avoid excessive space between the input and the next element.
***
#### Best Practice: Only Show One at a Time
To avoid overwhelming users:
* **Before an error occurs**, display helper text **below** the input.
* **When an error occurs**, **replace** the helper text with the error message.
✅ **Example (Best Practice)**
```html
Email
We'll never share your email with anyone.
Please enter a valid email.
```
### Final Recommendation for Input Description Placement
| **Scenario** | **Where to Place Helper Text?** | **Why?** |
| -------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------- |
| **Standard input fields (e.g., email, name, search)** | **Below** | Ensures consistency with error messages & better readability. |
| **Inputs with specific formatting (e.g., date, phone number)** | **Above** | Users need to understand format before typing. |
| **Password fields (with complexity rules)** | **Above** | Users need guidance before they type. |
| **Large forms with minimal UI** | **Above** or **Inline** | To prevent visual clutter. |
| **Error messages** | **Below** | Always below, ensuring users immediately see what went wrong. |
## Common Mistakes & Anti-Patterns 🚫
### Using Placeholder as Primary Label
**The Problem:**
Relying on placeholder text as the only label makes the field inaccessible when users start typing, and screen readers may not announce it properly.
```html
```
**How to Fix It?** Always provide a visible label and use placeholder for hints or examples only.
```html
First Name
```
***
### Poor Validation Timing
**The Problem:**
Showing error messages too early (on first keystroke) or too late (only on form submission) frustrates users.
**How to Fix It?** Use **progressive validation**:
* Show errors after field loses focus (onBlur) for first-time entry
* Show real-time validation for corrections after initial error
* Validate required fields on blur, format validation on input
```javascript
// Good: Progressive validation
function validateField(input, hasBeenBlurred) {
if (hasBeenBlurred && input.value.length > 0) {
// Show real-time validation after first blur
showValidationFeedback(input);
}
}
```
***
### Missing Error Recovery
**The Problem:**
Not providing clear guidance on how to fix validation errors leaves users stuck.
**How to Fix It?** Include specific, actionable error messages with examples.
```html
Invalid input
Password must contain at least 8 characters, including 1 number and 1 special character.
Example: MyPass123!
```
***
### Inaccessible Focus Management
**The Problem:**
Poor focus indicators or focus traps make keyboard navigation impossible.
**How to Fix It?** Ensure visible focus states and logical tab order.
```css
/* Good: Visible focus indicator */
.text-field input:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
```
## Accessibility
### Keyboard Interaction Pattern
Text fields should support **standard keyboard navigation and interactions** to ensure accessibility and usability.
| **Key** | **Action** |
| ------------------------- | ----------------------------------------------------------------- |
| `Tab` | Moves focus to the next interactive element. |
| `Shift + Tab` | Moves focus to the previous interactive element. |
| `Enter` *(inside a form)* | Submits the form (unless prevented). |
| `Arrow Left / Right` | Moves the text cursor within the input. |
| `Arrow Up / Down` | Moves the cursor within multi-line text fields (`textarea`). |
| `Esc` | If inside a **search field**, clears input *(optional behavior).* |
## Micro-Interactions & Animations
For text field components, implement these specific animations to enhance user experience while maintaining performance:
### Focus Animation
* **Effect:** Smooth border color transition and subtle scale when field receives focus
* **Timing:** 200ms ease-out transition for professional feel
* **Implementation:** CSS transition on border-color and box-shadow properties
```css
.text-field input {
border: 1px solid #d1d5db;
transition: border-color 200ms ease-out, box-shadow 200ms ease-out;
}
.text-field input:focus {
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
```
### Validation State Animation
* **Effect:** Smooth color transition when switching between validation states
* **Timing:** 300ms ease-in-out to allow users to notice state changes
* **Implementation:** Animate border color, text color, and icon appearance
### Character Counter Animation
* **Effect:** Number increments smoothly and color changes as limit approaches
* **Timing:** 150ms for number updates, 200ms for color transitions
* **Implementation:** Animate color when reaching 80% (warning) and 95% (danger) of limit
### Label Float Animation
* **Effect:** Label moves from placeholder position to above field when focused
* **Timing:** 200ms ease-out for smooth, natural movement
* **Implementation:** Transform translateY and scale properties
## Tracking
Text field interactions provide valuable insights into user behavior, form completion rates, and usability issues. Track these key metrics to optimize the input experience.
### Key Tracking Points
| **Event Name** | **Description** | **Why Track It?** |
| ------------------------------ | --------------------------------- | ---------------------------------------------------- |
| `textfield.focus` | When user focuses on a text field | Measures field engagement and interaction patterns |
| `textfield.input` | When user types in the field | Tracks active usage and input behavior |
| `textfield.blur` | When user leaves the field | Identifies completion patterns and field abandonment |
| `textfield.clear` | When user clears field content | Shows user correction behavior and field complexity |
| `textfield.validation_error` | When validation fails | Identifies problematic fields and error patterns |
| `textfield.validation_success` | When validation passes | Measures successful field completion |
| `textfield.paste` | When user pastes content | Shows copy-paste usage patterns |
| `textfield.autocomplete_used` | When browser autocomplete is used | Indicates field recognition and user convenience |
### Event Payload Structure
```json
{
"event": "textfield.validation_error",
"properties": {
"field_name": "email",
"field_type": "email",
"error_type": "invalid_format",
"input_length": 12,
"time_spent": 4.2,
"attempt_number": 2,
"form_id": "registration"
}
}
```
### Key Metrics to Analyze
* **Field Completion Rate** → Percentage of users who successfully complete each field
* **Error Rate** → Frequency of validation errors per field type
* **Time to Complete** → Average time users spend on each field
* **Abandonment Points** → Where users stop filling forms
* **Correction Patterns** → How often users backspace or clear fields
* **Paste Usage** → Fields where users commonly paste content
## Localization
Text fields require comprehensive localization support for international users, including text direction, input methods, and cultural formatting differences.
```json
{
"text_field": {
"validation": {
"required": "This field is required",
"invalid_email": "Please enter a valid email address",
"invalid_format": "Please check the format",
"too_short": "Must be at least {min} characters",
"too_long": "Must be no more than {max} characters",
"contains_invalid_chars": "Contains invalid characters"
},
"actions": {
"clear": "Clear field",
"show_password": "Show password",
"hide_password": "Hide password",
"copy": "Copy to clipboard",
"paste": "Paste from clipboard"
},
"counter": {
"characters_remaining": "{count} characters remaining",
"character_limit_reached": "Character limit reached",
"over_limit": "{count} characters over limit"
},
"states": {
"loading": "Loading...",
"success": "Valid",
"processing": "Processing...",
"saved": "Saved"
},
"placeholders": {
"search": "Search...",
"email": "Enter your email",
"password": "Enter your password",
"optional": "Optional"
}
}
}
```
### RTL Language Support
For right-to-left languages (Arabic, Hebrew), adjust text alignment and icon positions:
```css
[dir="rtl"] .text-field input {
text-align: right;
}
[dir="rtl"] .text-field__prefix {
order: 2;
}
[dir="rtl"] .text-field__suffix {
order: 0;
}
```
### Input Method Support
Consider different input methods for international users:
* **IME Support:** Handle composition events for Chinese, Japanese, Korean input
* **Virtual Keyboards:** Optimize for mobile virtual keyboards with appropriate `inputmode` attributes
* **Cultural Formats:** Support local name orders, address formats, and phone number patterns
## Performance Metrics
Target performance metrics for text field components:
* **Initial render**: \< 100ms for text field appearance
* **Focus response**: \< 50ms from click to focus state
* **Validation feedback**: \< 150ms after input validation
* **Character counter updates**: \< 50ms for smooth counting
* **Memory usage**: \< 5KB per text field instance
## Testing Guidelines
### Functional Testing
**Should ✓**
* [ ] Verify that users can input, edit, and delete text without issues.
* [ ] Ensure character limits work correctly and display remaining characters if applicable.
* [ ] Validate correct error handling and messaging (e.g., required fields, invalid formats).
* [ ] Confirm keyboard navigation and focus behavior, including tab order.
* [ ] Ensure users can **copy, paste, and autofill** without restrictions.
* [ ] Test **input masks and auto-formatting** to confirm they work as expected.
* [ ] Validate that pressing **Enter/Return** behaves as expected (e.g., form submission or moving to the next field).
***
### Accessibility Testing
**Should ✓**
* [ ] Ensure text fields have associated **labels (``)** for screen readers.
* [ ] Validate that error messages are announced by **screen readers (NVDA, JAWS, VoiceOver, TalkBack)**.
* [ ] Confirm that **keyboard users can navigate and interact** effectively using `Tab`, `Shift+Tab`, `Enter`, and `Esc`.
* [ ] Ensure **high contrast between text and background** (meets WCAG 2.2 AA contrast ratio).
* [ ] Check that **focus indicators are visible** when navigating via keyboard.
* [ ] Test with **different screen readers** to confirm field descriptions and validation messages are correctly read.
* [ ] Verify that **speech-to-text functionality works** for users relying on voice input.
* [ ] Ensure **placeholder text is not the only accessible label**, as it disappears when typing.
* [ ] Check for `aria-describedby` and `aria-invalid="true"` usage in error handling scenarios.
***
### Performance Testing
**Should ✓**
* [ ] Ensure text input does not **cause delays, freezing, or slow response times**.
* [ ] Validate large text input handling (e.g., pasting 1000+ characters into a field).
* [ ] Check **browser compatibility across different devices** (Chrome, Firefox, Safari, Edge, mobile browsers).
* [ ] Test mobile usability, including **touch input, autocorrect behavior, and focus handling**.
* [ ] Ensure input fields **don't trigger layout shifts** (Cumulative Layout Shift - CLS).
* [ ] Validate **lazy loading and deferred scripts** do not delay field interactions.
* [ ] Check memory usage when dynamically adding or removing fields.
***
### Security Testing
**Should ✓**
* [ ] Ensure fields do not store sensitive data in autocomplete history unless necessary (`autocomplete="off"` for sensitive inputs).
* [ ] Validate against **Cross-Site Scripting (XSS) attacks**—inputs should sanitize user-entered data.
* [ ] Verify that error messages do not reveal sensitive details (e.g., don't display "Incorrect email or password" separately).
* [ ] Check that invalid inputs do not break the layout or cause unexpected behavior.
***
### Mobile & Touch Testing
**Should ✓**
* [ ] Ensure the **correct keyboard type appears** for each input (e.g., numeric for phone numbers, email keyboard for email fields).
* [ ] Validate touch targets are **large enough (at least 44x44px)** for usability.
* [ ] Test how input behaves in **dark mode** and ensure readability.
* [ ] Check if input fields adjust correctly when the **virtual keyboard opens** (avoiding overlapping content).
* [ ] Ensure users can **easily dismiss the keyboard** after typing (e.g., tapping outside the input).
* [ ] Verify that **autocorrect and autocomplete work properly** without interfering with expected input behavior.
* [ ] Confirm that **multi-line inputs (`textarea`) scroll correctly** without hiding text on smaller screens.
***
### Error Handling & Validation Testing
**Should ✓**
* [ ] Ensure validation errors appear **next to the relevant input field** (not in a separate section).
* [ ] Validate that **real-time validation** does not trigger prematurely while typing.
* [ ] Confirm that error messages **persist until fixed**, rather than disappearing too quickly.
* [ ] Ensure errors provide **clear guidance** (e.g., "Enter a valid email" instead of "Invalid input").
* [ ] Check if `aria-live="polite"` announces validation messages dynamically.
* [ ] Test behavior when **submitting an empty required field**—does it highlight correctly?
* [ ] Verify that server-side validation handles **unexpected input** gracefully (e.g., very long strings, special characters).
* [ ] Ensure users can **recover from errors easily** without refreshing the page.
***
### Edge Case Testing\*\*
**Should ✓**
* [ ] Simulate **slow network conditions** to check if validation messages delay input behavior.
* [ ] Test behavior when **copying and pasting large amounts of text** into a field.
* [ ] Ensure **input remains intact** when navigating away and returning to the form.
* [ ] Check how the field handles **emoji, special characters, and non-Latin alphabets**.
* [ ] Test what happens if a **user pastes an entire paragraph into a single-line text field**.
* [ ] Verify that auto-suggestions do not interfere with manual input.
* [ ] Test behavior when **users press the "back" button on mobile browsers**—does the input persist?
* [ ] Ensure users **can undo accidental deletions** (via `Ctrl+Z` or long press on mobile).
## Frequently Asked Questions
## Related Patterns
## Resources
### Libraries
* [Input - Origin UI](https://originui.com/input) - Modern input component collection
* [React Hook Form](https://react-hook-form.com/) - Performant, flexible forms with validation
* [Formik](https://formik.org/) - Forms without tears
* [React Final Form](https://final-form.org/react) - High performance forms
* [Mantine TextInput](https://mantine.dev/core/text-input/) - Full-featured text input component
* [Chakra UI Input](https://chakra-ui.com/docs/components/input) - Simple and modular input component
### Design Systems
* [Material Design Text Fields](https://material.io/components/text-fields) - Google's text field guidelines
* [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/text-fields) - Apple's text field standards
* [Ant Design Input](https://ant.design/components/input) - Enterprise-grade input design
* [Carbon Design System](https://carbondesignsystem.com/components/text-input/usage) - IBM's input component guidelines
### Articles & Guides
* [Form Design Best Practices](https://uxplanet.org/designing-perfect-text-field-clarity-accessibility-and-user-experience-6e7dd80e68c8) - Comprehensive form design guide
* [Accessible Form Design](https://webaim.org/techniques/forms/) - WebAIM's form accessibility techniques
* [Mobile Input Best Practices](https://developers.google.com/web/fundamentals/design-and-ux/input/forms) - Google's mobile form guidelines
* [Input Validation Patterns](https://www.smashingmagazine.com/2009/07/web-form-validation-best-practices-and-tutorials/) - Validation best practices guide
### Tools & Utilities
* [HTML5 Input Types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types) - Complete reference for input types
* [Accessibility Checker](https://wave.webaim.org/) - Check form accessibility
* [Color Contrast Analyzer](https://www.tpgi.com/color-contrast-checker/) - Ensure sufficient contrast
* [Screen Reader Testing](https://webaim.org/articles/screenreader_testing/) - Test with assistive technologies
# UX Patterns for Devs: Textarea
URL: /patterns/forms/textarea
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/forms/textarea.mdx
Learn how to implement accessible textarea components for collecting long-form content, comments, and detailed responses. Discover best practices for multi-line text input with proper validation and user experience.
***
title: "Textarea"
summary: "Multi-line text input for longer content"
description: "Learn how to implement accessible textarea components for collecting long-form content, comments, and detailed responses. Discover best practices for multi-line text input with proper validation and user experience."
icon: TextSelect
----------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Time Input
URL: /patterns/forms/time-input
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/forms/time-input.mdx
Build user-friendly time input fields with validation and accessibility features.
***
title: "Time Input"
summary: "Enter time in a structured format"
description: "Build user-friendly time input fields with validation and accessibility features."
icon: Clock
-----------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Toggle
URL: /patterns/forms/toggle
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/forms/toggle.mdx
Implement toggle switches for binary state control in your web applications. Learn best practices for toggle buttons, state management, and accessibility.
***
title: "Toggle"
summary: "Switch between two states"
description: "Implement toggle switches for binary state control in your web applications. Learn best practices for toggle buttons, state management, and accessibility."
icon: ToggleLeft
----------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Image Gallery
URL: /patterns/media/image-gallery
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/media/image-gallery.mdx
Learn how to implement image galleries. Discover best practices for lightboxes, thumbnails, and image navigation.
***
title: "Image Gallery"
summary: "Display and browse image collections"
description: "Learn how to implement image galleries. Discover best practices for lightboxes, thumbnails, and image navigation."
icon: Images
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Slideshow display: [Carousel](/patterns/content-management/carousel)
* Image uploads: [Image Upload](/patterns/media/image-upload)
* Fullscreen viewing: [Modal](/patterns/content-management/modal)
# UX Patterns for Devs: Image Upload
URL: /patterns/media/image-upload
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/media/image-upload.mdx
Learn how to implement image upload interfaces. Discover best practices for drag-and-drop, preview, and validation.
***
title: "Image Upload"
summary: "Upload and preview images"
description: "Learn how to implement image upload interfaces. Discover best practices for drag-and-drop, preview, and validation."
icon: Upload
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* File uploads: [File Input](/patterns/forms/file-input)
* Drag interactions: [Drag and Drop](/patterns/content-management/drag-and-drop)
* Image display: [Image Gallery](/patterns/media/image-gallery)
# UX Patterns for Devs: Video Player
URL: /patterns/media/video-player
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/media/video-player.mdx
Learn how to implement video players. Discover best practices for playback controls, captions, and responsive video.
***
title: "Video Player"
summary: "Video playback with controls"
description: "Learn how to implement video players. Discover best practices for playback controls, captions, and responsive video."
icon: Video
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Audio playback: [Video Player](/patterns/media/video-player) (similar controls)
* Media galleries: [Image Gallery](/patterns/media/image-gallery)
* Fullscreen mode: [Modal](/patterns/content-management/modal)
# UX Patterns for Devs: Back to Top
URL: /patterns/navigation/back-to-top
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/back-to-top.mdx
Implement a Back to Top button for enhanced navigation on long pages with best practices for placement and accessibility.
***
title: "Back to Top"
summary: "Quickly navigate back to the top of the page"
description: "Implement a Back to Top button for enhanced navigation on long pages with best practices for placement and accessibility."
icon: ArrowUp
status: complete
----------------
import { Playground } from "@/components/playground";
## Overview
**Back to Top** gives users a quick way back to the page top after scrolling through lengthy or [infinite content](/patterns/navigation/infinite-scroll).
This floating button or link typically sits at the bottom-right corner, improving navigation and user experience.
## Use Cases
### When to use:
Use **Back to Top** to **help users quickly return to long page tops without excessive scrolling**.
**Common scenarios include:**
* Long or content-heavy pages where users scroll far down
* Quick navigation back to headers or navigation menus is essential
* Blogs, documentation pages, or e-commerce category listings need extensive scrolling
### When not to use:
* Very short pages with minimal or unnecessary scrolling
* Your layout already has persistent bottom navigation or sticky top menus
* Pages without infinite scrolling where scrolling isn't an issue
### Common scenarios and examples
* Long editorial content (articles, guides, and blog posts)
* Content hubs or portals with extensive listings
* FAQ pages with collapsible or expanded sections
* Dashboards or analytics pages containing large data tables
* Infinite scrolling experiences (e.g., social feeds) to let users quickly jump to the top
## Benefits
* Better navigation and usability on long pages
* Improved site accessibility with direct routes to main navigation
* Less scrolling fatigue for mobile users
* Clean UI that hides controls until needed, showing them after scrolling
## Drawbacks
* **Not always necessary** – Short pages make the button redundant
* **Can be disruptive** – Sudden jumps to top disorient users
* **Visibility control** – Needs logic to appear after certain scroll depth
* **Hidden functionality risk** – Users might not notice or understand it
* **Placement conflicts** – Interferes with other floating UI elements without careful positioning
## Anatomy
```mermaid
flowchart TB
subgraph BackToTop["Back to Top" Component]
Container[Container Element] -->|contains| Icon[Icon ]
Container --> Label[Label Text ]
end
```
### Component Structure
1. **Container**
* Clickable element (usually button) triggering scroll to top
* Positioned as floating element on desktop and mobile
* Handles focus states and accessibility attributes
2. **Icon (Optional)**
* Shows the go-to-top action (up arrow)
* Clear and universally recognized
* Sized for readability (16×16px or 24×24px common)
* Contrasts with background
3. **Label Text (Optional)**
* Clarifies action for screen readers or when icon alone doesn't work
* Hidden for visual users but available to assistive technology
* Visible when design needs extra clarity
4. **Visual States**
* **Default**: Visible when the user scrolls past a certain threshold
* **Hover**: Provides a visual cue (e.g. change in background color)
* **Active**: Pressed or clicked state
* **Focus**: Outline or highlight for keyboard navigation
* **Hidden**: Button is invisible or removed when the user is near the top of the page
#### Summary of Components
| Component | Required? | Purpose |
| ------------- | --------- | ----------------------------------------------------------- |
| Container | ✅ Yes | Clickable element that triggers scrolling to the top. |
| Icon | ❌ No | Visual indicator (e.g., an up arrow) for quick recognition. |
| Label Text | ❌ No | Provides additional clarity, especially for screen readers. |
| Visual States | ✅ Yes | Defines interaction states (hover, active, focus, hidden). |
## Variations
### 1. Fixed Position Button
The most common implementation - a button that remains in a fixed position (typically bottom-right) as the user scrolls.
**When to use:** Standard long-form content pages, articles, documentation
### 2. Sticky Footer Integration
Integrated into a sticky footer bar that may also contain other navigation elements.
**When to use:** When you have a persistent footer with multiple actions
### 3. Progress Indicator Combo
Combined with a scroll progress indicator that shows how far down the page the user has scrolled.
**When to use:** Long articles or tutorials where progress tracking is valuable
### 4. Expandable FAB (Floating Action Button)
A floating action button that expands to reveal multiple navigation options including "Back to Top".
**When to use:** Mobile apps or sites with multiple quick actions
### 5. Sidebar Integration
Embedded within a sticky sidebar navigation alongside other page navigation elements.
**When to use:** Documentation sites or content with extensive navigation needs
### 6. Contextual Appearance
Appears only within specific long sections rather than globally on the page.
**When to use:** Pages with distinct long sections that benefit from section-specific navigation
## Examples
### Interactive Back to Top Demo
This example showcases:
* Smooth scroll animation to top
* Button appears after scrolling 300px
* Fade-in/out transitions for button visibility
* Progress bar showing scroll position
* Throttled scroll events for performance
* Keyboard support (Tab to focus, Enter/Space to activate)
* Respects `prefers-reduced-motion` for accessibility
* Mobile-optimized touch targets
### Basic Implementation (HTML + minimal JS)
```html
↑
```
### React Implementation with Hooks
```jsx
import { useState, useEffect } from 'react';
function BackToTop() {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const toggleVisibility = () => {
setIsVisible(window.scrollY > 300);
};
window.addEventListener('scroll', toggleVisibility);
return () => window.removeEventListener('scroll', toggleVisibility);
}, []);
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
return isVisible ? (
↑
) : null;
}
```
### CSS Styling
```css
.back-to-top {
position: fixed;
bottom: 2rem;
right: 2rem;
width: 3rem;
height: 3rem;
border-radius: 50%;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
opacity: 0.9;
transition: opacity 0.3s, transform 0.3s;
z-index: 1000;
}
.back-to-top:hover {
opacity: 1;
transform: translateY(-4px);
}
.back-to-top:focus {
outline: 2px solid #0056b3;
outline-offset: 2px;
}
/* Reduce motion for accessibility */
@media (prefers-reduced-motion: reduce) {
.back-to-top {
transition: none;
}
* {
scroll-behavior: auto !important;
}
}
/* Mobile optimization */
@media (max-width: 768px) {
.back-to-top {
bottom: 1rem;
right: 1rem;
}
}
```
## Best Practices
### Content
**Do's ✅**
* Show a clear visual indicator (usually an up arrow icon)
* Display the button only after the user scrolls a predetermined distance
* Hide it when the user is near the top of the page
* Use an accessible label (e.g., `aria-label="Back to top"`) if the text is omitted
**Don'ts ❌**
* Don't make it permanently visible for short pages—it can be distracting
* Don't use vague icons or labels (e.g., a random symbol without context)
* Don't crowd the button with other floating elements
* Don't rely solely on color for states—use shape or text changes if possible
### Accessibility
**Do's ✅**
* Ensure the button is keyboard-focusable and can be activated via Enter or Space
* Provide sufficient color contrast between the button and its background
* Use an appropriate aria-label or descriptive text for screen readers
* Manage focus: after scrolling up, keep the user informed or maintain logical focus
**Don'ts ❌**
* Don't hide it behind complex interactions or animations
* Don't place it in a position that overlaps other important UI elements
* Don't disable focus outlines without providing an alternative focus style
### Visual Design
**Do's ✅**
* Use a large enough icon or label for quick recognition (minimum 16×16px icon)
* Maintain consistent styling with the rest of your UI (color, shape, corners)
* Incorporate hover/focus states that match your design system guidelines
* Place it in a fixed position (often bottom-right) for easy access
**Don'ts ❌**
* Don't block important content with a floating button
* Don't make the button so small that it's hard to tap on mobile
* Don't use misleading icons (ensure the arrow is pointing up)
### Mobile & Touch Considerations
**Do's ✅**
* Use a minimum touch target of 44×44px
* Keep it within thumb-friendly zones at the bottom of the screen
* Make sure it doesn't overlap interactive elements (navigation drawers, chat bubbles)
* Add any necessary spacing from device edges to avoid accidental swipes
**Don'ts ❌**
* Don't place it in corners difficult to reach on large screens
* Don't rely on hover states for mobile users—visual changes should appear on tap/press
* Don't crowd the bottom area with too many floating icons
### Layout & Positioning
**Do's ✅**
* Fix its position to the viewport so it remains visible during scrolling
* Use consistent margin or spacing from edges for aesthetic alignment
* Keep in mind other fixed UI elements such as sticky footers or chat widgets
**Don'ts ❌**
* Don't move it around the page as the user scrolls
* Don't tie it to an element that scrolls out of view
## Common Mistakes & Anti-Patterns 🚫
### Always Visible on Short Pages
**The Problem:**
Showing the Back to Top button on pages that don't require scrolling or have minimal content creates unnecessary UI clutter.
**How to Fix It:**
Only display the button after the user has scrolled at least 2x the viewport height or a minimum of 1000px.
### Jarring Jump Without Animation
**The Problem:**
Instantly jumping to the top without smooth scrolling can disorient users and make them lose context.
**How to Fix It:**
Implement smooth scrolling with `scroll-behavior: smooth` or JavaScript animation with appropriate duration (300-500ms).
### Poor Button Visibility
**The Problem:**
Using low contrast colors or making the button too small/transparent makes it hard to notice or click.
**How to Fix It:**
Ensure sufficient color contrast (WCAG AA minimum) and use a minimum touch target of 44x44px.
### Blocking Important Content
**The Problem:**
Placing the button where it covers important interactive elements like chat widgets or cookie banners.
**How to Fix It:**
Carefully position the button to avoid overlapping with other floating elements, adjusting position dynamically if needed.
### Missing Keyboard Support
**The Problem:**
Button only works with mouse/touch, excluding keyboard users from using the feature.
**How to Fix It:**
Ensure the button is keyboard accessible, focusable with Tab, and activatable with Enter/Space keys.
### No Visual Feedback on Interaction
**The Problem:**
Button doesn't provide hover, focus, or active states, leaving users uncertain if their interaction registered.
**How to Fix It:**
Implement clear visual states for all interactions including hover, focus, active, and disabled states.
## Micro-Interactions & Animations
### Button Appearance Animation
* **Effect:** Fade in with slight scale up
* **Timing:** 200ms ease-out
* **Trigger:** When scroll threshold is passed
* **Implementation:** CSS transition on opacity and transform
### Hover State Transition
* **Effect:** Background color change with subtle shadow elevation
* **Timing:** 150ms ease-in-out
* **Trigger:** Mouse hover or focus
* **Implementation:** CSS :hover and :focus states
### Click Feedback
* **Effect:** Scale down slightly then back to normal
* **Timing:** 100ms down, 150ms up
* **Trigger:** Click or tap
* **Implementation:** CSS :active state with transform: scale(0.95)
### Scroll Animation
* **Effect:** Smooth easing scroll to top
* **Timing:** 300-500ms depending on scroll distance
* **Trigger:** Button activation
* **Implementation:** JavaScript with easing function or CSS scroll-behavior
### Progress Indicator (Optional)
* **Effect:** Circular progress fills as user scrolls down
* **Timing:** Real-time tracking
* **Trigger:** Scroll events (throttled)
* **Implementation:** SVG stroke-dasharray animation
### Hide Animation
* **Effect:** Fade out with slight scale down
* **Timing:** 200ms ease-in
* **Trigger:** When user scrolls back near top
* **Implementation:** CSS transition with visibility toggle
## Tracking
### Key Events to Track
| **Event Name** | **Description** | **Why Track It?** |
| -------------------------------- | --------------------------------------------- | ----------------------------------------------- |
| `back_to_top.shown` | Button becomes visible after scroll threshold | Understand if users scroll far enough to see it |
| `back_to_top.clicked` | User clicks/taps the button | Measure actual usage and engagement |
| `back_to_top.keyboard_activated` | Button activated via keyboard | Track accessibility feature usage |
| `back_to_top.scroll_depth` | Maximum scroll depth before using button | Understand when users decide to return |
| `back_to_top.time_to_use` | Time between button appearance and click | Measure decision making time |
### Event Payload Structure
```json
{
"event": "back_to_top.clicked",
"properties": {
"page_height": 5000,
"scroll_depth": 3500,
"time_on_page": 45,
"device_type": "mobile",
"button_position": "bottom-right"
}
}
```
### Key Metrics to Analyze
* **Usage Rate:** Percentage of users who see and use the button
* **Scroll Depth at Use:** Average scroll position when button is clicked
* **Time to Engagement:** How long users take to click after button appears
* **Device Breakdown:** Usage patterns across desktop vs mobile
* **Page Type Performance:** Which content types benefit most from the feature
## Localization
```json
{
"back_to_top": {
"button": {
"label": "Back to top",
"aria_label": "Scroll back to top of page",
"tooltip": "Return to top"
},
"announcements": {
"scrolling": "Scrolling to top of page",
"completed": "Reached top of page"
},
"progress": {
"indicator_label": "Scroll progress: {percentage}%"
}
}
}
```
### RTL (Right-to-Left) Considerations
* Position button on bottom-left for RTL languages
* Mirror any directional icons appropriately
* Adjust animation directions for RTL context
### Cultural Considerations
* **Icon choice:** Up arrow is universally understood
* **Position:** Bottom-right is standard in LTR, bottom-left in RTL
* **Color significance:** Avoid colors with negative cultural connotations
## Performance
### Performance Metrics
```html
↑
```
### React Implementation with Hooks
```tsx
import { useState, useEffect } from 'react';
function BackToTop() {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const toggleVisibility = () => {
setIsVisible(window.scrollY > 300);
};
window.addEventListener('scroll', toggleVisibility);
return () => window.removeEventListener('scroll', toggleVisibility);
}, []);
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
return (
↑
);
}
```
### CSS Styling
```css
.back-to-top {
position: fixed;
bottom: 1rem;
right: 1rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
background: #333;
color: white;
border: none;
cursor: pointer;
opacity: 0;
visibility: hidden;
transition: opacity 200ms, visibility 200ms;
}
.back-to-top.visible {
opacity: 1;
visibility: visible;
}
.back-to-top:hover {
background: #555;
}
.back-to-top:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
```
## Performance
### Performance Metrics
**Target Metrics:**
* **Scroll trigger threshold**: Show after 2x viewport height (or \~1000px)
* **Scroll animation duration**: 300-500ms for smooth feel
* **Button fade-in**: \< 200ms transition
* **Interaction delay**: \< 50ms response to click
* **Frame rate**: Maintain 60fps during scroll animation
**Scroll Performance:**
* **Throttle scroll events**: Check position every 100-150ms (not on every scroll)
* **Use Intersection Observer**: More performant than scroll listeners
* **Passive event listeners**: Add `{ passive: true }` to scroll handlers
* **RAF for animations**: Use requestAnimationFrame for smooth scrolling
**Visibility Optimization:**
* **CSS transitions**: Use for show/hide animations (not JavaScript)
* **Transform + opacity**: Animate these properties for GPU acceleration
* **Will-change**: Apply sparingly to button during transitions
* **Avoid reflows**: Don't change layout properties during animations
**Mobile Performance:**
* **Touch responsiveness**: \< 100ms feedback on tap
* **Reduced motion**: Respect `prefers-reduced-motion` media query
* **Scroll behavior**: Use native CSS `scroll-behavior: smooth` when possible
* **Battery impact**: Minimize continuous animations
## Testing Guidelines
### Functional Testing
**Should ✓**
* [ ] Show the button after scrolling a set distance
* [ ] Smoothly scroll to top when clicked
* [ ] Hide the button when the user is near the top
* [ ] Maintain correct visible/hidden states on page load and resize
* [ ] Prevent overlapping interactions with other floating components
Accessibility Testing
**Should ✓**
* [ ] Have proper ARIA labels for icon-only implementations
* [ ] Be operable with keyboard (Enter, Space)
* [ ] Maintain a visible focus state when tabbed to
* [ ] Provide enough contrast between button and background
* [ ] Respect user motion preferences (reduce motion if system preferences are set)
Visual Testing
**Should ✓**
* [ ] Float consistently at the chosen position across different viewport sizes
* [ ] Show correct hover, focus, and active states
* [ ] Remain unobtrusive yet visible
* [ ] Align with other design elements and not overlap key UI components
Performance Testing
**Should ✓**
* [ ] Not introduce layout shifts when appearing or disappearing
* [ ] Handle rapid scrolling up/down events effectively
* [ ] Support smooth animations without jank
* [ ] Remain performant on mobile devices
## Browser Support
## Performance Metrics
### Target Metrics
**Response Times:**
* **Button appearance:** \< 50ms after scroll threshold
* **Hover feedback:** \< 100ms visual response
* **Click to scroll start:** \< 50ms
* **Scroll animation:** 300-500ms duration
* **Focus outline:** Immediate (\< 16ms)
**Scroll Performance:**
* **Throttle rate:** Check position every 100-150ms
* **Frame rate:** Maintain 60fps during animations
* **Memory usage:** \< 1MB for button component
* **CPU usage:** \< 5% during scroll monitoring
**Animation Performance:**
* **Use transform/opacity:** GPU-accelerated properties only
* **Avoid reflows:** No layout changes during animations
* **Will-change:** Apply sparingly, remove after animation
* **RequestAnimationFrame:** For smooth scroll implementations
**Mobile Optimization:**
* **Touch response:** \< 100ms feedback
* **Gesture recognition:** Support swipe-to-top on iOS
* **Battery impact:** Minimal with throttled events
* **Reduced motion:** Respect user preferences
## SEO Considerations
* **No direct SEO impact** - Back to Top is a UX feature that doesn't affect content indexing
* **Indirect benefits:** Improved user engagement metrics (time on page, bounce rate)
* **Ensure button doesn't hide content** from search engine crawlers
* **Use semantic HTML** (`` element) for better accessibility signals
* **Avoid keyword stuffing** in button text or ARIA labels
## Design Tokens
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.
### Button Tokens in DTF Format
```json
{
"$schema": "https://design-tokens.org/schema.json",
"backToTop": {
"position": {
"right": { "value": "1rem", "type": "dimension" },
"bottom": { "value": "1rem", "type": "dimension" }
},
"sizing": {
"width": { "value": "2.5rem", "type": "dimension" },
"height": { "value": "2.5rem", "type": "dimension" },
"touchTarget": {
"value": "2.75rem",
"type": "dimension",
"description": "44px minimum touch target"
}
},
"icon": {
"size": { "value": "1.25rem", "type": "dimension" }
},
"border": {
"radius": { "value": "50%", "type": "dimension" },
"width": { "value": "0px", "type": "dimension" }
},
"colors": {
"background": {
"default": { "value": "{color.gray.200}", "type": "color" },
"hover": { "value": "{color.gray.300}", "type": "color" },
"active": { "value": "{color.gray.400}", "type": "color" }
},
"icon": {
"default": { "value": "{color.gray.900}", "type": "color" }
}
},
"states": {
"focusRing": {
"width": { "value": "2px", "type": "dimension" },
"offset": { "value": "2px", "type": "dimension" },
"color": { "value": "{color.primary.200}", "type": "color" }
}
}
}
}
```
## FAQ
` element, provide a descriptive label like 'Back to Top', and implement visible focus indicators for users navigating via keyboard.",
},
{
question:
"What are the best practices for designing a 'Back to Top' button?",
answer:
"Use clear labeling, maintain a consistent position, ensure the button is appropriately sized for both desktop and mobile devices, and avoid covering important content. The button should appear after users have scrolled down a significant portion of the page.",
},
]}
/>
## Related Patterns
## Resources
### Libraries & Frameworks
#### React Components
* [React Scroll](https://github.com/fisshy/react-scroll) – Scroll components with smooth animations
#### Vue Components
* [Vue Backtotop](https://github.com/caiofsouza/vue-backtotop) – Back to top component for Vue.js
* [Vue Scroll To](https://github.com/rigor789/vue-scrollto) – Scrolling to elements with easing
#### Vanilla JavaScript
* [Vanilla Back To Top](https://github.com/vfeskov/vanilla-back-to-top) – Lightweight vanilla JS implementation
* [ScrollToTop.js](https://github.com/cferdinandi/smooth-scroll) – Smooth scrolling library
### Articles
* [Back-to-Top Button Design Guidelines](https://www.nngroup.com/articles/back-to-top/)
* [Scroll to Top: Does it Need to be Accessible?](https://www.digitala11y.com/scroll-to-top-does-it-need-to-be-accessible/)
# UX Patterns for Devs: Breadcrumb
URL: /patterns/navigation/breadcrumb
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/breadcrumb.mdx
Create effective breadcrumb navigation for better site orientation. Learn implementation techniques, accessibility requirements, and design best practices for clear hierarchical navigation.
***
title: "Breadcrumb"
summary: "Help users understand their current location"
description: "Create effective breadcrumb navigation for better site orientation. Learn implementation techniques, accessibility requirements, and design best practices for clear hierarchical navigation."
icon: Navigation2
status: complete
----------------
## Overview
**Breadcrumbs** display as horizontal link lists separated by symbols, helping users understand their website location at a glance.
Breadcrumbs work as secondary navigation aids showing users their current location and providing easy navigation back through parent pages.
Websites with deep hierarchical structures or complex navigation paths benefit most from breadcrumbs.
## Use Cases
### When to use:
Use **Breadcrumbs** to **show users their location within a website's structure and help easy navigation**.
**Common scenarios include:**
* Websites have multiple hierarchical levels (categories, sub-categories)
* Large or complex sites where users land on deep pages from search engines
* Systems rely on nested file or document organization (file explorers, project management tools)
* E-commerce stores use layered product categories
### When not to use:
* Single-level websites have flat structure
* Landing pages or homepages don't need them
* Small websites use simple navigation
* Hierarchy already shows through other navigation elements
* Single-page applications use modal-based navigation
### Common scenarios and examples
* E-commerce: Home > Electronics > Smartphones > iPhone 15
* Content Management: Dashboard > Projects > Project A > Documents
* File Systems: My Drive > Work > 2024 > Reports
## Benefits
* Fewer actions needed to navigate up levels
* Users don't feel lost in complex hierarchies
* Better SEO through exposed site structure
* Lower bounce rates for deep-linked pages
* Clear contextual information about current location
## Drawbacks
* **Context may be redundant on very flat sites** – On single‑level or shallow sites, breadcrumbs add little value; they're most useful when users land deep from external links and need quick context and upward navigation
* **Takes up space** – Redundant on small screens or without hierarchical navigation needs
* **Responsive design complexity** – Long trails need truncation or horizontal scrolling
* **Structured data requirement** – Correct implementation needed for SEO benefits (schema markup)
* **Misuse in flat hierarchies** – No benefit without clear depth-based navigation
## Anatomy
```mermaid
flowchart TB
subgraph Breadcrumb[Breadcrumb Navigation]
A[Home] -.->|separator| B[Parent Page]
B -.->|separator| C[Current Page]
classDef container stroke:#666,stroke-width:2px
class Breadcrumb container
end
```
### Component Structure
1. **Container (`nav`)**
* Wraps entire breadcrumb navigation
* Uses **semantic navigation elements** for accessibility
* Needs proper labeling for **screen readers**
2. **List (`ol`)**
* Holds **breadcrumb items** in sequential order
* Shows **hierarchical structure** of the page
* Usually an **ordered list** conveying structure
3. **Items (`li`)**
* **Home Link (Optional):** Starting point linking to homepage
* **Parent Pages:** Clickable links representing higher navigation levels
* **Current Page:** Final item that **shouldn't be a link** since it's the current view
* **Separators:** Visual dividers (`/`, `>`) showing clear navigation hierarchy
#### Summary of Components
| Component | Required? | Purpose |
| ------------ | --------- | ----------------------------------------------------- |
| Container | ✅ Yes | Wraps the entire breadcrumb navigation. |
| List | ✅ Yes | Contains the breadcrumb items in order. |
| Items | ✅ Yes | Represents individual breadcrumb links. |
| Separators | ✅ Yes | Visually separates breadcrumb links. |
| Home Link | ❌ No | Provides an optional shortcut to the homepage. |
| Current Page | ✅ Yes | Represents the active page (should not be clickable). |
## Best Practices
### Content
**Do's ✅**
* Use clear, concise labels that match page titles
* Maintain consistent naming conventions
* Show the full hierarchy path
**Don'ts ❌**
* Don't use inconsistent terminology between breadcrumb items and page titles
* Don't truncate breadcrumb items without indicating there's more content
### Accessibility
**Do's ✅**
* Use `` with `aria-label="Breadcrumb"` for landmark navigation
* Mark current page with `aria-current="page"`
* Use ordered list `` to convey sequence
* Ensure keyboard navigation with visible focus indicators
* Provide skip links for lengthy breadcrumb trails
* Announce dynamic breadcrumb updates to screen readers
**Don'ts ❌**
* Don't make the current page title clickable
* Don't rely solely on visual separators (use CSS pseudo-elements)
* Don't remove focus indicators without alternatives
* Don't use color alone to indicate current page
### Visual Design
**Do's ✅**
* Make it obvious that the last item is not clickable (through color, cursor type, etc.)
* Use consistent visual styling across all pages
* Ensure sufficient contrast between text and background
**Don'ts ❌**
* Don't use distracting animations or transitions
* Don't make separators too prominent
### Layout & Positioning
**Do's ✅**
* Place the breadcrumb at the top of the page, below the global navigation and above the page title
* Keep the breadcrumb left-aligned
* Consider showing both icon and text on larger screens
* Consider showing a house icon instead of text "Home" on smaller screens
**Don'ts ❌**
* Do not show a breadcrumb if the navigation's hierarchy contains only one level (home page or landing pages for example)
* Do not use an HTML element for separators but prefer using CSS
## Breadcrumb Variations
### Location-Based Breadcrumbs
Shows the page's position within the site hierarchy, most common type.
```html
Home > Products > Electronics > Laptops > Gaming Laptops
```
**Use when:** Site has clear hierarchical structure with defined categories.
### Path-Based Breadcrumbs
Shows the actual path the user took to reach the current page.
```html
Home > Search Results > Product Details > Reviews
```
**Use when:** Users follow varied paths and need to retrace their journey.
### Attribute-Based Breadcrumbs
Displays attributes or filters applied to reach current view.
```html
Products > Brand: Apple > Price: $500-$1000 > In Stock
```
**Use when:** E-commerce sites with faceted search and filtering.
### Mobile Breadcrumbs
Collapsed or simplified versions for small screens.
```html
← Electronics / Laptops
```
**Use when:** Mobile interfaces need space-efficient navigation.
## Common Mistakes & Anti-Patterns 🚫
### Making Current Page a Link
**The Problem:**
The last breadcrumb item links to the current page, creating confusing circular navigation.
```html
Current Page
Current Page
```
**How to Fix It:**
Use a non-clickable span with `aria-current="page"` for the current page instead of a link.
### Using Breadcrumbs as Primary Navigation
**The Problem:**
Relying on breadcrumbs instead of proper main navigation, leaving users without clear site structure.
**How to Fix It:**
Always provide a main navigation menu. Breadcrumbs should supplement, not replace primary navigation.
### Incorrect Hierarchy Representation
**The Problem:**
Breadcrumb trail doesn't match actual site structure, misleading users about their location.
```html
Home > Product Details
Home > Products > Electronics > Product Details
```
**How to Fix It:**
Show the complete hierarchical path from home to current page without skipping levels.
### Poor Mobile Handling
**The Problem:**
Full breadcrumb trail causes horizontal scroll on mobile, reducing usability.
```css
/* Bad */
.breadcrumb { white-space: nowrap; }
/* Good: Progressive disclosure */
@media (max-width: 768px) {
.breadcrumb-item:not(:last-child):not(:first-child) {
display: none;
}
}
```
**How to Fix It:**
Use progressive disclosure or collapsed breadcrumbs on mobile to show only essential levels.
### Missing Semantic Markup
**The Problem:**
Using generic divs without proper ARIA labels breaks screen reader navigation.
```html
...
...
```
**How to Fix It:**
Use semantic HTML with `` and `` elements, plus proper ARIA labels for accessibility.
## Tracking
Tracking breadcrumb interactions helps measure how users navigate through a site, whether they rely on breadcrumbs for backtracking, and if they help reduce friction in multi-level navigation. By analyzing usage patterns, we can optimize the breadcrumb structure and placement.
### Key Tracking Points
Each breadcrumb interaction provides valuable insights into user behavior. Below are the key events that should be tracked:
| **Event Name** | **Description** | **Why Track It?** |
| ------------------------ | ------------------------------------------------------------------ | --------------------------------------------------------------------- |
| `breadcrumb.view` | When the breadcrumb component enters the viewport. | Determines visibility and whether breadcrumbs are available to users. |
| `breadcrumb.click` | When a user clicks on any breadcrumb link. | Measures engagement and breadcrumb-driven navigation. |
| `breadcrumb.home_click` | When a user clicks on the **home** link in the breadcrumb. | Tracks how often users return to the homepage via breadcrumbs. |
| `breadcrumb.level_click` | When a user clicks on an intermediate breadcrumb level. | Helps assess whether users navigate back up the hierarchy. |
| `breadcrumb.usage` | Captures breadcrumb interaction data relative to total page views. | Helps measure how often breadcrumbs are used when available. |
### Event Payload Structure
To ensure consistent tracking, here’s a recommended event format:
```json
{
"event": "breadcrumb.click",
"properties": {
"breadcrumb_id": "product_category",
"clicked_level": "Electronics",
"breadcrumb_position": 2,
"total_levels": 4
}
}
```
### Key Metrics to Analyze
Once tracking is in place, the following metrics provide actionable insights:
* **Breadcrumb Usage Rate** → Percentage of page visits where breadcrumbs were interacted with.
* **Breadcrumb Click-Through Rate (CTR)** → Percentage of users who interact with breadcrumbs after seeing them.
* **Navigation Recovery Rate** → How often users navigate up using breadcrumbs instead of the browser back button.
* **Home Click Rate** → Measures how often users return to the homepage via breadcrumbs.
* **Intermediate Level Click Rate** → Tracks how often users use breadcrumbs to navigate back to higher levels.
### Insights & Optimization Based on Tracking
By analyzing tracking data, we can optimize breadcrumb usability:
* 🚨 **Low Breadcrumb Usage Rate?**
→ Users may not notice breadcrumbs or find them unnecessary.
**Optimization:** Improve visibility, adjust styling for better contrast, or test a more prominent placement.
* ⏳ **Low Breadcrumb Click-Through Rate?**
→ Users see breadcrumbs but don’t interact with them.
**Optimization:** Consider whether breadcrumbs are necessary in the current navigation structure. They may be redundant if other navigation methods are more intuitive.
* 🔄 **Frequent Home Clicks?**
→ Users might be struggling to find their way back.
**Optimization:** Review site structure and ensure proper linking between categories.
* 🔁 **More Back Button Usage Than Breadcrumb Clicks?**
→ Users might prefer using browser navigation instead of breadcrumbs.
**Optimization:** Make breadcrumbs more interactive and clearly indicate their functionality.
* 📉 **Low Intermediate Level Click Rate?**
→ Users are not navigating up through breadcrumbs.
**Optimization:** Ensure breadcrumbs are relevant for deep hierarchies and not just duplicating the main navigation.
By continuously monitoring these metrics, we can refine breadcrumb effectiveness, ensuring they support seamless navigation and reduce friction in user journeys.
## Performance Metrics
Target performance metrics for breadcrumb navigation:
* **Initial render**: \< 50ms for breadcrumb component
* **Interaction delay**: \< 100ms for hover/focus states
* **Layout shift**: CLS score of 0 (no shift after initial render)
* **Bundle size**: \< 5KB for breadcrumb component with styles
* **Memory usage**: \< 1MB for complex breadcrumb trails
### Optimization Strategies
**Lazy Loading for Deep Hierarchies**
```javascript
// Load intermediate levels only when needed
const BreadcrumbTrail = ({ path }) => {
const [expanded, setExpanded] = useState(false);
if (path.length > 5 && !expanded) {
return (
<>
{path[0]}
setExpanded(true)}>...
{path[path.length - 1]}
>
);
}
return path.map(item => );
};
```
**CSS-Only Separators**
```css
/* Avoid DOM elements for separators */
.breadcrumb-item:not(:last-child)::after {
content: "›";
margin: 0 0.5rem;
}
```
## Usability Testing Insights
Research shows that users:
* Understand breadcrumb purpose immediately when properly styled (87% of users)
* Use breadcrumbs for upward navigation (52% of users)
* Click middle hierarchy levels more than home (68% of clicks)
* Have 23% lower engagement on mobile due to space constraints
* Prefer ">" separator over other symbols (72% preference)
### Testing Recommendations
**A/B Test Variables:**
* Separator symbols (>, /, →, |)
* Truncation methods (ellipsis, collapsing, scrolling)
* Current page inclusion/exclusion
* Mobile presentation styles
## Localization
### Text Expansion Considerations
Breadcrumb text can expand 30-200% when translated:
```css
/* Allow for text expansion */
.breadcrumb {
min-width: 0;
flex-wrap: wrap;
}
.breadcrumb-item {
min-width: 0;
overflow-wrap: break-word;
}
```
### RTL (Right-to-Left) Support
```css
/* Automatic RTL flipping */
.breadcrumb {
display: flex;
flex-direction: row;
}
/* Flip separator in RTL */
[dir="rtl"] .breadcrumb-item:not(:last-child)::after {
content: "‹";
}
```
### Cultural Considerations
* **Home Label:** "Home" doesn't translate literally in all languages
* **Separator Symbols:** Avoid culturally specific symbols
* **Truncation:** Consider character-based vs word-based truncation
* **Reading Direction:** Some cultures read hierarchy differently
## Code Examples
### Basic Implementation
This example uses semantic HTML to provide a clear structure for the breadcrumb navigation.
```html
Home
Products
Current Page
```
### JSON-LD Structured Data
This example demonstrates how to dynamically generate the breadcrumb JSON-LD structured Data using JavaScript.
```javascript
const breadcrumbs = [
{ title: "Home", url: "https://example.com" },
{ title: "Products", url: "https://example.com/products" },
{ title: "Current Page" },
];
function generateBreadcrumbSchema(breadcrumbs) {
return {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: breadcrumbs.map((crumb, index) => {
const isLastItem = index === breadcrumbs.length - 1;
const baseItem = {
"@type": "ListItem",
position: index + 1,
name: crumb.title,
};
// Only add the "item" property if it's not the last item and has a URL
if (!isLastItem && crumb.url) {
baseItem.item = crumb.url;
}
return baseItem;
}),
};
}
```
## SEO
### Structured Data
* Implement breadcrumb structured data using [Schema.org markup](https://schema.org/BreadcrumbList) to help search engines understand your site's hierarchy
* This improves the way your site appears in search results and helps search engines better understand your content structure
Example JSON-LD structured data:
```json
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Products",
"item": "https://example.com/products"
},
{
"@type": "ListItem",
"position": 3,
"name": "Current Page"
}
]
}
```
### Testing & Validation
* Use Google's [Rich Results Test](https://search.google.com/test/rich-results) to validate structured data
* Monitor breadcrumb appearance in search results through Google Search Console
* Check for proper indexing of breadcrumb pages in site architecture
* Verify mobile rendering of breadcrumbs for mobile-first indexing
## Testing Guidelines
### Functional Testing
**Should ✓**
* [ ] Navigate to the correct page when clicking each breadcrumb link
* [ ] Show the complete hierarchy path from home to current page
* [ ] Update breadcrumb trail when navigating through different levels
* [ ] Maintain state after page refresh
* [ ] Work with browser back/forward navigation
### Accessibility Testing
**Should ✓**
* [ ] Be navigable using keyboard (Tab and Enter keys)
* [ ] Have proper ARIA labels and roles
* [ ] Announce proper hierarchy to screen readers
* [ ] Maintain focus state visibility
* [ ] Have sufficient color contrast (WCAG 2.2 AA)
### Responsive Testing
**Should ✓**
* [ ] Adapt layout for different screen sizes
* [ ] Show/hide home icon appropriately
* [ ] Handle text overflow gracefully
* [ ] Maintain touch target sizes on mobile (minimum 44x44px)
* [ ] Preserve functionality across different devices
### SEO Testing
**Should ✓**
* [ ] Include proper Schema.org markup
* [ ] Have semantic HTML structure
* [ ] Maintain consistent URL structure
* [ ] Include relevant meta tags
* [ ] Follow proper link hierarchy
### Performance Testing
**Should ✓**
* [ ] Load without significant delay
* [ ] Not cause layout shifts
* [ ] Handle large numbers of items efficiently
* [ ] Work with dynamic content updates
* [ ] Function without JavaScript (progressive enhancement)
## Browser Support
## Design Tokens (DTF)
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.
```json
{
"breadcrumb": {
"container": {
"paddingY": "{spacing.3}",
"paddingX": "{spacing.0}",
"fontSize": "{fontSize.sm}",
"background": "{colors.transparent}"
},
"item": {
"color": "{colors.gray.600}",
"colorHover": "{colors.gray.900}",
"marginRight": "{spacing.2}",
"fontSize": "{fontSize.sm}"
},
"separator": {
"color": "{colors.gray.400}",
"marginX": "{spacing.2}"
},
"current": {
"color": "{colors.gray.900}",
"fontWeight": "{fontWeight.medium}"
},
"link": {
"color": "{colors.gray.600}",
"colorHover": "{colors.gray.900}",
"textDecoration": "{textDecoration.none}",
"transition": "{transition.colors}",
"focusOutline": "2px solid {colors.blue.500}"
}
}
}
```
## Frequently Asked Questions
' or '/'\n" +
"3. Ensure all items, except the current page, are clickable links\n" +
"4. Be concise and not occupy excessive space\n" +
"5. Be placed near the top of the page, below the main navigation",
},
{
question: "What are the benefits of using breadcrumbs?",
answer:
"Breadcrumbs enhance user experience by:\n\n" +
"1. Providing a clear path back to higher-level pages\n" +
"2. Reducing the number of actions needed to navigate to previous pages\n" +
"3. Offering context about the site's structure\n" +
"4. Potentially improving SEO by providing internal links with relevant anchor text",
},
{
question: "What are common mistakes to avoid with breadcrumb navigation?",
answer:
"Avoid these common mistakes:\n\n" +
"1. Making the breadcrumb trail too prominent, overshadowing primary navigation\n" +
"2. Omitting the current page from the breadcrumb trail\n" +
"3. Using inconsistent or unclear separators\n" +
"4. Not providing enough space between links, making them hard to click, especially on mobile devices",
},
]}
/>
## Related Patterns
## Resources
### Articles
* [Breadcrumbs: 11 Design Guidelines for Desktop and Mobile](https://www.nngroup.com/articles/breadcrumbs/) by Nielsen Norman Group
* [Designing Effective Breadcrumbs Navigation — Smashing Magazine](https://www.smashingmagazine.com/2022/04/breadcrumbs-ux-design/)
* [Breadcrumb Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/) by W3C
* [Breadcrumbs](https://a11y-style-guide.com/style-guide/section-navigation.html#kssref-navigation-breadcrumbs) - By A11y Style guide
### Libraries
* [Breadcrumb: shadcn/ui](https://ui.shadcn.com/docs/components/breadcrumb)
* [Breadcrumb - Origin UI](https://originui.com/breadcrumb)
# UX Patterns for Devs: Hamburger Menu
URL: /patterns/navigation/hambuger-menu
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/hambuger-menu.mdx
Create accessible mobile menus with smooth animations and touch-friendly interactions.
***
title: "Hamburger Menu"
summary: "Display a menu icon for mobile devices"
description: "Create accessible mobile menus with smooth animations and touch-friendly interactions."
icon: Menu
----------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Infinite scroll
URL: /patterns/navigation/infinite-scroll
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/infinite-scroll.mdx
Create seamless content loading with infinite scroll, focusing on performance, accessibility, and user experience best practices.
***
title: "Infinite scroll"
summary: "Loads additional content automatically as users scroll down."
description: "Create seamless content loading with infinite scroll, focusing on performance, accessibility, and user experience best practices."
icon: Infinity
status: complete
----------------
import { GuidesBanner } from "@/components/guides-banner";
***(Also called Continuous scrolling)***
## Overview
**Infinite Scroll** is a UI pattern that dynamically loads more content as users scroll down a page, eliminating the need for pagination or manual interaction. It provides a seamless browsing experience by continuously appending new items to the current view.
This pattern is commonly used in **social media feeds, search results, and content-heavy websites** to keep users engaged without interruptions.
## Use Cases
### When to use:
Use Infinite Scroll when you need to dynamically load more content as users scroll without requiring manual pagination.
**Common scenarios include:**
* **Social media feeds** – e.g., Twitter, Instagram, Facebook, where users consume an endless stream of content.
* **News and blog sites** – e.g., showing a continuous stream of articles.
* **E-commerce product listings** – e.g., dynamically loading more items as users explore the catalog.
* **Search results** – e.g., reducing friction in discovering relevant items.
* **Media galleries** – e.g., loading more images/videos as users scroll.
### When not to use:
* **When users need to find specific content quickly** – Paginated results may be more efficient.
* **For structured navigation** – If users need to compare items or revisit previous results, pagination provides better control.
* **If performance is a concern** – Infinite scroll can lead to high memory usage and slow rendering.
* **For content requiring user actions** – If users frequently need to interact with elements (e.g., filling forms), infinite scrolling can be disruptive.
* **When reaching the footer is important** – Users may struggle to access footer content if new items keep loading.
## Benefits
* **Enhances engagement** by providing a seamless browsing experience.
* **Eliminates unnecessary page loads** and reduces navigation friction.
* **Encourages content exploration** by presenting an uninterrupted flow of items.
* **Optimized for touchscreens** where scrolling is more intuitive than clicking pagination buttons.
## Drawbacks
* **Navigation challenges** – Users may struggle to return to a previous position.
* **Performance issues** – Excessive DOM elements can lead to lag and slow rendering.
* **Accessibility concerns** – Keyboard and screen reader users may find it harder to navigate.
* **Disrupts footer visibility** – Users may never reach the footer if content loads indefinitely.
## Anatomy
```mermaid
flowchart TB
subgraph InfiniteScroll[Infinite Scroll Component]
A[Content Container] --> B[Trigger Point]
B --> C[Loading Indicator]
C --> D[Newly Loaded Content]
D --> E[Next Trigger Point - Optional]
end
```
### Component Structure
1. **Content Container**
* Holds the dynamically loaded items.
* Ensures content is structured and visually organized.
* Can be a **list, grid, or other layout structure**.
2. **Trigger Point**
* The detection mechanism that determines **when to load more content**.
* Typically appears when the **user scrolls near the end** of the container.
* Can be based on **[viewport](/glossary/viewport) visibility, scroll depth, or other triggers**.
3. **Loading Indicator**
* Provides **visual feedback** while content is being retrieved.
* Can be a **spinner, progress bar, or skeleton loader**.
* Should **only be displayed when new content is actively loading**.
4. **Newly Loaded Content**
* The additional items dynamically inserted once new data is fetched.
* Should **seamlessly integrate** with previously loaded content.
* May **fade in or animate** to indicate new content.
5. **Next Trigger Point (Optional)**
* If more content is available, a new **Trigger Point** is added for the next batch.
* Helps manage continuous loading in **long content feeds**.
#### Summary of Components
| Component | Required? | Purpose |
| -------------------- | --------- | ------------------------------------------------------------ |
| Content Container | ✅ Yes | Holds the items being dynamically loaded. |
| Trigger Point | ✅ Yes | Detects when the user reaches the threshold for new content. |
| Loading Indicator | ✅ Yes | Shows that content is being fetched. |
| Newly Loaded Content | ✅ Yes | Represents the new batch of dynamically inserted content. |
| Next Trigger Point | ❌ No | Appears if additional content is available for loading. |
## Best Practices
### Content & Usability
**Do's ✅**
* **Provide clear loading indicators** to inform users that content is being fetched.
* **Use a 'Load More' button as a fallback** in case auto-loading fails.
* **Allow users to jump back to the top** with a 'Back to Top' button.
* **Save scroll position** so users don't lose their place when navigating back.
**Don'ts ❌**
* **Avoid infinite loops** – Ensure loading stops when all content is fetched.
* **Don't break browser back navigation** – Users should be able to return to previous content states.
* **Avoid excessive memory usage** – Remove off-screen items if necessary to optimize performance.
### Accessibility
**Do's ✅**
* **Ensure content is focusable** – New items should be reachable via keyboard navigation.
* **Announce new content dynamically** using ARIA [live regions](/glossary/live-regions) (`aria-live="polite"`).
* **Provide an alternative to infinite scrolling** – Offer pagination or a "Load More" option.
* **Ensure users can pause or stop loading** – Unexpected content updates can be disorienting.
**Don'ts ❌**
* **Avoid relying solely on scrolling** – Users with assistive technologies may need alternative navigation.
* **Don't change content order unexpectedly** – Screen readers should process content sequentially.
### Visual Design
**Do's ✅**
* **Use smooth transitions** when loading new items to maintain a natural experience.
* **Indicate loading state** – Provide a spinner or skeleton loader while fetching data.
* **Ensure visual continuity** – Keep layout stable to prevent sudden jumps.
**Don'ts ❌**
* **Don't push content down unexpectedly** – New items should append seamlessly without disrupting user flow.
* **Avoid excessive whitespace** – Content should remain readable and well-structured.
### Performance Optimization
**Do's ✅**
* **Implement lazy loading** – Load images and assets only when needed.
* **Use virtualization** – Remove off-screen items from the DOM to improve performance.
* **Optimize API calls** – Fetch only necessary data to reduce network requests.
**Don'ts ❌**
* **Avoid fetching too much data at once** – This can slow down rendering and increase memory usage.
* **Don't re-render the entire list on new data arrival** – Only update necessary elements.
## SEO Considerations
* Ensure **search engines can access all content** by implementing **server-side rendering (SSR)** or an accessible paginated alternative.
* Provide a **static link to all content pages** to ensure crawlers can index them.
* Ensure that critical content is **available without JavaScript**.
## Testing Guidelines
### Functional Testing
**Should ✓**
* [ ] Confirm new content loads properly as the user scrolls.
* [ ] Ensure scroll position remains stable after navigating back to the page.
* [ ] Verify that users can manually load more content if needed.
* [ ] Ensure the feature works across different browsers and devices.
### Accessibility Testing
**Should ✓**
* [ ] Verify that screen readers announce new content properly.
* [ ] Ensure that keyboard users can navigate through dynamically loaded items.
* [ ] Test with reduced motion settings to ensure animations don't cause issues.
### Performance Testing
**Should ✓**
* [ ] Measure memory usage to prevent excessive DOM elements.
* [ ] Ensure API calls are efficient and minimize network overhead.
* [ ] Test scrolling performance on both desktop and mobile devices.
## Related Patterns
## Frequently Asked Questions
## Resources
### Articles
### Documentation
### Libraries
# UX Patterns for Devs: Link
URL: /patterns/navigation/link
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/link.mdx
Build accessible links with proper styling, hover states, and keyboard navigation support.
***
title: "Link"
summary: "Create accessible and interactive links"
description: "Build accessible links with proper styling, hover states, and keyboard navigation support."
icon: Link
----------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Load More
URL: /patterns/navigation/load-more
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/load-more.mdx
Build efficient content loading with the Load More pattern, focusing on user experience and performance optimization.
***
title: "Load More"
summary: "Load additional content on user demand"
description: "Build efficient content loading with the Load More pattern, focusing on user experience and performance optimization."
icon: Plus
status: complete
----------------
import { Playground } from "@/components/playground";
## Overview
**Load More** lets users request additional content dynamically instead of loading everything upfront. This pattern cuts initial page load times and gives users seamless access to more content when they need it.
## Use Cases
### When to use:
Use Load More when users should explore content progressively at their own pace without getting overwhelmed. Unlike infinite scrolling, Load More gives users clear control and lets them consciously decide when to view more items.
For better usability, make sure the Load More button gets **removed when all content is loaded** or updates to show that no additional items remain (like **"No More Results"**).
**Common scenarios include:**
* Large lists of content need pagination (news feeds, product listings)
* Page performance improves by loading only a subset of data initially
* Users browse progressively instead of needing all content at once
* You want an alternative to infinite scrolling with more user control
### When not to use:
* The full content list is small enough to load upfront without performance issues
* Users need to compare multiple items at once ([pagination](/patterns/navigation/pagination) works better here)
* Real-time updates or continuous data streaming is required
### Common scenarios and examples
* **E-commerce**: Loading additional products in a grid or list
* **News or blog feeds**: Expanding more articles dynamically
* **Social media feeds**: Loading additional posts without overwhelming users
* **Search results**: Fetching more results upon user request
## Benefits
* **Speeds up initial page load** by reducing data overhead
* **Users control** their content consumption, avoiding cognitive overload
* **Better accessibility** than infinite scrolling since users keep track of their position
* **Works across devices** with controlled data retrieval
* **Footer stays accessible** – users can reach secondary links like policies, shipping info, and contact details
* **Stops unnecessary clicks** by **removing the Load More button once everything loads** or showing **"No More Results"**
* **Prevents layout jumps** – newly loaded content appears smoothly without shifting user position
## Drawbacks
* **User Effort** – Users must take action to reveal more content, not seamless like infinite scroll
* **Hidden Content Risk** – Users might miss that more content exists if the button lacks visibility
* **Flow Interruption** – Clicking Load More breaks immersion compared to continuous scrolling
* **Navigation Issues** – Returning to previously loaded sections gets tricky without proper implementation
* **SEO Hurdles** – Search engines might skip dynamically loaded content without proper handling
* **Accessibility Work** – Screen readers need careful ARIA implementation to announce new content
* **Performance Cost** – Multiple fetch requests impact performance without optimization
## Anatomy
```mermaid
flowchart TB
subgraph LoadMore[Load More Component]
A[Container] --> B[Initial Content List]
B --> C[Load More Button]
C --> D[Loading Indicator - Optional]
C --> E[Additional Content]
E --> F[Another Load More Button - Optional]
end
```
### Component Structure
1. **Container**
* Wraps the entire load more component
* Keeps content properly structured and styled
2. **Initial Content List**
* Shows a **limited number of items** to avoid overwhelming users
* Sets the default **starting state** before additional content loads
3. **Load More Button**
* Primary trigger for **loading additional content**
* Must show **clear affordance** that more content exists
* Often includes **ARIA attributes** to indicate loading state
4. **Loading Indicator (Optional)**
* Shows **visual feedback** while fetching new content
* Usually a **spinner, progress bar, or skeleton loader**
5. **Additional Content**
* **Newly loaded items** appear after clicking Load More
* Must blend **seamlessly** with the initial content list
6. **Another Load More Button (Optional)**
* Appears **if more content is available after the first load**.
* Helps users **incrementally explore content** without scrolling endlessly.
#### Summary of Components
| Component | Required? | Purpose |
| ------------------------ | --------- | ------------------------------------------------------------ |
| Container | ✅ Yes | Wraps the content that will load more items. |
| Initial Content List | ✅ Yes | Displays a limited set of items to avoid overwhelming users. |
| Load More Button | ✅ Yes | Allows users to manually fetch more content. |
| Loading Indicator | ❌ No | Shows progress while loading more items. |
| Additional Content | ✅ Yes | The dynamically inserted content after clicking "Load More." |
| Another Load More Button | ❌ No | Appears if further content can still be loaded. |
## Variations
### Basic Load More
Standard button that loads additional content when clicked.
### Load More with Counter
Shows how many items will be loaded (e.g., "Load 10 more items").
### Load More with Progress
Displays overall progress (e.g., "Showing 20 of 100 items").
### Auto-Load on Scroll Proximity
Automatically triggers when user scrolls near the button (hybrid approach).
### Load More with Categories
Multiple load more buttons for different content sections.
### Skeleton Loading
Shows placeholder content while real content loads.
## Best Practices
### Content
**Do's ✅**
* Show clearly that more content is available
* Pick concise, meaningful labels: **"Load More"**, **"Show More"**, or **"See More Results"**
* Keep transitions smooth when new content loads
**Don'ts ❌**
* Skip vague labels like **"Click Here"**
* Never load excessive content at once; keep batches manageable
* Avoid disrupting the existing layout when inserting new content
### Accessibility & UX
**Do's ✅**
* Make the **Load More** button keyboard accessible (`tab` and `enter` keys)
* Announce new content to screen readers (`aria-live="polite"`)
* Give feedback (loading indicators) to show content retrieval
* **Keep keyboard focus logical** – After clicking Load More, focus shifts **to the newly loaded content**, not back to the button
* **Alert assistive technologies** – `aria-live="polite"` tells screen reader users that additional items loaded
**Don'ts ❌**
* Keep focus on the **Load More** button after clicking (skip `disabled`)
* Never use infinite scrolling without a **Load More** fallback
* Stop relying solely on color for action buttons (check contrast and readable text)
### Visual Design
**Do's ✅**
* Put the **Load More** button prominently below existing content
* Show clear visual feedback when new content loads (animations, progress indicators)
* Keep spacing and alignment consistent with existing content
**Don'ts ❌**
* Never make the button too small for mobile tapping
* Prevent sudden layout shifts when loading new content
### Layout & Positioning
**Do's ✅**
* Put the **Load More** button at logical content breakpoints
* Loaded content appears right after existing items
* Keep the user's position in the list after loading more
**Don'ts ❌**
* Never insert new content above the user's current view unless explicitly requested
* Skip loading content off-screen without visual confirmation
## Common Mistakes & Anti-Patterns 🚫
### No Visual Feedback
**The Problem:**
Users think the button broke if nothing happens immediately after clicking.
**How to Fix It?**
Add a **spinner or loading animation** and consider disabling the button until new content fully loads.
***
### Loading Too Many Items at Once
**The Problem:**
Large content batches slow performance, cause layout shifts, and overwhelm users.
**How to Fix It?**
Load **smaller chunks** (10–20 items per click). Use incremental updates instead of one large data fetch.
***
### Forcing Excessive Load More Clicks
**The Problem:**
Repeated Load More clicks frustrate users and make pages feel unresponsive.
**How to Fix It?**
Try **auto-loading on scroll** after a few manual loads, or increase batch size when you detect high engagement.
***
### No End of Content Indicator
**The Problem:**
Users can't tell when they've reached the end, clicking Load More repeatedly with no result.
**How to Fix It?**
Show a "You've reached the end" message (announce via aria-live="polite") or hide the button entirely when no more data exists.
***
### Missing Keyboard Accessibility
**The Problem:**
Load More buttons that aren't focusable or don't respond to keyboard events lock out keyboard users from loading new content.
**How to Fix It?**
Use a proper, focusable element like ``. Check that `Tab` focuses it and `Enter/Space` triggers loading.
***
### Missing ARIA Updates for New Content
**The Problem:**
Screen reader users miss new items without announcements that content got added to the page.
**How to Fix It?**
Wrap your list with `role="region"` or use `aria-live="polite"`. Update the [live region](/glossary/live-regions) or add a brief "New content loaded" announcement after each batch renders.
***
### Insufficient Visual Contrast
**The Problem:**
Low-contrast Load More buttons or hard-to-see loading indicators (like small spinners on cluttered backgrounds) cause problems for low-vision users.
**How to Fix It?**
Use **high-contrast** button styles and **clear, visible** loading indicators (spinner or progress bar) that stand out from surrounding content.
## Examples
### Interactive Load More Demo
This example demonstrates:
* Loading state with spinner animation
* Smooth content insertion with fade-in effect
* Proper button state management (disabled during loading)
* Progress tracking (showing X of Y items)
* Keyboard support (Enter/Space to activate)
* Screen reader announcements for loaded content
* Automatic button removal when all content is loaded
## Micro-Interactions & Animations
### Button State Transitions
* **Effect:** Smooth transition between default, hover, loading, and disabled states
* **Timing:** 200ms ease-out for hover effects, immediate for loading state
* **Implementation:** CSS transitions on background-color, transform, and opacity
### Loading Spinner Animation
* **Effect:** Rotating spinner or pulsing dots to indicate loading
* **Timing:** 1s infinite rotation or 1.4s pulse sequence
* **Implementation:** CSS keyframe animations or SVG animations
### Content Insertion Animation
* **Effect:** New items fade in and slide up from below
* **Timing:** 300ms ease-out for each item, staggered by 50ms
* **Implementation:** CSS animations with animation-delay for stagger effect
### Progress Counter Update
* **Effect:** Number smoothly increments when new items load
* **Timing:** 500ms ease-in-out
* **Implementation:** JavaScript counter animation with requestAnimationFrame
### End of Content Feedback
* **Effect:** Button fades out and "End of content" message fades in
* **Timing:** 300ms crossfade
* **Implementation:** Opacity transition with element swap
## Tracking
Load More tracking measures how users navigate content, their preference for incremental loading versus pagination, and engagement depth. User behavior analysis optimizes when and how Load More gets implemented.
### Key Tracking Points
Load More interactions provide valuable user behavior insights. Key events to track include:
| **Event Name** | **Description** | **Why Track It?** |
| ------------------------ | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `load_more.view` | When the "Load More" button enters the [viewport](/glossary/viewport). | Determines visibility and whether users see the option to load more content. |
| `load_more.click` | When a user clicks the "Load More" button. | Measures engagement and intent to see additional content. |
| `load_more.auto_trigger` | When more content loads automatically without user action (e.g., lazy loading on scroll). | Helps compare manual clicks vs. auto-triggered loads. |
| `load_more.depth` | The number of times a user loads more content in one session. | Indicates how deep users are willing to explore. |
| `load_more.scroll_usage` | If infinite scrolling is enabled, tracks when users reach the "Load More" trigger area. | Helps compare scrolling behavior vs. button clicks. |
### Event Payload Structure
For consistent tracking, use this event format:
```json
{
"event": "load_more.click",
"properties": {
"load_more_id": "search_results",
"current_page": 1,
"next_page": 2,
"total_pages": 5
}
}
```
### Key Metrics to Analyze
After setting up tracking, these metrics provide actionable insights:
* **Load More Click Rate** → Percentage of users who click the "Load More" button.
* **Auto-Trigger Rate** → Percentage of users who load more content automatically via scrolling (if enabled).
* **Average Load More Depth** → Number of times users load more content in a session.
* **Completion Rate** → Percentage of users who reach the final batch of content.
* **Scroll vs. Click Engagement** → If both options exist, measures user preference for scrolling vs. manually clicking "Load More."
### Insights & Optimization Based on Tracking
Tracking data analysis optimizes the Load More experience:
* 🚨 **Low Load More Click Rate?**
→ Users don't notice the button or find it unnecessary.
**Fix:** Improve visibility, adjust styling, or test auto-loading on scroll.
* ⏳ **High Auto-Trigger Rate?**
→ Users rely on automatic loading instead of clicking.
**Fix:** Consider replacing Load More with infinite scrolling or add a "Show More" summary before triggering content.
* 🔄 **Low Average Load More Depth?**
→ Users stop after one or two loads.
**Fix:** Make the first few results engaging enough to encourage further exploration.
* 🔁 **Low Completion Rate?**
→ Users rarely reach the final batch.
**Fix:** Try smaller content chunks per load or add preview indicators ("Showing 20 of 100 results").
* ⚙️ **High Scroll vs. Click Engagement?**
→ Users prefer scrolling over clicking.
**Fix:** Consider switching to infinite scrolling but maintain good performance and usability.
Continuous monitoring of these metrics refines the Load More pattern, helping users navigate content without unnecessary friction.
## Localization
```json
{
"load_more": {
"button_text": {
"default": "Load More",
"with_count": "Load {count} More Items",
"loading": "Loading..."
},
"progress": {
"showing": "Showing {current} of {total} items",
"all_loaded": "All items loaded",
"end_message": "You've reached the end"
},
"errors": {
"load_failed": "Failed to load items. Please try again.",
"network_error": "Check your connection and try again"
},
"announcements": {
"items_loaded": "{count} new items loaded",
"loading_started": "Loading more items",
"no_more_items": "No more items to load"
}
}
}
```
## Code Examples
### Basic Load More Implementation
```html
Load More
Showing 10 of 50 items
```
### Load More with Intersection Observer
```javascript
// Auto-load when button is near viewport
const loadMoreBtn = document.querySelector('.load-more-btn');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && !isLoading) {
// Trigger load when button is 200px from viewport
loadMoreContent();
}
});
}, {
rootMargin: '200px'
});
observer.observe(loadMoreBtn);
```
## Accessibility
### ARIA Attributes
**Required ARIA attributes:**
* Use `aria-controls` to associate the **Load More** button with the content being updated.
* Announce loading states with `aria-live="polite"`.
* If the button is removed after loading all content, update its `aria-label` to indicate that no more content is available.
### Screen Reader Support
**Implementation considerations:**
* Users should be informed when new content is added.
* Ensure proper tab focus order when new items appear.
* Use accessible button elements (`` instead of `` or `
`).
## Testing Guidelines
### Functional Testing
**Should ✓**
* Verify that the **Load More** button successfully loads additional content when clicked.
* Ensure **smooth transitions** and that new content is **visually distinct** without disrupting the layout.
* Test **multiple clicks on the button** to confirm continuous content retrieval works as expected.
* Ensure the button **disables or disappears** when all content has been loaded.
* Validate that clicking **Load More** does not cause a page refresh or unexpected navigation.
* Confirm that the **user remains in the same scroll position** after loading more content.
* Ensure newly loaded content appears **sequentially** in the correct order.
* Check for **error handling**—simulate network failures to confirm users receive an appropriate message.
***
### Accessibility Testing
**Should ✓**
* Verify that the **Load More** button is fully keyboard accessible\*\* (`Tab` to navigate, `Enter` to activate).
* Ensure that new content is **announced to screen readers** using `aria-live="polite"`.
* Validate that **focus moves to the newly loaded content** rather than back to the button.
* Check that the button has **proper contrast** and is easily readable.
* Confirm that screen readers announce when **no more content is available** after the last load.
* Ensure that `aria-controls` links the button to the dynamically updated content.
* Verify that users can **navigate through the loaded content** using standard keyboard interactions.
***
### Performance Testing
**Should ✓**
* Ensure that **each content load request is optimized** to avoid unnecessary data retrieval.
* Check that **lazy-loading techniques** prevent excessive memory usage.
* Test with **large datasets** to confirm that performance remains smooth.
* Validate that **content loading does not block interactions** with other page elements.
* Measure **network requests and response times** to ensure efficient API calls.
* Check that **animations and transitions** remain smooth without jank.
* Verify that **multiple Load More interactions do not degrade performance** over time.
***
### SEO Considerations Testing
**Should ✓**
* Confirm that dynamically loaded content is **indexable by search engines** (e.g., using server-side rendering or progressive enhancement).
* Check that search engines can **crawl and discover** all content, even if JavaScript is disabled.
* Ensure that **important content is not hidden behind JavaScript-only interactions**.
* Run Lighthouse or Google's Mobile-Friendly Test to ensure SEO best practices are met.
* Test the page with JavaScript disabled to confirm that at least some content remains visible.
***
### User Experience Testing
**Should ✓**
* Observe user behavior to determine if the **Load More button is easily discoverable**.
* Ensure that the button **clearly communicates** its function (e.g., "Load More" vs. "Show More Results").
* Test on **mobile devices** to verify tap targets are large enough.
* Confirm that **loading indicators** provide clear feedback during content retrieval.
* Ensure that **content loads fast enough** to avoid user frustration.
* Validate that **users do not get lost** when additional content is inserted.
***
### Edge Case Testing
**Should ✓**
* Simulate a **slow network connection** to test how loading delays affect usability.
* Check behavior when **no more content is available**—the button should be removed or updated.
* Verify how the component behaves if the **API fails** or returns an error.
* Test **rapid multiple clicks** on the button to ensure proper request handling.
* Ensure **back navigation retains loaded content**, preventing users from losing progress.
* Confirm the **component adapts to different screen sizes and orientations**.
## Usability Testing Insights
Based on usability studies, users expect:
* **Clear progress indication** - Users want to know how much content remains
* **Consistent batch sizes** - Loading 10 items then 50 items confuses users
* **Preserved scroll position** - Page shouldn't jump when new content loads
* **Quick loading times** - Users abandon if loading takes > 3 seconds
* **End-of-content clarity** - Users repeatedly click when the end isn't clear
## Browser Support
## Performance Metrics
**Target Metrics:**
* **Initial button render**: \< 50ms after page load
* **Loading state feedback**: \< 100ms after click (immediate visual response)
* **Content fetch time**: 200-500ms for typical batch (10-20 items)
* **DOM update after fetch**: \< 100ms for smooth insertion
* **Total time to new content visible**: \< 600ms ideal, \< 1000ms acceptable
**Memory Considerations:**
* **Items per batch**: 10-20 items optimal (balance between requests and memory)
* **DOM nodes**: Monitor total count, consider virtualization after 100+ items
* **Image lazy loading**: Load images only when approaching [viewport](/glossary/viewport)
* **Previous content**: Keep in DOM for scroll position preservation
**Network Optimization:**
* **Prefetch next batch**: Start loading when user is 80% through current content
* **Request debouncing**: Prevent multiple simultaneous requests
* **Caching strategy**: Cache loaded pages for back navigation
* **Compression**: Enable gzip/brotli for API responses
**Animation Performance:**
* **Use CSS transforms**: For smooth loading animations (not margins/positions)
* **Will-change property**: Apply to animated elements sparingly
* **RequestAnimationFrame**: For JavaScript-based scroll animations
* **Reduce reflows**: Batch DOM updates, avoid layout thrashing
## SEO Considerations
* Ensure content loaded via **Load More** is indexable by search engines.
* Use progressive enhancement to allow content visibility even if JavaScript is disabled.
* Provide a paginated alternative if necessary for deep content navigation.
* Ensure that dynamically loaded content is **crawlable by search engines** by using progressive enhancement techniques or **server-side rendering**.
* If SEO visibility is a priority, consider **implementing paginated URLs** as a fallback to allow search engines to index all content properly.
## [Design Tokens](/glossary/design-tokens)
These [design tokens](/glossary/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.
### Load More Tokens in DTF Format
```json
{
"$schema": "https://design-tokens.org/schema.json",
"loadMore": {
"button": {
"background": {
"default": { "value": "{color.primary.600}", "type": "color" },
"hover": { "value": "{color.primary.700}", "type": "color" },
"active": { "value": "{color.primary.800}", "type": "color" },
"disabled": { "value": "{color.gray.300}", "type": "color" }
},
"text": {
"default": { "value": "{color.white}", "type": "color" },
"disabled": { "value": "{color.gray.500}", "type": "color" }
},
"padding": {
"vertical": { "value": "0.75rem", "type": "dimension" },
"horizontal": { "value": "1.5rem", "type": "dimension" }
},
"fontSize": { "value": "{typography.size.base}", "type": "fontSizes" },
"fontWeight": { "value": "{typography.weight.medium}", "type": "fontWeights" },
"borderRadius": { "value": "{radius.md}", "type": "dimension" },
"minWidth": { "value": "7.5rem", "type": "dimension" },
"minHeight": {
"value": "2.75rem",
"type": "dimension",
"description": "44px minimum [touch target](/glossary/touch-targets) for WCAG compliance"
}
},
"spinner": {
"size": { "value": "1.25rem", "type": "dimension" },
"color": { "value": "{color.primary.600}", "type": "color" },
"animationDuration": { "value": "1s", "type": "duration" }
},
"content": {
"gap": { "value": "1rem", "type": "dimension" },
"itemAnimation": {
"duration": { "value": "300ms", "type": "duration" },
"staggerDelay": { "value": "50ms", "type": "duration" },
"slideDistance": { "value": "1.25rem", "type": "dimension" }
}
},
"progress": {
"fontSize": { "value": "{typography.size.sm}", "type": "fontSizes" },
"color": { "value": "{color.gray.600}", "type": "color" },
"margin": { "value": "1rem", "type": "dimension" }
},
"container": {
"marginTop": { "value": "2rem", "type": "dimension" },
"marginBottom": { "value": "2rem", "type": "dimension" }
}
}
}
```
## FAQ
## Related Patterns
## Resources
### Libraries & Frameworks
#### React Components
* [React Infinite Scroll Component](https://github.com/ankeetmaini/react-infinite-scroll-component) – Infinite scroll with "Load More" support
* [React Waypoint](https://github.com/civiccc/react-waypoint) – Trigger functions when scrolling to an element
* [React Query](https://tanstack.com/query/latest) – Data fetching with pagination support
* [SWR](https://swr.vercel.app/) – Data fetching with infinite loading patterns
#### Vue Components
* [Vue Infinite Loading](https://github.com/PeachScript/vue-infinite-loading) – Infinite scroll plugin with "Load More" button option
* [Vue Load More](https://github.com/Akryum/vue-observe-visibility) – Detect when element becomes visible
#### Vanilla JavaScript
* [Infinite Scroll](https://infinite-scroll.com/) – JavaScript plugin by Metafizzy
* [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) – Native browser API for detecting visibility
### Design Systems
* [Material Design - Progress & Activity](https://m3.material.io/components/progress-indicators/overview) - Loading patterns guidance
* [Carbon Design System - Loading](https://carbondesignsystem.com/patterns/loading-pattern/) - IBM's loading patterns
### Articles & Guides
* [Load More vs Pagination vs Infinite Scroll](https://www.nngroup.com/articles/infinite-scrolling-tips/) - Nielsen Norman Group analysis
* [Performance Best Practices for Load More](https://web.dev/patterns/web-vitals-patterns/infinite-scroll/) - Web.dev performance guide
### Tools & Testing
* [WAVE](https://wave.webaim.org/) - Test load more accessibility
* [Lighthouse](https://developers.google.com/web/tools/lighthouse) - Performance testing for lazy loading
* [PageSpeed Insights](https://pagespeed.web.dev/) - Analyze load more performance impact
# UX Patterns for Devs: Megamenu
URL: /patterns/navigation/megamenu
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/megamenu.mdx
Build accessible and responsive megamenus with keyboard navigation and mobile-friendly adaptations.
***
title: "Megamenu"
summary: "Display a large number of links in a single menu"
description: "Build accessible and responsive megamenus with keyboard navigation and mobile-friendly adaptations."
icon: Grid3x3
-------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Navigation Menu
URL: /patterns/navigation/navigation-menu
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/navigation-menu.mdx
Build effective navigation menus for your website. Learn best practices for creating accessible, responsive navigation with proper keyboard support and mobile-friendly interactions.
***
title: "Navigation Menu"
summary: "Organize and structure site navigation"
description: "Build effective navigation menus for your website. Learn best practices for creating accessible, responsive navigation with proper keyboard support and mobile-friendly interactions."
icon: LayoutDashboard
---------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Pagination
URL: /patterns/navigation/pagination
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/pagination.mdx
Learn best practices for building accessible, user-friendly page navigation with clear guidelines for design and performance.
***
title: "Pagination"
summary: "Navigate through multiple pages of content"
description: "Learn best practices for building accessible, user-friendly page navigation with clear guidelines for design and performance."
icon: Route
ogImage: /covers/patterns/pagination.png
status: complete
----------------
import { Playground } from "@/components/playground";
import { StepsPagination } from "@/components/seo/steps-pagination.tsx";
import { GuidesBanner } from "@/components/guides-banner";
## Overview
**[Pagination](/glossary/pagination)** divides large content collections into manageable chunks or pages.
Users navigate through data sets, search results, or product listings without getting overwhelmed by too much information at once.
Pagination works well, but consider alternatives like [infinite scroll](/patterns/navigation/infinite-scroll) or ["Load More"](/patterns/navigation/load-more) buttons for certain content types. Your choice between pagination and infinite scroll depends on content nature, user behavior, and interface goals.
## Use Cases
### When to use:
Use pagination when content needs structured, progressive loading for smoother user experience and better performance.
Pagination helps users navigate large information sets without getting overwhelmed.
**Common scenarios include:**
* **Content lists** need browsing (search results, blog archives, product listings)
* **Page performance** improves by loading smaller content segments
* **User clarity** increases when large data sets become easier to navigate
* **Sequential content** requires navigation (multi-page tutorials or articles)
### When not to use:
* All content fits better on a single page (short lists or summaries)
* [Infinite scroll](/patterns/navigation/infinite-scroll) or ["load more"](/patterns/navigation/load-more) patterns suit the experience better
* Users need continuous comparison between items on different pages
## Benefits
* Page loads faster by limiting content loaded at once
* Users stay oriented within large datasets
* Clear navigation cues guide through content
* Performance improves and server load drops
* Bookmarking and sharing specific pages becomes easier
* Users understand content scope (total pages/items)
* Goal-oriented tasks work better than with infinite scroll
## Drawbacks
* **Interrupts user flow** – Users must click to navigate instead of scrolling continuously
* **Complex navigation** – Must handle "Previous," "Next," first, and last page controls
* **Mobile challenges** – Small pagination buttons are hard to tap on touchscreens
* **SEO risks** – Poor implementation creates duplicate content issues
* **Reload delays** – Full-page reloads slow the experience without dynamic updates
## Anatomy
```mermaid
flowchart TB
subgraph Pagination[Pagination Component]
A[Pagination Container] --> B[First Page Button - Optional]
A --> C[Previous Button]
A --> D[Pagination Items]
A --> E[Ellipsis - Optional]
A --> F[Next Button]
A --> G[Last Page Button - Optional]
end
```
### Component Structure
1. **Container**
* Wraps all pagination controls
* Manages layout and spacing
* Handles ARIA labeling and keyboard navigation
2. **Previous Button**
* Navigates to the preceding page
* Disabled on first page to show no previous content exists
3. **Pagination Items**
* Numbered buttons or links for each page
* Current page shows clearly (visual cues and ARIA attributes)
* Ellipsis ("…") appears for large page ranges
4. **Next Button**
* Navigates to the next page
* Disabled on last page to prevent further navigation
5. **First & Last Page Buttons (Optional)**
* Quick jumps to **first** and **last** pages
* Helpful for **long pagination ranges**
6. **Ellipsis (Optional)**
* Shows missing page numbers in large paginations
* Reduces clutter, keeps navigation clear
7. **Visual States**
* **Default:** Normal state with clear labels and clickable elements.
* **Hover and Focus:** Provides visual cues (underline, background change, or border) for interactive elements.
* **Active:** Indicates the currently selected page.
* **Disabled:** Non-interactive controls (e.g., previous on page 1, next on last page).
* **Keyboard Focus:** Ensures proper highlight states for accessibility.
* **ARIA Live Updates:** Announces page changes for screen readers.
* **Loading Indicators (Optional):** Shows progress when paginated content is being fetched asynchronously.
#### Summary of Components
| Component | Required? | Purpose |
| ----------------------- | --------- | ------------------------------------------------ |
| Container | ✅ Yes | Wraps the pagination controls. |
| Next/Previous Buttons | ✅ Yes | Allows users to navigate between pages. |
| Page List | ✅ Yes | Contains the list of page numbers. |
| Page Item | ✅ Yes | Represents each individual page link. |
| First/Last Page Buttons | ❌ No | Enables quick navigation to the first/last page. |
| Ellipsis | ❌ No | Represents omitted pages in large paginations. |
| Loading Indicator | ❌ No | Displays when fetching new paginated content. |
## Variations
### 1. Standard Pagination
The classic numbered page navigation with Previous/Next buttons.
**When to use:** General content lists, search results, tables
### 2. Infinite Pagination
Combines pagination with infinite scroll - loads new pages automatically but maintains page boundaries.
**When to use:** Social feeds, image galleries where users want continuous browsing
### 3. Load More Pagination
Shows a "Load More" button instead of page numbers, appending content to the current view.
**When to use:** Mobile interfaces, casual browsing experiences
### 4. Simple Previous/Next
Only shows Previous and Next buttons without page numbers.
**When to use:** Linear content like tutorials, wizards, or articles
### 5. Alphabetical/Range Pagination
Groups content by alphabetical ranges (A-C, D-F) or other categories.
**When to use:** Directories, glossaries, large catalogs
### 6. Mini Pagination
Compact version showing limited page numbers (e.g., 1...5, 6, 7...20).
**When to use:** Limited space, mobile views, secondary navigation
### 7. Hybrid Pagination
Combines page numbers with a dropdown to jump to any page.
**When to use:** Large datasets where users need both sequential and random access
## Examples
### Basic Pagination
This example demonstrates:
* Page number navigation with Previous/Next buttons
* Current page highlighting
* Disabled states for first/last pages
* Keyboard navigation support
* ARIA labels for accessibility
* Responsive design for mobile
* Smooth transitions between pages
### Basic Implementation
```html
```
## Best Practices
### Content
**Do's ✅**
* Pick clear, concise labels for navigation controls
* Give context ("Page 5 of 20")
* Use ellipsis (...) for large page ranges
* Check if pagination or infinite scroll fits your use case and content type better
* Display loading indicators when fetching new content
* Update URLs to reflect current page numbers
**Don'ts ❌**
* Skip cluttering the interface with excessive pagination controls
* Never paginate short lists that fit on one page
* Avoid ambiguous labels that confuse users
* Stop loading unnecessary data or assets irrelevant to the current page
### Accessibility
**Do's ✅**
* Wrap pagination controls with semantic `` element
* Add `aria-label="Pagination"` or similar for screen readers
* Make each page link focusable with clear labels
* Set logical keyboard navigation order (Tab, Enter, Arrow keys)
* Mark current page with `aria-current="page"`
* Auto-scroll to top of content area when loading new pages (use smooth scrolling to avoid jarring jumps)
* Move focus to main content or first item after loading
* Announce loading status and page changes with ARIA [live regions](/glossary/live-regions) (e.g., Loading page 3…
) for screen readers
* Include "Skip to content" link that shows on focus for keyboard users
**Don'ts ❌**
* Never rely only on color for current page; add text or icons too
* Skip complex pagination structures that confuse keyboard and assistive tech users
* Always change scroll position when loading new page content
* Don't set focus to pagination controls after page load – it disorients users
### Visual Design
**Do's ✅**
* Keep spacing, typography, and colors consistent for clarity
* Separate pagination items visually
* Make active state stand out
* Add subtle hover animations to signal interactivity
* Design for scale with many pages (abbreviate: 1k, 2k for 1000, 2000)
* Build efficient server-side pagination to cut load times
* Apply smooth scrolling when auto-moving to new content top
**Don'ts ❌**
* Never make interactive elements too small for mobile tapping
* Skip decorative styles that hurt content readability
* Avoid blocking entire page interaction during loading unless necessary
* Don't add separator elements to the DOM; render separators with CSS pseudo-elements instead
### Layout & Positioning
**Do's ✅**
* Place pagination controls logically (usually bottom of content listings)
* Maintain strong contrast between pagination controls and background
* Apply responsive design for usability across devices
* Try progressive loading for images and media
* Keep scroll position when updating only part of the page (single-page apps)
**Don'ts ❌**
* Keep pagination close to content to avoid excessive scrolling
* Skip fixed positioning that blocks content on small screens
* Preserve browser history functionality with custom pagination
## Common Mistakes & Anti-Patterns 🚫
### **No Indication of Total Pages**
**The Problem:**
Users can't gauge content size or their progress.
**How to Fix It:**
Show total page count or items ("Page 3 of 12" or "Showing 21-30 of 120 items").
### **Missing Current Page Highlight**
**The Problem:**
Users lose track of their current page, especially after scrolling.
**How to Fix It:**
Distinguish the active page with contrasting colors, borders, or size.
### **Tiny Click Targets**
**The Problem:**
Page numbers and controls are too small for easy clicking, especially on mobile.
**How to Fix It:**
Use minimum 44x44px touch targets with adequate spacing between elements.
### **No Keyboard Navigation**
**The Problem:**
Pagination works only with mouse/touch, locking out keyboard users.
**How to Fix It:**
Add full keyboard support with Tab navigation and Enter/Space activation.
### **Jumping to Top Without Warning**
**The Problem:**
Page changes trigger unexpected scroll to top, disorienting users.
**How to Fix It:**
Keep scroll position or smoothly animate to top with clear indication. Use `scroll-behavior: smooth` or JavaScript smooth scrolling, and announce page changes via ARIA live regions to inform users of the navigation change.
### **Poor Mobile Adaptation**
**The Problem:**
Desktop pagination with many page numbers fails on mobile.
**How to Fix It:**
Apply responsive design showing fewer page numbers on smaller screens.
## Micro-Interactions & Animations
Pagination needs these specific, purpose-driven animations:
* **Button Hover Animation:**
* **Effect:** Scale button to 1.05× on hover and smoothly transition background color
* **Timing:** 200ms ease transition for responsive feel without delay
* **Focus State Animation:**
* **Effect:** Button focus (keyboard or pointer) animates clear visual indicator—crisp outline or subtle drop-shadow for active state
* **Timing:** 200ms effect creates smooth visual cue
* **Active (Click) Animation:**
* **Effect:** Clicking triggers brief confirmation animation (quick pulse or scale to 1.1×) signaling selection
* **Timing:** 150–200ms completion gives immediate feedback without interrupting flow
* **Content Transition (When Applicable):**
* **Effect:** Pagination triggering content updates (common in SPAs) uses fade transition—outgoing fades out, incoming fades in
* **Timing:** 250ms opacity transition ensures smooth change without distraction
* **Reduced Motion Consideration:**
* **Implementation:** Check user motion preferences (`prefers-reduced-motion` media query) and disable or minimize animations for accessibility
These animations give just enough feedback to guide interactions and enhance pagination feel without overwhelming the interface.
## Tracking
Pagination tracking measures how users navigate content, their preference for sequential clicking versus skipping ahead, and whether they reach deeper pages. Analyzing pagination behavior optimizes user experience and improves content discoverability.
### Key Tracking Points
Pagination interactions provide valuable user behavior insights. Key events to track:
| **Event Name** | **Description** | **Why Track It?** |
| --------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `pagination.view` | When the pagination component enters the [viewport](/glossary/viewport). | Determines visibility and whether pagination is available to users. |
| `pagination.next_click` | When a user clicks the **next page** button. | Measures sequential navigation behavior. |
| `pagination.prev_click` | When a user clicks the **previous page** button. | Tracks backward navigation trends. |
| `pagination.page_click` | When a user clicks a specific numbered page. | Helps assess whether users jump ahead instead of clicking next. |
| `pagination.first_click` | When a user clicks the first page button (if available). | Measures how often users return to the beginning. |
| `pagination.last_click` | When a user clicks the last page button (if available). | Indicates if users want to skip directly to the end. |
| `pagination.page_load` | When a new paginated page loads (via user interaction or auto-pagination). | Helps measure engagement depth. |
| `pagination.scroll_trigger` | If infinite scrolling is enabled, tracks when users reach a pagination trigger (e.g., "Load More" button). | Helps compare pagination click interactions vs. scrolling behavior. |
### Common Payload Contract
All pagination events should include these core properties for consistent analysis:
```json
{
"component_id": "search_results",
"current_page": 3,
"total_pages": 10
}
```
### Event Payload Structure
For consistent tracking, use this event format:
```json
{
"event": "pagination.page_click",
"properties": {
"pagination_id": "search_results",
"clicked_page": 4,
"total_pages": 10,
"interaction_type": "click"
}
}
```
### Key Metrics to Analyze
After setting up tracking, these metrics provide actionable insights:
* **Next Page Click Rate** → Percentage of users who click the "Next" button.
* **Page Jump Rate** → Percentage of users who select a specific page instead of clicking "Next."
* **Backward Navigation Rate** → Percentage of users who click "Previous" or navigate back to earlier pages.
* **Deep Pagination Engagement** → How far users go into paginated content (e.g., do they go past page 3?).
* **First vs. Last Page Access Rate** → How often users jump to the first or last page.
* **Infinite Scroll vs. Pagination Click Rate** → If both options exist, measures preference for clicking pagination vs. scrolling to load more.
### Insights & Optimization Based on Tracking
Tracking data analysis optimizes the pagination experience:
* 🚨 **Low Next Page Click Rate?**
→ Users don't find pagination useful or engaging.
**Fix:** Improve results per page, strengthen visual cues, or test infinite scrolling.
* ⏳ **High Page Jump Rate?**
→ Users prefer skipping ahead over sequential navigation.
**Fix:** Add better filtering options or let users select results per page.
* 🔄 **Frequent Backward Navigation?**
→ Users miss important content on previous pages.
**Fix:** Improve sorting and relevance on earlier pages.
* 🔁 **Low Deep Pagination Engagement?**
→ Users rarely go past the first few pages.
**Fix:** Don't bury important content deep or test loading more items per page.
* ⚙️ **High Infinite Scroll Usage vs. Clicks?**
→ Users prefer scrolling over clicking pagination.
**Fix:** Test infinite scrolling as default but check performance and usability impact.
Continuous monitoring of these metrics refines pagination usability, helping users navigate content without frustration.
## Localization
```json
{
"pagination": {
"next_page": {
"label": "Next",
"aria_label": "Go to the next page"
},
"previous_page": {
"label": "Previous",
"aria_label": "Go to the previous page"
},
"page_number": {
"aria_label": "Page {page_number}"
},
"first_page": {
"label": "First",
"aria_label": "Go to the first page"
},
"last_page": {
"label": "Last",
"aria_label": "Go to the last page"
}
}
}
```
## Accessibility
### ARIA Attributes
**Required [ARIA Attributes](/glossary/aria-attributes):**
* The container should use role="navigation" with an appropriate aria-label (e.g., "Pagination Navigation").
* Each pagination item should include aria-labels indicating the respective page number.
* Indicate the current page using aria-current="page".
### Keyboard Interaction Pattern
The following table outlines the standard keyboard interactions for pagination components:
| Key | Action |
| ----------- | -------------------------------------------------------- |
| Tab | Navigate among pagination controls and page buttons |
| Enter/Space | Activate the focused pagination button |
| Arrow Keys | Optionally, navigate between page items (if implemented) |
## Testing Guidelines
### Functional Testing
**Should ✓**
* [ ] Verify that the pagination controls render correctly.
* [ ] Ensure clicking the Previous and Next buttons navigates to the correct pages.
* [ ] Test that the active state updates when navigating through pages.
* [ ] Confirm that disabled states (on the first or last page) are correctly implemented.
### Accessibility Testing
**Should ✓**
* [ ] Validate that the pagination container has role="navigation" and an appropriate aria-label.
* [ ] Confirm each pagination item is focusable and properly labeled.
* [ ] Ensure keyboard navigation works seamlessly with the pagination controls.
* [ ] Test that screen readers correctly announce the current page.
### Visual Testing
**Should ✓**
* [ ] Confirm that pagination controls adapt gracefully to different screen sizes.
* [ ] Verify that active and hover states are visually distinct.
* [ ] Check that pagination does not overlap or interfere with other page elements.
### Performance Testing
**Should ✓**
* [ ] Ensure that pagination does not cause significant loading delays.
* [ ] Validate that new page content loads efficiently when navigating.
## Browser Support
## Performance Metrics
### Target Metrics
**Response Times:**
* **Page change initiation:** \< 100ms after click
* **Content load start:** \< 200ms
* **Full page render:** \< 1000ms (ideal), \< 2000ms (acceptable)
* **Animation duration:** 200-300ms for transitions
**Data Loading:**
* **Prefetch strategy:** Load adjacent pages in background
* **Cache duration:** 5 minutes for recently viewed pages
* **Request size:** \< 50KB per page of data
* **Concurrent requests:** Maximum 2 prefetch requests
**Rendering Performance:**
* **First Contentful Paint:** \< 500ms
* **Cumulative Layout Shift (CLS):** [CLS](/glossary/cls-cumulative-layout-shift) \< 0.1
* **Time to Interactive:** \< 1500ms
* **Frame rate:** 60fps during animations
**Mobile Optimization:**
* **Touch response:** \< 100ms feedback
* **Bandwidth usage:** Minimize with compression
* **Battery impact:** Avoid continuous animations
* **Memory footprint:** \< 10MB for pagination component
## SEO Considerations
* Use [semantic HTML](/glossary/semantic-html) (e.g., `` and lists) to help search engines understand your site structure.
* Ensure that pagination links are crawlable, improving site indexing.
* Consider implementing [progressive loading](/glossary/progressive-loading) for better performance and user experience.
* Use unique URL parameters for each page (e.g., `/products?page=2`)
* Implement rel="prev" and rel="next" link tags for search engines
* Avoid duplicate content issues with proper [canonical tags](/glossary/canonical-tags)
## Design Tokens
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.
### Pagination Tokens in DTF Format
```json
{
"$schema": "https://design-tokens.org/schema.json",
"pagination": {
"container": {
"padding": { "value": "1rem", "type": "dimension" },
"background": { "value": "{color.white}", "type": "color" }
},
"item": {
"size": { "value": "2rem", "type": "dimension" },
"fontSize": { "value": "1rem", "type": "fontSize" },
"color": { "value": "{color.text}", "type": "color" },
"activeColor": { "value": "{color.primary}", "type": "color" }
},
"button": {
"padding": { "value": "0.5rem 1rem", "type": "dimension" },
"borderRadius": { "value": "0.25rem", "type": "dimension" }
}
}
}
```
## FAQ
), ensure touch targets are at least 44x44px, and consider 'Load More' as an alternative for better mobile experience.",
},
]}
/>
## Related Patterns
## Resources
### Libraries & Frameworks
#### React Components
* [React Paginate](https://github.com/AdeleD/react-paginate) – A ReactJS component to render a pagination
* [RC Pagination](https://github.com/react-component/pagination) – React pagination component
* [Ant Design Pagination](https://ant.design/components/pagination) – Enterprise-class pagination component
#### Vue Components
* [Vue Pagination 2](https://github.com/matfish2/vue-pagination-2) – Vue.js 2 pagination component
* [Vuetify Pagination](https://vuetifyjs.com/en/components/paginations/) – Material Design pagination component
#### Vanilla JavaScript
* [Pagination.js](http://pagination.js.org/) – A jQuery plugin for pagination
* [SimplePagination.js](https://flaviusmatis.github.io/simplePagination.js) – Simple and lightweight pagination plugin
### Articles
* [Pagination Design Pattern](https://www.nngroup.com/articles/pagination/)
### Implementation Guides
* [React Pagination Tutorial](https://www.digitalocean.com/community/tutorials/how-to-build-custom-pagination-with-react)
* [Vue.js Pagination Component](https://vuejs.org/examples/#grid-component)
* [Accessible Pagination with ARIA](https://a11y-style-guide.com/style-guide/section-navigation.html#kssref-navigation-pagination)
# UX Patterns for Devs: Sidebar
URL: /patterns/navigation/sidebar
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/sidebar.mdx
Build responsive and accessible sidebar navigation with collapsible sections and keyboard navigation support.
***
title: "Sidebar"
summary: "Organize and structure site navigation"
description: "Build responsive and accessible sidebar navigation with collapsible sections and keyboard navigation support."
icon: PanelLeft
---------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Tabs
URL: /patterns/navigation/tabs
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/navigation/tabs.mdx
Create accessible tab interfaces with keyboard navigation, ARIA attributes, and responsive design patterns.
***
title: "Tabs"
summary: "Switch between different views"
description: "Create accessible tab interfaces with keyboard navigation, ARIA attributes, and responsive design patterns."
icon: LayoutGrid
----------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Checkout Flow
URL: /patterns/e-commerce/checkout
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/e-commerce/checkout.mdx
Learn how to implement checkout flows. Discover best practices for payment forms, order review, and conversion optimization.
***
title: "Checkout Flow"
summary: "Multi-step checkout process"
description: "Learn how to implement checkout flows. Discover best practices for payment forms, order review, and conversion optimization."
icon: CreditCard
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Cart review: [Shopping Cart](/patterns/e-commerce/shopping-cart)
* Payment forms: [Form Validation](/patterns/forms/form-validation)
* Progress tracking: [Progress Indicator](/patterns/user-feedback/progress-indicator)
# UX Patterns for Devs: Product Card
URL: /patterns/e-commerce/product-card
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/e-commerce/product-card.mdx
Learn how to implement effective product cards. Discover best practices for product images, pricing display, and quick actions.
***
title: "Product Card"
summary: "Product display cards for e-commerce"
description: "Learn how to implement effective product cards. Discover best practices for product images, pricing display, and quick actions."
icon: Package
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Product grids: [Card Grid](/patterns/data-display/card-grid)
* Cart management: [Shopping Cart](/patterns/e-commerce/shopping-cart)
* Image display: [Carousel](/patterns/content-management/carousel)
# UX Patterns for Devs: Shopping Cart
URL: /patterns/e-commerce/shopping-cart
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/e-commerce/shopping-cart.mdx
Learn how to implement shopping cart functionality. Discover best practices for cart management, item updates, and persistent storage.
***
title: "Shopping Cart"
summary: "Shopping cart and item management"
description: "Learn how to implement shopping cart functionality. Discover best practices for cart management, item updates, and persistent storage."
icon: ShoppingCart
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Product display: [Product Card](/patterns/e-commerce/product-card)
* Next step: [Checkout Flow](/patterns/e-commerce/checkout)
* Quantity selection: [Number Input](/patterns/forms/text-field)
# UX Patterns for Devs: Cookie Consent
URL: /patterns/user-feedback/cookie-consent
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/user-feedback/cookie-consent.mdx
Implement effective cookie consent banners in your web applications. Learn best practices for GDPR compliance, user privacy, and consent management.
***
title: "Cookie Consent"
summary: "Inform users about the use of cookies"
description: "Implement effective cookie consent banners in your web applications. Learn best practices for GDPR compliance, user privacy, and consent management."
icon: Cookie
------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Empty States
URL: /patterns/user-feedback/empty-states
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/user-feedback/empty-states.mdx
Create effective empty state experiences in your web applications. Learn best practices for handling no-content scenarios with helpful messaging and clear actions.
***
title: "Empty States"
summary: "Guide users when no content is available"
description: "Create effective empty state experiences in your web applications. Learn best practices for handling no-content scenarios with helpful messaging and clear actions."
icon: CircleAlert
-----------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Loading Indicator
URL: /patterns/user-feedback/loading-indicator
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/user-feedback/loading-indicator.mdx
Build effective loading indicators for your web applications. Learn best practices for implementing loading states, spinners, and progress feedback with proper accessibility.
***
title: "Loading Indicator"
summary: "Show users that content is being loaded"
description: "Build effective loading indicators for your web applications. Learn best practices for implementing loading states, spinners, and progress feedback with proper accessibility."
icon: Loader
------------
This page is a work in progress. Don't consider it complete yet.
***(Also called loader, loading, spinner)***
Not to be confused with [progress indicator](/patterns/user-feedback/progress-indicator).
## Overview
A **loading indicator** is a visual cue that indicates that a task is in progress.
# UX Patterns for Devs: Notification
URL: /patterns/user-feedback/notification
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/user-feedback/notification.mdx
Implement effective notification systems in your web applications. Learn best practices for toast messages, alerts, and user notifications with proper timing and accessibility.
***
title: "Notification"
summary: "Inform users about important updates"
description: "Implement effective notification systems in your web applications. Learn best practices for toast messages, alerts, and user notifications with proper timing and accessibility."
icon: Bell
----------
This page is a work in progress. Don't consider it complete yet.
***(Also called toast)***
## Overview
## Usage
* To inform the user about a change in the application
* To alert the user about an error or warning
# UX Patterns for Devs: Progress Indicator
URL: /patterns/user-feedback/progress-indicator
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/user-feedback/progress-indicator.mdx
Create effective progress indicators for your web applications. Learn best practices for implementing progress bars, step indicators, and completion feedback with proper accessibility.
***
title: "Progress Indicator"
summary: "Show completion status of an operation"
description: "Create effective progress indicators for your web applications. Learn best practices for implementing progress bars, step indicators, and completion feedback with proper accessibility."
icon: Gauge
-----------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
Not to be confused with [loading indicator](/patterns/user-feedback/loading-indicator).
# UX Patterns for Devs: Skeleton
URL: /patterns/user-feedback/skeleton
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/user-feedback/skeleton.mdx
Build effective skeleton loading states for your web applications. Learn best practices for implementing content placeholders and loading animations with proper accessibility.
***
title: "Skeleton"
summary: "Show users that content is being loaded"
description: "Build effective skeleton loading states for your web applications. Learn best practices for implementing content placeholders and loading animations with proper accessibility."
icon: LoaderCircle
------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
# UX Patterns for Devs: Activity Feed
URL: /patterns/social/activity-feed
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/social/activity-feed.mdx
Learn how to implement activity feeds. Discover best practices for real-time updates, infinite scrolling, and engagement tracking.
***
title: "Activity Feed"
summary: "Social activity and updates stream"
description: "Learn how to implement activity feeds. Discover best practices for real-time updates, infinite scrolling, and engagement tracking."
icon: Activity
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Timeline view: [Timeline](/patterns/data-display/timeline)
* Loading more: [Infinite Scroll](/patterns/navigation/infinite-scroll)
* User interactions: [Comment System](/patterns/social/comment-system)
# UX Patterns for Devs: Comment System
URL: /patterns/social/comment-system
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/social/comment-system.mdx
Learn how to implement comment systems. Discover best practices for threaded discussions, moderation, and user interactions.
***
title: "Comment System"
summary: "User comments and discussion threads"
description: "Learn how to implement comment systems. Discover best practices for threaded discussions, moderation, and user interactions."
icon: MessageSquare
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* User reactions: [Like Button](/patterns/social/like-button)
* User mentions: [Tag Input](/patterns/forms/tag-input)
* Activity updates: [Activity Feed](/patterns/social/activity-feed)
# UX Patterns for Devs: Like Button
URL: /patterns/social/like-button
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/social/like-button.mdx
Learn how to implement like buttons and reactions. Discover best practices for engagement tracking, animations, and accessibility.
***
title: "Like Button"
summary: "Like and reaction buttons"
description: "Learn how to implement like buttons and reactions. Discover best practices for engagement tracking, animations, and accessibility."
icon: Heart
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* User comments: [Comment System](/patterns/social/comment-system)
* Share actions: [Share Dialog](/patterns/social/share-dialog)
* Toggle states: [Toggle](/patterns/forms/toggle)
# UX Patterns for Devs: Share Dialog
URL: /patterns/social/share-dialog
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/social/share-dialog.mdx
Learn how to implement share dialogs. Discover best practices for social media integration, copy links, and sharing analytics.
***
title: "Share Dialog"
summary: "Social sharing functionality"
description: "Learn how to implement share dialogs. Discover best practices for social media integration, copy links, and sharing analytics."
icon: Share2
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Modal dialogs: [Modal](/patterns/content-management/modal)
* Copy to clipboard: [Tooltip](/patterns/content-management/tooltip)
* Social engagement: [Like Button](/patterns/social/like-button)
# UX Patterns for Devs: AI Chat Interface
URL: /patterns/ai-intelligence/ai-chat
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/ai-chat.mdx
Learn how to implement AI chat interfaces. Discover best practices for message threading, context management, and conversational UX.
***
title: "AI Chat Interface"
summary: "Conversational AI chat interfaces"
description: "Learn how to implement AI chat interfaces. Discover best practices for message threading, context management, and conversational UX."
icon: Bot
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Message input: [Prompt Input](/patterns/ai-intelligence/prompt-input)
* Response display: [Streaming Response](/patterns/ai-intelligence/streaming-response)
* Chat history: [Context Window](/patterns/ai-intelligence/context-window)
# UX Patterns for Devs: AI Error States
URL: /patterns/ai-intelligence/ai-error-states
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/ai-error-states.mdx
Learn how to implement AI error states. Discover best practices for rate limits, model errors, and graceful degradation.
***
title: "AI Error States"
summary: "Handling AI-specific errors"
description: "Learn how to implement AI error states. Discover best practices for rate limits, model errors, and graceful degradation."
icon: CircleAlert
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* General errors: [Notification](/patterns/user-feedback/notification)
* Empty states: [Empty States](/patterns/user-feedback/empty-states)
* Response retry: [Response Feedback](/patterns/ai-intelligence/response-feedback)
# UX Patterns for Devs: AI Loading States
URL: /patterns/ai-intelligence/ai-loading-states
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/ai-loading-states.mdx
Learn how to implement AI-specific loading states. Discover best practices for thinking animations, progress indicators, and stream initialization.
***
title: "AI Loading States"
summary: "Loading states for AI operations"
description: "Learn how to implement AI-specific loading states. Discover best practices for thinking animations, progress indicators, and stream initialization."
icon: Loader
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Basic loading: [Loading Indicator](/patterns/user-feedback/loading-indicator)
* Stream display: [Streaming Response](/patterns/ai-intelligence/streaming-response)
* Skeleton states: [Skeleton](/patterns/user-feedback/skeleton)
# UX Patterns for Devs: AI Suggestions
URL: /patterns/ai-intelligence/ai-suggestions
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/ai-suggestions.mdx
Learn how to implement AI suggestions. Discover best practices for predictive text, smart completions, and recommendation interfaces.
***
title: "AI Suggestions"
summary: "AI-powered autocomplete and suggestions"
description: "Learn how to implement AI suggestions. Discover best practices for predictive text, smart completions, and recommendation interfaces."
icon: Sparkles
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Basic autocomplete: [Autocomplete](/patterns/forms/autocomplete)
* Prompt enhancement: [Prompt Input](/patterns/ai-intelligence/prompt-input)
* Selection interface: [Selection Input](/patterns/forms/selection-input)
# UX Patterns for Devs: Context Window
URL: /patterns/ai-intelligence/context-window
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/context-window.mdx
Learn how to implement context window management. Discover best practices for conversation history, context limits, and memory management.
***
title: "Context Window"
summary: "Managing AI conversation context"
description: "Learn how to implement context window management. Discover best practices for conversation history, context limits, and memory management."
icon: Archive
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Chat interface: [AI Chat Interface](/patterns/ai-intelligence/ai-chat)
* Token limits: [Token Counter](/patterns/ai-intelligence/token-counter)
* History display: [Timeline](/patterns/data-display/timeline)
# UX Patterns for Devs: Model Selector
URL: /patterns/ai-intelligence/model-selector
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/model-selector.mdx
Learn how to implement model selectors. Discover best practices for model comparison, capability display, and settings management.
***
title: "Model Selector"
summary: "AI model selection interface"
description: "Learn how to implement model selectors. Discover best practices for model comparison, capability display, and settings management."
icon: Cpu
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Selection UI: [Selection Input](/patterns/forms/selection-input)
* Settings: [Account Settings](/patterns/authentication/account-settings)
* Comparison: [Comparison Table](/patterns/data-display/comparison-table)
# UX Patterns for Devs: Prompt Input
URL: /patterns/ai-intelligence/prompt-input
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/prompt-input.mdx
Learn how to implement prompt input interfaces. Discover best practices for multiline inputs, prompt templates, and input enhancements.
***
title: "Prompt Input"
summary: "Enhanced text inputs for AI prompts"
description: "Learn how to implement prompt input interfaces. Discover best practices for multiline inputs, prompt templates, and input enhancements."
icon: Pen
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Basic input: [Textarea](/patterns/forms/textarea)
* Token limits: [Token Counter](/patterns/ai-intelligence/token-counter)
* AI suggestions: [AI Suggestions](/patterns/ai-intelligence/ai-suggestions)
# UX Patterns for Devs: Response Feedback
URL: /patterns/ai-intelligence/response-feedback
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/response-feedback.mdx
Learn how to implement response feedback. Discover best practices for ratings, regeneration, and improvement signals.
***
title: "Response Feedback"
summary: "Feedback mechanisms for AI responses"
description: "Learn how to implement response feedback. Discover best practices for ratings, regeneration, and improvement signals."
icon: ThumbsUp
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Rating interface: [Rating Input](/patterns/forms/rating-input)
* User reactions: [Like Button](/patterns/social/like-button)
* Response display: [Streaming Response](/patterns/ai-intelligence/streaming-response)
# UX Patterns for Devs: Streaming Response
URL: /patterns/ai-intelligence/streaming-response
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/streaming-response.mdx
Learn how to implement streaming AI responses. Discover best practices for progressive rendering, markdown formatting, and stream interruption.
***
title: "Streaming Response"
summary: "Real-time AI response streaming"
description: "Learn how to implement streaming AI responses. Discover best practices for progressive rendering, markdown formatting, and stream interruption."
icon: Zap
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Loading states: [AI Loading States](/patterns/ai-intelligence/ai-loading-states)
* Response actions: [Response Feedback](/patterns/ai-intelligence/response-feedback)
* Error handling: [AI Error States](/patterns/ai-intelligence/ai-error-states)
# UX Patterns for Devs: Token Counter
URL: /patterns/ai-intelligence/token-counter
Source: https://raw.githubusercontent.com/thedaviddias/ux-patterns-for-developers/refs/heads/main/apps/web/content/patterns/ai-intelligence/token-counter.mdx
Learn how to implement token counters. Discover best practices for usage indicators, limit warnings, and cost estimation.
***
title: "Token Counter"
summary: "Display token usage and limits"
description: "Learn how to implement token counters. Discover best practices for usage indicators, limit warnings, and cost estimation."
icon: Hash
status: coming-soon
-------------------
This page is empty for now. Please help us by
[contributing](https://github.com/thedaviddias/ux-patterns-for-developers/blob/main/.github/CONTRIBUTING.md)
to add content.
## Related patterns
* Progress display: [Progress Indicator](/patterns/user-feedback/progress-indicator)
* Input limits: [Prompt Input](/patterns/ai-intelligence/prompt-input)
* Usage stats: [Statistics Display](/patterns/data-display/statistics)