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.
Medium because missing CSS containment on complex components causes unnecessary document-wide layout recalculation on every update, degrading animation frame rate and scroll performance.
Apply contain: layout paint to the root element of complex, frequently-updated components:
/* 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:
// 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.
ID: performance-core.script-style-efficiency.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:
.data-table {
contain: layout paint; /* layout and paint operations scoped to this element */
}
On complex, frequently-updated components:
<div style={{ contain: 'layout paint' }}>
<DataTable data={items} />
</div>