Can media queries resize based on a div element instead of the screen?

I've just created a javascript shim to achieve this goal. Take a look if you want, it's a proof-of-concept, but take care: it's a early version and still needs some work.

https://github.com/marcj/css-element-queries


Yes, CSS Container Queries are what you're looking for. The CSS Containment Module is the specification that details this feature.

You can read more about the decade of work, including proposals, proofs-of-concept, discussions and other contributions by the broader web developer community here! For more details on how such a feature might work and be used, check out Miriam Suzanne's extensive explainer.

Currently only Chromium 105+ supports Container queries out of the box, though Safari 16 will include support as well. Hopefully it won't be much longer before we see a robust cross-browser implementation of such a system. It's been a grueling wait, but I'm glad that it's no longer something we simply have to accept as an insurmountable limitation of CSS due to cyclic dependencies or infinite loops or what have you (these are still a potential issue in some aspects of the proposed design, but I have faith that the CSSWG will find a way).


Media queries aren't designed to work based on elements in a page. They are designed to work based on devices or media types (hence why they are called media queries). width, height, and other dimension-based media features all refer to the dimensions of either the viewport or the device's screen in screen-based media. They cannot be used to refer to a certain element on a page.

If you need to apply styles depending on the size of a certain div element on your page, you'll have to use JavaScript to observe changes in the size of that div element instead of media queries.

Alternatively, with more modern layout techniques introduced since the original publication of this answer such as flexbox and standards such as custom properties, you may not need media or element queries after all. Djave provides an example.


From a layout perspective, it is possible using modern techniques.

Its made up (I believe) by Heydon Pickering. He details the process here: http://www.heydonworks.com/article/the-flexbox-holy-albatross

Chris Coyier picks it up and works through a demo of it here: https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

To restate the issue, below we see 3 of the same component, each made up of three orange divs labelled a, b and c.

The second two's blocks display vertically, because they are limited on horizontal room, while the top components 3 blocks are laid out horizontally.

It uses the flex-basis CSS property and CSS Variables to create this effect.

Final example

.panel{
  display: flex;
  flex-wrap: wrap;
  border: 1px solid #f00;
  $breakpoint: 600px;
  --multiplier: calc( #{$breakpoint} - 100%);
  .element{
    min-width: 33%;
    max-width: 100%;
    flex-grow: 1;
    flex-basis: calc( var(--multiplier) * 999 );
  }
}

Demo

Heydon's article is 1000 words explaining it in detail, and I'd highly recommend reading it.

Update 2021/22

As mentioned in other answers, container queries are coming. There is a full spec for it, and its usage is detailed on MDN:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries

and there is a polyfill to get browsers that don't yet support it up to speed:

https://github.com/GoogleChromeLabs/container-query-polyfill

There is a nice little overview video of it here:

https://www.youtube.com/watch?v=gCNMyYr7F6w

This has now shipped to Chrome (05 September 2022)

https://caniuse.com/css-container-queries