Use cases for container queries

by Michael Scharnagl

This article has been updated the last time on February 20, 2016 and the given information may be not accurate anymore. Feel free to contact me on twitter to get more details.

Container queries – formerly known as element queries – are one of the features I really want to see implemented in 2016. That’s why I would like to show some use cases for container queries.

Note: I use the CSS-Element-Queries Polyfill for all demos here, as it supports only min-width, min-height, max-width and max-height (which the native solution will probably also do) and is pretty well tested. I added links to other polyfills at the end of the article. Also, the syntax used by the polyfill will be different from the final solution.

Modular components

The ideal responsive website is a system of flexible, modular components that can be repurposed to serve in multiple contexts.
Mat Marquis on A List Apart

Using media queries we need to check a module in very area of the site in different screen sizes and add a breakpoint every time the design *breaks*. By using container queries on the other hand the module is independent from the viewport size and we could define styles and container query breakpoints once based on the container size and reuse it everywhere.

Login form

Screenshot showing the different styles of a login form in different areas of a website

Let’s start with a demo of a Login form. This may be used in various areas of a site, be it the header, the sidebar or the main area. In this demo the input fields are among each other on narrow screens and next to each other on bigger (> 600px) screens.

form[max-width~="600px"] label,
form[max-width~="600px"] input[type="submit"] {
  margin: 0.6em 0 0.2em 0;
  display: block;
}

Demo and Code

Product items

Screenshot showing the different styles of a product item in different areas of a website

Next, we have a list of items – in this case products. On narrow screens they are shown among one another, if the container size is between 600px and 800px they are still among one another, but the image floats and the headline and text are shown alongside and if the container size is bigger than 800px the items are shown next to each other. By using container queries we can use the product list everywhere on our site and only need to define container breakpoints once – using mediaqueries we would have to use new breakpoints for every new context.

.products ul {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-wrap: wrap;
}

.products[min-width~="600px"] img {
	width: 50%;
	float: left;
	margin: 0 2em 2em 0;
}

.products[min-width~="800px"] ul {
	display: flex;
	flex-wrap: nowrap;
	justify-content: space-between;
}

.products[min-width~="800px"] li {
	width: 32%;
}

.products[min-width~="800px"] li:nth-child(1):nth-last-child(1) {
	width: 100%;
}

/* two items */
.products[min-width~="800px"] li:nth-child(1):nth-last-child(2),
.products[min-width~="800px"] li:nth-child(2):nth-last-child(1) {
	width: 49%;
}

.products[min-width~="800px"] img {
	width: 100%;
	float: none;
	margin: 0;
}

Demo and Code

Widgets

Another use case will be widgets, mostly third-party widgets. Think about advertising, social media buttons and widgets, community widgets (comments, forum) or all sorts of forms. When building a third-party widget you never know in which context the code will be integrated, which makes it pretty hard to deliver a responsive version. With container queries developers will be able to react to the surrounding container and deliver a great looking version in every possible case.

Third-party iframe

Screenshot showing the different styles of an third-party iframe widget in different areas of a website

Here is an example of a third-party iframe we use in different parts of our website, in this case once in the main area and once in a sidebar. The developer of the widget here changes the background-color of an element from blue to red for narrow (=< 300px) containers.

div {
  background-color: blue;
}

div[max-width~="300px"] {
  background-color: red;
}

Demo and Code

Advertisement

Screenshot showing the different styles of an ad in different areas of a website

Next is an example of an advertisement, inserted into our page with JavaScript. Within the JavaScript of the ad a stylesheet gets inserted, with some styles for the ads. Using container queries the developer changes the font-size from 1em to 1.4em if the container is bigger than 500px.

.ad {
  font-size: 1em;
}

.ad[min-width~="500px"] {
  font-size: 1.4em;
}

Demo and Code

Responsive images

Screenshot showing the different sizes based on container size of an responsive image in different areas of a website

Wouldn’t it be great if you could define sizes based on container sizes instead of viewport size, I thought so too, but it seems impossible. Yoav Weiss told me:

`sizes` can’t be based on layout info, since it’s needed before. EQ based images would have to suffer some delay.

Which makes sense after thinking about it, the browser don’t know the size of the container until the layout is *ready* and therefore it would take some time until the browser can decide which image should be shown.

We most likely won’t get container based sizes, but one never knows. So, I made an example nevertheless using the pollyfill to show the benefits.

<div data-responsive-image>
 <img data-src="http://lorempixel.com/350/150/sports/350x150/">
 <img min-width="350" data-src="http://lorempixel.com/700/300/sports/700x300/">
 <img min-width="700" data-src="http://lorempixel.com/1400/600/sports/1400x600/">
</div>

Demo and Code

Problems and Questions

When creating all the demos here I also had the idea for a navigation which items change from among each other to side by side if they all fit in one line. It did this by setting a container breakpoint if the nav is higher than 80px and therefore spreads across two lines. If this is the case, the nav items will all be among one another. Using the pollyfill this worked somehow, meaning you would get the right design onload and if you resize from big to small. But it won’t work when resizing from small to big, as the nav will always be higher than 80px. I don’t really know how this could be solved, but maybe you do – here is the demo?

Yes, there are a lot of questions to be asked and a lot of problems to be addressed, but I am still very optimistic we will see a first draft of container queries by the end of the year.

Demos

Here is a list of all demos, also available on Github.

Further reading

Pollyfills (incomplete list)

Michael Scharnagl

Portrait Michael Scharnagl

Follow me: @justmarkup

Subscribe to RSS: /feed

A freelance front-end developer focusing on HTML5, CSS, progressive enhancement and web performance.