# CSS contain and content-visibility: Performance and Rendering Control

Source: https://devdocs10.com/articles/css/css-containment  
By Murat Bo · Published 2026-08-27 · DevDocs10 (https://devdocs10.com)

CSS containment lets you tell the browser that parts of a page are independent, while `content-visibility` lets the browser skip work for content that is not currently visible. Used well, these features can reduce layout, paint, and style recalculation costs on large pages.

> **Quick answer:** Use `contain` when you want to isolate an element’s layout, paint, style, or size effects from the rest of the page. Use `content-visibility: auto` when you want the browser to skip rendering offscreen content until it is needed.

> **Difficulty:** Intermediate
>
> **You'll understand this better if you know:** basic CSS layout behavior, how the browser renders pages, and the difference between block layout, paint, and reflow.

## 1. What Is contain and content-visibility?

`contain` is a CSS property that limits how much an element can affect the rest of the page. `content-visibility` is a related property that can skip rendering work for an element, especially when it is offscreen.

- `contain` creates containment boundaries for layout, paint, style, or size.
- `content-visibility` can delay rendering until the browser needs the content.
- Both features help performance on large or complex pages.
- Both are about reducing unnecessary work, not changing the visual design by themselves.

These properties are especially useful for large lists, dashboards, long documents, expandable panels, and card grids where only part of the content is visible at once.

## 2. Why contain and content-visibility Matter

Modern pages often contain many nested elements, images, widgets, and text blocks. Without containment, a small change in one area can cause the browser to do more layout and paint work than necessary.

Containment helps the browser make better performance decisions:

- It can limit how far layout changes spread.
- It can prevent expensive repainting from escaping an element.
- It can reduce style recalculation in some cases.
- It can make scrolling and interaction smoother on large pages.

`content-visibility: auto` is especially valuable for content below the fold because the browser can skip rendering it until it approaches the viewport. That can significantly improve initial load time on content-heavy pages.

## 3. Basic Syntax

The core idea is simple: use `contain` to isolate an element, and use `content-visibility` to let the browser defer rendering.

### Containment syntax

Here is the basic form of `contain`:

```css
.card {
  contain: layout paint;
}
```

This tells the browser that the element’s layout and painting effects should not leak outside the element.

### Content visibility syntax

Here is the basic form of `content-visibility`:

```css
.section {
  content-visibility: auto;
  contain-intrinsic-size: 500px;
}
```

The `contain-intrinsic-size` value gives the browser a placeholder size before the content is fully rendered, which helps prevent layout jumps.

## 4. Step-by-Step Examples

### Example 1: Isolating a card component

Suppose you have a card with an image, text, and a button. If internal changes should not affect the rest of the page, containment can help.

```css
.product-card {
  contain: layout paint;
  border: 1px solid #ccc;
  padding: 1rem;
}
```

This is useful when a card contains animations, badges, or internal layout changes that should stay local.

### Example 2: Skipping offscreen sections

For long content sections, `content-visibility: auto` can avoid rendering work until the user scrolls near the section.

```css
.article-section {
  content-visibility: auto;
  contain-intrinsic-size: 800px;
}
```

The browser may skip rendering the section until it is close to the viewport, then paint it when needed.

### Example 3: Keeping expensive widgets isolated

A chart or editor inside a dashboard can be expensive to paint and relayout. Containment helps prevent changes inside the widget from affecting surrounding layout.

```css
.dashboard-widget {
  contain: content;
}
```

`contain: content` is a shorthand that combines several containment types and is often a practical default for self-contained UI blocks.

### Example 4: Reserving space for lazy-rendered content

When the browser skips rendering offscreen content, you should still reserve reasonable space to reduce layout shifts.

```css
.lazy-panel {
  content-visibility: auto;
  contain-intrinsic-size: 400px 600px;
}
```

This gives the browser a fallback size so the page does not collapse while the element is skipped.

## 5. Practical Use Cases

- Long article pages with many sections below the fold.
- Infinite feeds or large comment lists with many repeated items.
- Dashboard widgets that contain charts, tabs, or live data.
- Component libraries where each block should render independently.
- Accordion panels and collapsible sections that are not always visible.
- Complex documents where only the visible portion matters during initial load.

These features are most useful when the page contains many large regions, not just a few small elements.

## 6. Common Mistakes

### Mistake 1: Using contain when the element must size itself from outside content

`contain: size` and related containment modes can change how an element participates in layout. If you expect the browser to size the element based on its contents, size containment can produce surprising results.

**Problem:** The element may end up with an unexpected size because size containment prevents the element’s contents from influencing its own size in the normal way.

```css
.panel {
  contain: size;
  border: 1px solid #999;
}
```

**Fix:** Use a less restrictive containment mode, such as layout or content, when you still want the element to size naturally.

```css
.panel {
  contain: layout paint;
  border: 1px solid #999;
}
```

The corrected version keeps layout effects contained without forcing the element into size isolation.

### Mistake 2: Forgetting contain-intrinsic-size with content-visibility: auto

When the browser skips rendering offscreen content, it still needs a reasonable placeholder size to avoid layout jumps.

**Problem:** Without an intrinsic size, the skipped element can collapse and then expand later, causing content to shift when it becomes visible.

```css
.lazy-section {
  content-visibility: auto;
}
```

**Fix:** Add `contain-intrinsic-size` so the browser reserves space before rendering.

```css
.lazy-section {
  content-visibility: auto;
  contain-intrinsic-size: 600px;
}
```

The fix works because the browser has a fallback size even before the element is rendered.

### Mistake 3: Expecting containment to hide overflow problems

`contain` is not a replacement for `overflow`. It isolates certain rendering effects, but it does not automatically clip visual overflow the way developers often expect.

**Problem:** Content may still visibly extend outside the element if you need clipping and do not set overflow behavior explicitly.

```css
.tooltip-box {
  contain: paint;
}
```

**Fix:** Use `overflow` when clipping is required, and use containment for the rendering optimization you actually need.

```css
.tooltip-box {
  contain: paint;
  overflow: hidden;
}
```

The corrected version separates clipping from containment so the behavior is predictable.

## 7. Best Practices

### Practice 1: Use the least restrictive containment that solves the problem

Start with the smallest containment mode that gives you the performance improvement you need. Overusing size containment can make layout harder to reason about.

```css
.widget {
  contain: layout paint;
}
```

This is often a safer default than applying every containment type automatically.

### Practice 2: Pair content-visibility with a realistic intrinsic size

Whenever you skip rendering for offscreen content, reserve space that matches the expected content size as closely as possible.

```css
.feed-item {
  content-visibility: auto;
  contain-intrinsic-size: 320px;
}
```

This reduces layout shift and makes the page feel stable as content appears.

### Practice 3: Test scrolling and focus behavior

Because skipped content is not fully rendered until needed, always test keyboard focus, anchor navigation, and scroll-to-section interactions.

```css
.section {
  content-visibility: auto;
  contain-intrinsic-size: 500px;
}
```

This helps you catch edge cases where content becomes visible later than expected.

## 8. Limitations and Edge Cases

- `content-visibility: auto` is most effective on large, offscreen content blocks. Tiny elements often do not benefit much.
- Containment can change layout behavior, so it should be applied carefully to elements that participate in complex sizing.
- Some visual effects, such as shadows or positioned descendants, may behave differently when containment boundaries are introduced.
- Browsers still need to know the approximate size of skipped content, which is why `contain-intrinsic-size` matters.
- Containment does not replace semantic structure, good DOM organization, or efficient component design.
- Not every browser optimization is visible in the CSS alone; you often need to measure before and after.

> If a page already performs well, adding containment everywhere may not provide a noticeable benefit and can make debugging harder.

## 9. Practical Mini Project

Let’s build a simple article feed where each post card is isolated, and offscreen posts are skipped until they scroll near the viewport.

```css
.feed {
  display: grid;
  gap: 1rem;
}

.post {
  content-visibility: auto;
  contain-intrinsic-size: 280px;
  contain: layout paint;
  padding: 1rem;
  border: 1px solid #ddd;
  border-radius: 0.5rem;
}

.post h2 {
  margin: 0 0 0.5rem;
}
```

This example shows a realistic pattern for a long feed: each card is self-contained, and the browser can avoid rendering cards that are not yet visible. The placeholder size helps keep scrolling smooth and stable.

## 10. Key Points

- `contain` limits how an element affects the rest of the page.
- `content-visibility` lets the browser skip rendering work, especially for offscreen content.
- `contain-intrinsic-size` helps reserve space for skipped content.
- Containment is useful for large, modular UI pieces and expensive visual regions.
- Use the smallest effective containment mode to avoid layout surprises.
- Always test scrolling, focus, and size behavior after adding these properties.

## 11. Practice Exercise

Try styling a long FAQ page so that each answer block is isolated and offscreen answers are skipped until needed.

- Create a repeated FAQ item container.
- Apply `content-visibility: auto` to the answer block.
- Add `contain-intrinsic-size` to reserve space.
- Use `contain: layout paint` on each item to keep internal changes local.

**Expected output:** A long page that scrolls smoothly, with each answer block appearing stable as it enters the viewport.

**Hint:** Give each answer block a realistic placeholder height so the page does not jump when content is revealed.

**Solution:**

```css
.faq {
  display: grid;
  gap: 1rem;
}

.faq-item {
  contain: layout paint;
  border: 1px solid #e0e0e0;
  padding: 1rem;
}

.faq-answer {
  content-visibility: auto;
  contain-intrinsic-size: 240px;
}
```

This solution combines containment and rendering skipping in a way that is practical for long, scrollable content.

## 12. Final Summary

`contain` and `content-visibility` are CSS tools for controlling how much work the browser does. `contain` isolates an element’s effects, while `content-visibility` can delay rendering until content is needed.

They are especially useful on large pages with repeated components, long lists, and offscreen sections. The key is to apply them carefully, test the result, and pair skipped content with a sensible intrinsic size.

If you want to go deeper, the next useful topics are CSS rendering performance, layout containment details, and how browser painting and reflow work.

## Browser Support

| Feature | Status | Chrome | Edge | Firefox | Safari | Safari iOS |
| --- | --- | --- | --- | --- | --- | --- |
| contain | Widely available since Sep 2024 | 52+ | 79+ | 69+ | 15.4+ | 15.4+ |
| content-visibility | Newly available since Sep 2025 | 108+ | 108+ | 130+ | 26+ | 26+ |

Data: web-features 3.43.0 (MDN Baseline).
