slides.oddbird.net/cq/pre-cssday/

CSS Containers. What Do They Know?

slides.oddbird.net/cq/pre-cssday/

@ Pre-CSS-Day, CMD Amsterdam

Containers…

Do they know things?

What are they hiding in there?

As long as I can remember, developers have had questions for containers. What do they know? Do they know stuff?

And the answer is yes. They do. Container queries have had broad support in all modern browsers for over a year now.

Ok, it’s more complicated than that. Mostly developers had a single question, going back years: how big is the box?

In 2010 we got Media Queries, the heart of Responsive Web Design

Letting us measure the ‘viewport’ that our page is rendered in – and them adjust our designs based on that. That’s pretty great, until we start adjusting our designs in more complex ways.

So right away developers were asking to measure (or query) not just the viewport, but other elements on the page.

2011-2022 Selector Queries
Element Queries
Container Queries

There have been multiple approaches to this over the years, using a variety of names…

And it became one of the most requested features in CSS.

Browsers knew we were asking, they knew we wanted this feature, and they all gave us the same answer…

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

– Browsers, A Paraphrase (circa 2020)

The fact we can control a paper page is really a limitation of that medium.

– John Allsopp, 2000

@media prefers-reduced-motion

@supports container-type: inline-size

Animation of twitter-like posts appearing

Normal Flow

in a “Block Formatting Context

Intrinsic Sizing

  • auto
  • min-content
  • max-content
  • fit-content

Extrinsic Sizing

  • Context sizes (available space)
  • width or height set in px, %, em, etc

Responsive Web Design Force Everything Fluid

2010s – only extrinsic sizing

Intrinsic Web Design Combines Fluid & Fixed

2020s – Use intrinsic size as well!

  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

😎 Fing Cool Features

Making The Web Responsive

  1. Nested Contexts ???

  2. Expand & Contract Content ???

For Container Queries Some Restrictions Apply

We can’t change The Container Being Queried

CSS Containment

contain: size | layout | style | paint;

By default, block boxes Get block-size from Content

(intrinsic)

By default, block boxes Get inline-size from Context

(extrinsic)

👎🏼 Block-Size Containment

(too many side effects)

Queries only Measure The Axis We Contain

contain: inline-size layout style;

container-type: inline-size;
.element-to-query {
container-type: inline-size; /* or size */
}
@container (inline-size > 40em) {
.card { /* ... */ }
h2 { /* ... */ }
}

Also Recommended… Name Your Containers

Any number of names

main {
container-type: inline-size;
container-name: layout main;
}
main {
container: layout main / inline-size;
}
@container layout (min-width: 40em) {
.conditional { /* … */ }
}

@container main (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

No self-query Measuring an Ancestor

(can’t change what you measure!)

Bonus! Container Queries Measure Actual Styles

Grid Tracks & Flex Sizing?

No element to measure…

For reasons… No Default Containers

body {
> * { container: layout / inline-size; }
}

also… Container Query Units

cqw | cqh | cqi | cqb | cqmin | cqmax

@keyframes slide {
0% {translate: calc(0cqi - 100%);}
100% {translate: calc(100cqi);}
}

Default unit container The Small Viewport

Style Queries

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

Always Queries Direct Parent

Unless you query a specific container-name

.ಠ_ಠ {
  --(╯°□°)╯: ︵┻━┻;
} is valid CSS.

– Tab Atkins, @tabatkins

Style Queries… Only Custom Properties*

* for now

Style Queries… Only Custom Properties*

* for now **
** but maybe forever?

???

@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)