Skip to content

Carousel causes horizontal page overflow in width-constrained containers #17

@JakeLin

Description

@JakeLin

The Carousel component causes horizontal page-level overflow when used inside width-constrained containers (e.g., max-width: 768px), resulting in an unwanted horizontal scrollbar.

Root Cause

The .emblaContainer class uses negative horizontal margins to implement the gap system:

.emblaContainer {
  display: flex;
  align-items: stretch;
  margin-left: calc(var(--carousel-gap, 0) / -2);   /* ← Negative margin */
  margin-right: calc(var(--carousel-gap, 0) / -2);  /* ← Negative margin */
  padding-left: var(--carousel-start-inset, 0);
}

While .emblaViewport has overflow: hidden, when the Carousel is placed in a width-constrained parent container, these negative margins push content outside the container boundaries, causing page-level horizontal overflow.

Reproduction

<div style={{ maxWidth: '768px', margin: '0 auto' }}>
  <Carousel gap="16px" align="start">
    <Card>Item 1</Card>
    <Card>Item 2</Card>
    <Card>Item 3</Card>
  </Carousel>
</div>

Result: Horizontal scrollbar appears at page level.

Current Workaround

Add overflow-x: hidden to parent containers:

.carousel-wrapper {
  overflow-x: hidden;
}

However, this requires users to know about the internal implementation detail and apply fixes at multiple container levels.

Suggested Fixes

  1. Use CSS gap property instead of negative margins:

    .emblaContainer {
      display: flex;
      gap: var(--carousel-gap, 0);
    }
  2. Add compensating padding to contain the negative margins:

    .emblaViewport {
      padding-left: calc(var(--carousel-gap, 0) / 2);
      padding-right: calc(var(--carousel-gap, 0) / 2);
    }
  3. Document the requirement that parent containers must use overflow-x: hidden

Environment

  • @ainativekit/ui version: 0.8.0
  • Browser: Chrome/Safari/Firefox (affects all)
  • Use case: ChatGPT widgets with constrained iframe widths

Expected Behavior

A self-contained component should handle its own overflow without requiring parent containers to apply overflow fixes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions