Navigation

Load More

Build efficient content loading with the Load More pattern, focusing on user experience and performance optimization.

🌟Very Popular
Example of load-more pattern

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.

Build Effort
Medium Complexity

Requires dynamic content loading, state management, accessibility considerations (keyboard navigation, `aria-live` updates), and performance optimizations. The button should be removed when all content is loaded.

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 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

Compare Alternatives

Best for: users need to jump to specific pages or see total item count

Better for SEO, Clear position indicator
More clicks required, Page reload disruption

Best for: content consumption should be seamless and continuous

No user action needed, Smooth browsing
Hard to reach footer, Can't bookmark position

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

Loading diagram...

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

ComponentRequired?Purpose
Container✅ YesWraps the content that will load more items.
Initial Content List✅ YesDisplays a limited set of items to avoid overwhelming users.
Load More Button✅ YesAllows users to manually fetch more content.
Loading Indicator❌ NoShows progress while loading more items.
Additional Content✅ YesThe dynamically inserted content after clicking "Load More."
Another Load More Button❌ NoAppears 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 technologiesaria-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 <button>. 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 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

Loading code editor...

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 NameDescriptionWhy Track It?
load_more.viewWhen the "Load More" button enters the viewport.Determines visibility and whether users see the option to load more content.
load_more.clickWhen a user clicks the "Load More" button.Measures engagement and intent to see additional content.
load_more.auto_triggerWhen more content loads automatically without user action (e.g., lazy loading on scroll).Helps compare manual clicks vs. auto-triggered loads.
load_more.depthThe number of times a user loads more content in one session.Indicates how deep users are willing to explore.
load_more.scroll_usageIf 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:

{
  "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

{
  "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

<div class="content-list" role="region" aria-label="Content items">
  <ul id="items-list">
    <!-- Initial items -->
  </ul>

  <button
    type="button"
    class="load-more-btn"
    aria-label="Load more items"
    data-loading="false"
  >
    <span class="btn-text">Load More</span>
    <span class="btn-spinner" aria-hidden="true"></span>
  </button>

  <div class="load-progress" aria-live="polite">
    Showing <span id="current-count">10</span> of <span id="total-count">50</span> items
  </div>
</div>

Load More with Intersection Observer

// 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 (<button> instead of <div> or <span>).

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

api.IntersectionObserver

Google Chrome
chrome
Since v51
Firefox
firefox
Since v55
Safari
safari
Since v12.1

css.transitions

Google Chrome
chrome
No
Firefox
firefox
No
Safari
safari
No

html.elements.button

Google Chrome
chrome
Since v1
Firefox
firefox
Since v1
Safari
safari
Since v1

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
  • 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

These design tokens follow the Design Tokens Format specification and can be used with various token transformation tools to generate platform-specific variables.

Load More Tokens in DTF Format

{
  "$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

What is the 'Load More' pattern in web design?

The 'Load More' pattern is a UI component that allows users to load additional content on demand, reducing initial page load times and improving content discoverability. It is often compared with Infinite Scroll, where content loads automatically, and Pagination, where users navigate between predefined pages.

When should I use the 'Load More' pattern?

Use the 'Load More' pattern when users need control over content loading without being overwhelmed by an excessive amount of data at once. It is ideal for media galleries, search results, and feeds where users prefer manual control rather than automatic loading like in Infinite Scroll.

How does 'Load More' compare to infinite scrolling and pagination?

'Load More' provides a middle ground between Infinite Scroll, which continuously loads content as users scroll, and Pagination, which separates content into discrete pages. 'Load More' allows users to explore additional content without navigating away from their current view.

What are the benefits of using the 'Load More' pattern?

Benefits include improved user control, better accessibility, and reduced initial page load times. Unlike Infinite Scroll, it allows users to reach the footer and navigate more easily.

What are the drawbacks of the 'Load More' pattern?

One downside is that search engines may struggle to index content hidden behind a 'Load More' button. A hybrid approach that combines 'Load More' with Pagination can sometimes be a better alternative for SEO purposes.

How can I implement the 'Load More' pattern accessibly?

Ensure the button is keyboard accessible and labeled correctly. Similar to Accordion, you should use ARIA attributes such as aria-expanded to indicate state changes when content loads.

What are some best practices for designing a 'Load More' button?

Use a clear, descriptive label such as 'Load More' or 'Show More'. Ensure the button provides immediate feedback when clicked, similar to Button components.

Resources

Libraries & Frameworks

React Components

Vue Components

Vanilla JavaScript

Design Systems

Articles & Guides

Tools & Testing

How is this guide?