# CSS containment used on high-complexity components

- **Pattern:** `ab-002012` (`performance-core.script-style-efficiency.css-containment`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002012
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002012)

## Why it matters

Without CSS containment, updating one component in a data table, carousel, or real-time dashboard causes the browser to recalculate layout and repaint for the entire document — not just the changed element (ISO-25010 resource-utilisation). On a dashboard with 12 widgets where one widget polls every second, that means 12 full-page layout passes per second. `contain: layout paint` tells the browser the component is visually isolated, scoping style and layout work to the component boundary and dramatically reducing render overhead for complex UIs.

## Severity rationale

Medium because missing CSS containment on complex components causes unnecessary document-wide layout recalculation on every update, degrading animation frame rate and scroll performance.

## Remediation

Apply `contain: layout paint` to the root element of complex, frequently-updated components:

```css
/* src/components/data-table/data-table.module.css */
.dataTable {
  contain: layout paint;  /* scope layout and paint to this element */
}

.dashboardWidget {
  contain: layout paint style;  /* also scope CSS inheritance */
}
```

In a React component:
```tsx
// src/components/DataTable.tsx
<div style={{ contain: 'layout paint' }}>
  <table>{rows.map(renderRow)}</table>
</div>
```

Verify the impact in Chrome DevTools → Rendering → Paint flashing. After adding containment, the green flash on re-render should be limited to the component boundary rather than the full page. Do not apply containment to elements that overflow their box (dropdown menus, tooltips) — it clips overflow content.

## Detection

- **ID:** `css-containment`
- **Severity:** `medium`
- **What to look for:** Count all relevant instances and enumerate each. Identify complex components: data tables, carousels, dashboards, dynamic feeds. Check whether they use CSS `contain` property. Look for `contain: layout` or `contain: layout paint` directives on component roots.
- **Pass criteria:** High-complexity components use `contain: layout` or `contain: paint` to scope rendering context. At least 1 implementation must be verified. Repaint performance is verified to be faster with containment than without.
- **Fail criteria:** Complex components have no containment, forcing the browser to recalculate layout and paint for the entire page on every change. Component updates are slow.
- **Skip (N/A) when:** The project has no complex or frequently-updated components.
- **Detail on fail:** Identify the slow component. Example: `"Data table with 100 rows re-renders on sort; without containment, layout recalculation affects entire page. No contain property used. Repaint takes 150ms"` or `"Dashboard with 12 widgets; updating one widget triggers global style recalculation. No containment"`.
- **Remediation:** CSS containment limits the scope of style and layout calculations:

  ```css
  .data-table {
    contain: layout paint;  /* layout and paint operations scoped to this element */
  }
  ```

  On complex, frequently-updated components:
  ```tsx
  <div style={{ contain: 'layout paint' }}>
    <DataTable data={items} />
  </div>
  ```

## External references

- iso-25010 performance-efficiency.resource-utilization

Taxons: performance

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