There seems to be a lot of confusion and conflicting information and definitions being given for the terminology relating to style scoping, element queries, and container queries.

As we discuss these ideas, work on a spec to propose these as a new feature for CSS, and begin building layouts using these concepts it's important for us to have a vocabulary that lets us talk about these ideas with specificity and clarity.

In this video I walk you through element and container queries from the ground up, talking about them naturally, and using new terms in context so you can understand how to talk about these same concepts when discussing your own ideas.

Key Terms

Scoped Style

Normally all CSS is written in a global scope. This means that the point of reference for all of the styles begins with the HTML element and all of its child elements. With scoped CSS you have the ability to pick any element as a point of referene for writing your styles, and by 'scoping' an element you create a context around that element that can be shared or accessed via JavaScript.

In the CSS Element Query syntax I propose, a scoped style might look like this:

  @element 'ul' {}

In this example we could say that this is a 'scoped style' written for the ul element. We would also call the ul our 'scoped element', or 'the element in our scope'.

This is an at-rule, @element, that wraps a block of other CSS rules. These rules would only apply to the page if there is at least one element in the DOM that matches the selector in our scope.

Element Query

An element query is essentially a scoped style with the addition of one or more responsive conditions. A responsive condition could look like and (min-width: 500px) or and (max-characters: 20) and would prevent the block of css rules from applying to the page until the responsive conditions are true.

Here is an example of an element query in the same syntax:

  @element 'input' and (max-characters: 20) {}

Now one thing you can notice about this right away is that max-characters is not a media feature supported by @media queries - as it turns out when writing responsive styles for elements instead of for the viewport, the ability to base responsive conditions on a wider variety of properties makes sense. The full list of possible responsive conditions element queries might looks something like this:

  • min-width
  • max-width
  • min-height
  • max-height
  • min-children
  • max-children
  • min-characters
  • max-characters
  • min-lines
  • max-lines
  • min-scroll-x
  • max-scroll-x
  • min-scroll-y
  • max-scroll-y
  • orientation
  • min-aspect-ratio
  • max-aspect-ratio

That's a lot of new flexibility for creating responsive layouts!

Container Query

This is a term for an element query that wraps a block of CSS rules that apply to different elements other than the scoped element itself. The syntax I am proposing is a container-style element query syntax.

  @element '#sidebar' and (max-width: 300px) {
  #sidebar .widget {
    font-size: 10pt;
  }
}

A non container-style element query syntax would allow you to write responsive conditions for one element, and only change styles for that one element depending on its own condition.

(For those people who believe container queries have a circularity or self-reference problem, the idea of non container-style element queries is right out of the question because in theory the only thing an element query could change would be itself. As it turns out, the circularity or self-reference might have some easy workarounds, but this is why you'll hear or see some people saying "It's container queries now, not element queries" or stuff like that - they're still operating on information from 2015 or earlier.)

Meta Selector

When writing scoped styles the need became immediately clear that once you have the ability to scope an element, you need a selector that can target elements based on that new point of reference in the DOM. The idea to include a selector referring to $this, the very element(s) matching the scoped selector in our scoped style became apparent.

  @element 'input' and (min-characters: 10) {
  $this {
    background: red;
  }
}

Another selector that makes sense in a world with style scoping is $parent, which refers to the element containing our scoped element.

Other meta selectors include: $prev which targets the element before our scoped element, and $next which targets the element directly after our scoped element.

(If you understand the approach to CSS like CSS Modules where you assign unique identifiers to your elements, and as selectors in CSS as a way to try to target only one element on the page - that's a laborious workaround to the problem solved by proper style scoping. If CSS had style scoping as a native feature this is something you would never need to do. Using meta selectors can help replace the need for this kind of workflow.)

Hopefully this video and blog post clear up some of the terms being used relating to element queries and container queries!

For more reading and videos about the topic of element and container queries, check out my Element Queries Reading List to stay up-to-date with the latest developments in this area!


4,134 2 25