slides.oddbird.net/cq/cssday/

CSS Containers. What Do They Know?

@ CSS Day

2009 @media Queries

2011-2022 Selector Queries
Element Queries
Container Queries

Containers don’t know anything.

– Browsers

Container queries will never be possible on the web. They would cause infinite layout loops.

– Browsers, A Paraphrase (circa 2020)

Would you like some very flexible boxes instead?

– Browsers

Intrinsic Web Design

The responsive web keeps evolving…

Responsive Web Design Forces Everything Fluid

Using % for everything

Intrinsic Web Design Combines Fluid & Fixed

Using intrinsic size of elements

  1. Truly Two-Dimensional Layouts
  2. Combine Fluid & Fixed
  3. Stages of Squishiness
  4. Nested Contexts
  5. Expand & Contract Content
  6. Media Queries, As Needed

Media Queries are Obsolete!*

(* in some situations)

  1. Nested Contexts ???

  2. Expand & Contract Content ???

CQ Fact Check: Possible on The Web

CQ Fact Check: 🧐 Infinite layout Loops?

In order to understand… How Container Queries Work

We need to understand… Why They Shouldn’t Work

Every box has An Intrinsic Size

defined by content

Some boxes have An Extrinsic Size

defined by containers/attributes/etc

😎 Fing Cool Feature

(enables flexbox and grid layouts)

🤯 Makes Queries Recursive

💥 Size » Query Change » Resize 💥

We can’t change What We Want To Measure

We can’t style The Container Being Queried

Or anything about The Container’s Context

We Need to Turn Off Intrinsic Sizing

(at least partially)

CSS Containment

Size, Layout, Style, Paint, &c

Size containment Removes Intrinsic Sizing

We can only Measure The Axis We Contain

Use size containment With Overflowing Containers

(like the html element)

We create containers Explicitly and Carefully

.element-to-query {
container-type: inline-size; /* or size */
}

For legacy reasons… No Default Containers

html {
container-type: size;
height: 100%; /* viewport height */
}
@media (min-width: 40em) {
.card { /* … */ }
h2 { /* ... */ }
}
@container (min-width: 40em) {
.card { /* … */ }
h2 { /* ... */ }
}
@container (width > 40em) {
.card { /* … */ }
h2 { /* ... */ }
}
@container (inline-size > 40em) {
.card { /* ... */ }
h2 { /* ... */ }
}
@container (20em > inline-size > 40em) {
.card { /* ... */ }
h2 { /* ... */ }
}

Container Queries Measure Actual Styles

Computed Values On the Container Element

@container (min-width: 30em) { /* CQ support */ }

@supports not (container: name) {
/* no CQ support */
}

Also Recommended… Name Your Containers

html {
container-type: size;
container-name: layout root;
}
html {
container: layout root / size;
}

Names can be Like Classes or IDs

(shared or unique – establish conventions!)

@container layout (min-width: 40em) {
.conditional { /* … */ }
}

@container root (min-width: 40em) {
.conditional { /* … */ }
}

Finding Containers

  1. For each matched element
  2. Find the nearest ancestor that has…
    • Any required container name
    • Any required container types

Containers Can’t Self-Query

(That would introduce loops!)

Always Measuring an Ancestor

(can’t change what you measure!)

Grid Tracks & Flex Sizing?

No element to measure…

also… Container Query Units

cqw | cqh | cqi | cqb | cqmin | cqmax

Default unit container The Small Viewport

Style Queries

@container style(--colors: invert) {}

Style Queries… Only Custom Properties*

* for now

Style Queries… Only Custom Properties*

* for now **
** but maybe forever?

Always Queries Direct Parent

Unless you query a specific container-name

???

@container state(stuck) {}
@container state(snapped) {}
@container state(overflowing) {}

Things Containers Know:

  1. Their Size (if contained)
  2. Custom Property Values
  3. Relative Values (like em)
  4. Maybe Some States?? (tbd)