# Viewport meta tag is present

- **Pattern:** `ab-002524` (`site-health-check.accessibility-mobile.viewport-meta`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002524
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002524)

## Why it matters

Without `<meta name="viewport" content="width=device-width">`, mobile browsers render the page at desktop width (typically 980px) and scale it down — text becomes unreadable, tap targets become too small, and users must pinch-zoom to navigate. WCAG 2.2 SC 1.4.4 (Resize Text) requires content to remain usable when scaled to 200%, and section 508 requires equivalent mobile access. Setting `user-scalable=no` or `maximum-scale=1` blocks pinch-to-zoom entirely, which is an accessibility violation that fails WCAG 1.4.4 — a separate and more serious defect than a missing viewport tag.

## Severity rationale

High because a missing viewport meta tag renders the entire page unusable on mobile devices — content appears at desktop scale with no readable text or functional tap targets.

## Remediation

Add the viewport meta tag to your HTML `<head>`. This is the canonical correct value:

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

In Next.js App Router, set it in `app/layout.tsx`:

```tsx
export const metadata = {
  viewport: 'width=device-width, initial-scale=1',
};
```

Or directly in the `<html>` template's `<head>`. Do NOT include `maximum-scale=1` or `user-scalable=no` — these prevent pinch-to-zoom and violate WCAG 2.2 SC 1.4.4. Vite, Create React App, and most framework starters include this tag by default in `index.html`.

## Detection

- **ID:** `viewport-meta`
- **Severity:** `high`
- **What to look for:** Count the number of `<meta name="viewport">` tags in the HTML. Extract the `content` attribute value and check that it contains the `width=device-width` directive. Also check for `initial-scale=1` which is recommended but not required. Check that `maximum-scale` is not set to a value less than 2 (this blocks pinch-to-zoom accessibility).
- **Pass criteria:** At least 1 `<meta name="viewport">` tag exists with a `content` attribute containing `width=device-width`. The viewport must not disable user scaling by setting `maximum-scale` to less than 2.0 or `user-scalable=no`. Report the full viewport content value.
- **Fail criteria:** No `<meta name="viewport">` tag found, or the `content` attribute does not include `width=device-width`.
- **Do NOT pass when:** The viewport meta tag is present but includes `user-scalable=no` or `maximum-scale=1.0` — these block pinch-to-zoom, which is an accessibility violation (WCAG 1.4.4).
- **Skip (N/A) when:** The response `Content-Type` is not HTML (e.g., JSON API, plain text).
- **Error when:** SPA detected.
- **Detail on fail:** `"No viewport meta tag — site will not be mobile-friendly"`
- **Remediation:** The viewport meta tag tells mobile browsers how to scale the page. Without it, mobile devices render the page at desktop width and shrink it. Add to your `<head>`:

  ```html
  <meta name="viewport" content="width=device-width, initial-scale=1">
  ```

  Do NOT include `maximum-scale=1` or `user-scalable=no` — these prevent pinch-to-zoom, which is needed for accessibility. Next.js, Vite, and most frameworks include this by default in their HTML template.

## External references

- wcag 1.4.4
- section-508 502.3.3

Taxons: accessibility

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