# No unintended horizontal scrolling at mobile widths

- **Pattern:** `ab-001918` (`mobile-responsiveness.layout.no-horizontal-scroll`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001918
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001918)

## Why it matters

Unintended horizontal scroll breaks the fundamental contract of a mobile layout: that the viewport shows the full page width. Users on touch devices cannot easily discover off-screen content and may not realise navigation controls or call-to-action buttons are hidden to the right. WCAG 2.2 SC 1.4.10 (Reflow) requires content to reflow at 320px viewport width without horizontal scrolling; violating it is a WCAG AA failure that also creates a Section 508 Refresh 502.3.3 barrier for assistive technology users. Applying `overflow-x: hidden` to `<body>` hides the symptom but leaves the broken layout in place, meaning the content is silently truncated rather than accessible.

## Severity rationale

Critical because horizontal scroll at mobile widths silently hides content and controls — including navigation and CTAs — and constitutes a WCAG 2.2 SC 1.4.10 (Reflow) AA failure.

## Remediation

Fix the source of overflow rather than masking it. In your global styles:

```css
*, *::before, *::after { box-sizing: border-box; }
body { max-width: 100vw; overflow-x: clip; }
```

For absolutely-positioned elements that escape their parent, add a containing ancestor:

```css
.section-wrapper { position: relative; overflow: hidden; }
```

In Tailwind, replace any fixed pixel widths wider than `max-w-screen-sm` with `w-full` and add `overflow-x-clip` to the outermost layout wrapper in `src/app/layout.tsx`.

## Detection

- **ID:** `no-horizontal-scroll`
- **Severity:** `critical`
- **What to look for:** Search for CSS properties that commonly cause horizontal overflow: elements with `width` values that exceed the viewport, elements using `position: absolute` or `position: fixed` with offsets that push content off-screen, long unbreakable strings without `word-break` or `overflow-wrap`, `white-space: nowrap` on wide content. Check whether the body uses `overflow-x: hidden` (which hides the symptom rather than fixing the cause).
- **Pass criteria:** Count all elements with fixed widths exceeding 640px, absolute/fixed positioned elements with offsets, and `white-space: nowrap` declarations on wide content. No more than 0 uncontrolled horizontal overflow sources may exist. The body must not use `overflow-x: hidden` to mask overflow from fixed-width children. Do NOT pass when `overflow-x: hidden` is applied to `body` or `html` as a workaround for an underlying layout problem.
- **Fail criteria:** At least 1 element with a fixed width exceeding 640px without containing overflow, or `overflow-x: hidden` on the body masking an unfixed underlying problem.
- **Skip (N/A) when:** Never.
- **Detail on fail:** `"Body has overflow-x: hidden which is masking overflow from a fixed-width child container — 1 horizontal overflow source found"` or `"Absolute-positioned element in hero section extends beyond right viewport edge at mobile widths"`.
- **Remediation:** Common fixes for horizontal overflow:

  ```css
  /* Prevent width overflow globally */
  *, *::before, *::after { box-sizing: border-box; }
  body { max-width: 100vw; overflow-x: clip; }

  /* Fix absolute positioned elements */
  .container { position: relative; overflow: hidden; }
  ```

  In Tailwind, use `w-full` instead of fixed widths and `overflow-x-clip` on the outermost wrapper.

---

## External references

- wcag 1.4.10
- section-508 502.3.3

Taxons: accessibility, user-experience

HTML version: https://auditbuffet.com/patterns/ab-001918
