Responsive Components: a Solution to the Container Queries Problem

Container Queries, as in, the ability to style elements based on values from a particular element, like its width and height. We have media queries, but those are based on the viewport not individual elements. There are plenty of use cases for them. It's been said before, but I'll say it again, if container queries existed, the vast majority of media queries in CSS would actually be container queries.

Discussion about how to pull it off technologically gets interesting. (more…)

Container Query Discussion

Right now, we have the power to write CSS that only applies when the browser window itself is at certain widths or heights. Breakpoints, as it were. Super useful. What we don't have (natively) is the ability to write conditional CSS based on any particular elements (or "containers") properties.


Container Queries: Once More Unto the Breach

I guess the plan is to stop with the "element queries" and start thinking and referring to them as "container queries". We've been following this saga for a while. Element queries have a serious pitfall: infinite loops.

.our-element:media(min-width: 500px) {
  width: 499px;

As Responsive Issues Community Group member Mat Marquis puts it:

Well, since the query no longer matches, the new width is no longer applied. Since that new width is never applied, the element query would match again, so the new width would be applied, so the query would no longer match, so the new width wouldn’t be applied—and so on unto infinity. We've achieved a TARDIS-caliber paradox with just a few lines of CSS, and there's no predictable way for the browser to handle it.

Jon Neal actually had some ideas on how browsers could handle that:

Infinite loops would freeze at the offending block. While infinite loops are much more likely to happen with element media queries, this issue has been around since :hover. Therefore, a clear specification would be doubly useful.

But alas, perhaps forcing the queries onto a parent element will help:

... we need to reframe the way we talk about a potential solution. Since a solution can't allow an element to restyle itself, we can build that constraint into the specification: queries attached to an element can only influence the styling of that element's child elements.

I don't think it totally solves the infinite loop problem, but makes it easier to handle somehow?

Use Cases and Requirements for Element Queries

This is a perfect example of making a case for new language features. Not just a vague "element queries! that would be awesome!" but laying out a real-world scenario, what we have to do to achieve it now, and why that's not ideal. Of course there are big challenges (see this and this) but those debates can be held elsewhere and not muddy the "why we need it" explanation.

Thoughts on Media Queries for Elements

Imagine something like these Transformer Tabs as a widget in a fluid column in a responsive design. Depending on the browser window width, perhaps this design is either 4, 2, or 1 column wide. When it breaks from 4 to 2, the column probably temporarily gets wider than it was, even though the screen is narrower. It would be preferable when writing the media query logic for those tabs to consider how much space the widget has available rather than the entire window, which might be totally unrelated, especially when re-using this widget.

Jonathan Neal has some thoughts on how this might work, including the complicated bits you might not have thought about, like how a widgets contents might affect its parent container and cause an infinite loop.

Responsive Elements

Width based media queries are based on the entire browser window. If the browser window is narrower than 800px, do this. If the browser is window is wider than 400px, do this. But that's not always enough. Imagine a desktop 3-column layout at 1000px. Each column is 333px wide. Then you have a media query break at 800px which drops it to a 2-column layout, and with the third below. Even though the browser is now narrower, each column is wider (400px). It would be easier to write media queries for the modules inside those columns based on the current width of the column, not the browser window.

Kumail Hunaid's project can help with that. I like the approach. It adds class names to elements that you then use to style, so it's pretty unobtrusive.