About a year ago, I talked about Element Queries and why they were difficult to make work. It's about time for an update.
Short version: Not much has changed. Naive element queries still suffer from circularity issues, and there's been no real effort to specify anything to get around it. However, Shadow DOM seems well-placed as a way to get an EQ feature into the web.
What Are Element Queries Again?
An "element query" is like a media query, specifically the 'width'/'height' MQs, but they apply to the width/height of the element's container, rather than of the screen or device.
Why Were Element Queries Problematic Again?
Element Queries (let's just call them EQs from here on) suffer from basic circular dependency issues.
Here's a simple example: Say you have an element which is normally 100px wide, but it uses an EQ to say that if its container is less than 200px wide, the element becomes 500px wide. (This is silly, but bear with me.) If the container is explicitly sized (
width: 150px; or the like), this is fine, but if the container is sized to its contents (
float: left;, for example), then you have a circular dependency: if the element is 100px wide, the container is 100px wide, but that trigger the EQ, so the element is 500px wide, so the container is 500px wide, but that disables the EQ, so the element is 100px wide, so the container is 100px wide, etc.
What About Them
A funny detail of this is that EQs already exist, at least in some form. If you use a MQ on a page displayed in an
<iframe>, the MQ is resolved against the size of the
<iframe> element. This is exactly an EQ, if you treat the
<iframe> as the "container" in the above explanations.
This avoids the problems outlined above because an
<iframe> cannot depend on the size of its contents. An
<iframe> is only ever explicitly sized; if it doesn't have anything explicit, it defaults to being 300px wide and 150px tall. The contents never affect its size in any way, and so the circularity problem never comes into effect - if you get super wide because the
<iframe> is skinny, nobody cares; the
<iframe> just sprouts a scrollbar.
How Can We Get Around This?
Of course, you don't want to use
<iframe>s all over your page. It would be nice if we could somehow establish the same sort of situation while keeping all our content in the page together.
The first thought people usually have is to create some CSS value, perhaps a
display value or something like that, which makes the element no longer pay attention to its contents. Unfortunately, this doesn't work well - since you don't know which elements are "independent" until you apply CSS, you might do too much work on initial layouts before you figure out that you're all wrong. Also, since the boundaries aren't immediately clear (and in fact can shift over time, if the property starts/stops applying to various elements), it's somewhat difficult to understand what elements are allowed to use EQs.
Better would be something that would alert browsers to the "independent" nature of the element before they start applying CSS. For example, an HTML attribute would work for this. Unfortunately, it's annoying to have to sprinkle presentation-based attributes over your page just to get your styling to work right.
I think that we've got a good opportunity to make this less bad with Web Components, though. They already represent a useful "boundary" in the form of the shadow DOM, so the potential confusion of not knowing which element your EQ is applying to would go away - it always applies to your host element, assuming it's marked as "independent".
While Level 1 of the Shadow DOM specs are stabilizing right now, I think this is something reasonable to aim for as a Level 2 feature. You'd be able to set some switch when defining your custom element, or perhaps set it per
ShadowRoot, which would make your component's layout independent of its contents, just like
<iframe>. Then, EQs would work inside the shadow, referring to the size of the host element. Outside of a shadow, or in a non-"independent" shadow, EQs would just always be false.
So that's the state of Element Queries in 2014. We're not really any closer to having them than we were in 2013, but there's light on the horizon for a possible good solution.