Why I Am Not A Fan of CSS Container Queries

If you’re reading this, you know what CSS container queries are. I’m not going to go into why they’re so important and so special and why everybody is talking about them. You know what they are. There’s no need for an introduction.

But I’m not a fan of them.

Well, at least I’m not a fan of the syntax of them.

I could understand the syntax of CSS custom properties (var(--this-is-fine) ) and I guess I can embrace the wonky syntax of CSS grid (grid-area: 1 / 1 / span 1 / span 3 ). But container queries’ stupid syntax is where I draw the line.

To start off, if you’re setting up a container query you need to the contain property to the element, and it needs to have the value of layout inline-size style like so:

.container { contain: layout inline-size style }

(Some docs say that only layout and inline-size are needed, but in every example I found, the only way they worked is with the style value included. Think of it as the Heart Ring in Capitan Planet. Useless but required.)

(I even had to add it to Smashing Magazines’ pen, which was weird because they know their stuff and wouldn't forget something like that.)

The contain style is a working draft version to help with CSS performance. According to Mozilla: “By using contain: layout you can tell the browser it only needs to check this element — everything inside the element is scoped to that element and does not affect the rest of the page, and the containing box establishes an independent formatting context.

So, contain: layout = changing styles within the element do not affect the rest of the page. Cool.

Another value is contain: size , in which the child elements have no impact on the size of the parent element. Because of this, size only works if you set a width and height. Mozilla even says “Size containment does not offer much in the way of performance optimizations when used on its own.” Visually, it’s very similar to any element with overflow: visible on it.

Because inline-size is still in a working draft, Mozilla had no docs on what inline-size was, but according to Smashing Magazine, it is similar to size, except it doesn’t care about height. As long as you set the width of the element, the height is “intrinsic”. This makes sense because container queries are checking the width of the container.

(One wonders if the width is intrinsic if you set the height instead…)

So, contain: inline-size = if width (or height?) is declared, it is not affected by the size of the child elements. Cool cool.

Lastly, there is contain: style , which according to the CSS Working Group, “turns on style containment for the element. This ensures that, for properties which can have effects on more than just an element and its descendants, those effects don’t escape the element.

So, contain: style = limits style containment to within element and children. I’m not sure how that’s different than contain: layout but okay. Cool cool cool.

But why are they required? To be honest, if not for container queries, i will never use the contain property. Bloated JavaScript and non-responsive images are the cause of poor internet performance, not CSS. When I run my websites through Pingdom or GTmetrix or Google PageSpeed Insights, I’m not looking at how fast a single element is performing. Maybe I will look at Cumulative Layout Shift, but that’s not performance. In fact, I got some slack from my earlier Medium post about document.getElementById()and was informed that “Premature optimisation is the root of all evil”. With this in mind, requiring contain to optimize elements for container queries would therefore be evil.

A similar example would be forcing users to use will-change prior to using a CSS transition. Does it help? Sure. Is it required? No. This is how it should be with CSS container queries and contain too.

I’m not against the idea of CSS container queries, but seeing articles like “Say Hello to CSS Container Queries” or “Container Queries are actually coming” or “Container queries are possible!” or “CSS Container Queries are FINALLY HERE!!!” are wrong. Currently, at the time of writing, it only works in Chrome Canary with flags turned on with very specific syntax. There is abysmal, non-existent browser support. Sure, you can use a polyfill to provide more support but the fact that the CSS itself is awkward in the way it needs to be structured is still a valid concern. I can think of no other instance in CSS where something like contain needs to be declared first, especially when it isn’t referenced anywhere else afterward.

Personally, I think CSS container queries with d6u’s syntax of .container:media(max-width: 800px)would make more sense. Something like that doesn’t rely on an additional contain property. For those who don’t want any extra styling conditions, we also have Heydon Pickering’s Holy Albatross or Xiao Zhuo Jia’s Unholy Albatross.

I like the idea of CSS container queries, but I really hope they change the spec. This is good in theory but if contain is required, it seems like forcing people to use a new CSS feature that nobody would really use anyway. In the meantime, I will use the Holy/Unholy Albatross’ and not the contain property.

I am a web developer turned travel blogger that is forced to code to eat.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store