Containment

Table of Contents

Layout and Size containment are supported in all major evergreen browsers:

.sidebar {
contain: layout size;
}

Layout Containment

Isolates the layout-impact of contents in several ways:

This ensures that:

Size Containment

Isolates the size-impact of contents:

This feature primarily exists to make container queries possible. When combined with layout containment, it allows:

Is single-axis containment even possible?

2-axis size containment might work for some app-style layouts, where layout areas are sized to the viewport, and each area is a scroll-container. But most web layout relies on specifying inline-size (often horizontal), and allowing content to expand or contract on the block-axis (often vertical).

We need container queries to support that more common use-case.

Conceptually, single-axis containment should not be hard to implement if we can describe how it works. But that may still be challenging…

Single-axis containment only works if we can ensure that changes in the cross-axis have no impact on the contained axis. There are several places where CSS makes that difficult.

We have potential solutions to most of the individual issue here. But the overarching concern is that all these solutions need to be applied on arbitrary ancestors of the contained element, making their impact expensive for browser engines, and unpredictable for authors.

Cross-axis overflow and classic scrollbars

(requires classic scrollbars enabled by the operating system)

See the Pen demo by @miriamsuzanne on CodePen.

If any ancestor has overflow on the container’s block axis, then additional block-size of the contents can trigger a scrollbar on the cross-axis. Classic scrollbars for block-scrolling take up space on the inline-axis, leaving less space for the container.

This is likely to a very common scenario, impacting the majority of sites that uses inline-size containment, since the viewport itself uses auto-scrollbars.

This could be resolved by applying overflow-gutter: stable to the nearest ancestor with overflow: auto on the container’s block axis. However, overflow-gutter is currently limited to a single axis (block-scrolling), and might need to handle inline-scrolling as well, in case the scroller has a writing mode orthogonal to the container.

%-Padding percentages in Orthogonal Writing Modes

See the Pen demo by @miriamsuzanne on CodePen.

When padding is applied to the block axis in percentages, those values resolve against the inline-size of the parent. By restricting single-axis containment to the inline axis, we eliminate the majority of these issues. However, it’s still possible to apply orthogonal writing modes to any arbitrary ancestor with block-padding that would respond to the (now cross-axis) block size of the container.

This could be resolved by “zeroing out” any percentage-padding applied to any ancestor on the containers block-axis.

Auto-sized BFCs effected by floats

See the Pen demo by @miriamsuzanne on CodePen.

The auto-sized Block Formatting Context (created by overflow:hidden) finds space for itself among various floated elements. However, as the contents expand vertically, the BFC has to contend with additional floated elements, and resizes. Note that:

This could be resolved by adding clear: both to the BFC.

Aspect ratios (and Orthogonal Writing Modes?)

See the Pen demo by @miriamsuzanne on CodePen.

Since aspect-ratio implementations are inconsistent, and may have existing recursion issues (see #6419), I’m not confident that I know what issues here are specific to inline containment. Still it seems like something to keep an eye on - especially when orthogonal writing modes come into play.

I expect this could be resolved in by removing the impact of the preferred aspect ratio. Authors who want to maintain a strict aspect ratio can still do that by applying size containment and defining overflow behavior.