Belinda Ijeoma Front end Engineer || Technical writer|| Tech Enthusiast

What are container queries in CSS?

3 min read 1096

CSS Logo Over a Background of Feathers

Container queries are one of the most talked about and requested features in CSS. So much so that it has become a cliché in the developer community. But what really is a container query?

Container queries are queries that help us style a container’s content based on its properties, like width and height. This takes a different approach from media queries, which help us style our web pages/websites based on changes on the viewport.

Container queries are currently not yet in CSS as of 2020, but do we really need an official addition before we can get our hands on some of the advantages that come with it?

Well, not exactly. There are tweaks that we can make to achieve a container query-like behavior in our code. We will be looking at some of them below.

Container query with flexbox

Flexbox is a unidirectional layout model that allows us to create a much more responsive website.

In this article, we will be using a technique rooted in flexbox and created by Heldon Pickering to mimic a container query. Our aim is to create three columns with flexbox and move them all to rows at a certain container width.

Create a folder called ‘container_query’ in your preferred directory, and then proceed to open it in your code editor. Next, let’s create two files within our ‘container_query’ folder and name them ‘index.html’ and ‘style.css’, respectively.

Proceed to paste the code below into your ‘index.html’ file:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>container queries</title>
</head> 
<body>
    <div class="container">
        <div class="child child1">
           Lorem ipsum dolor sit amet consectetur adipisicing elit. Ex, enim!
        </div>
        <div class="child child2">
            Lorem ipsum Lorem ipsum dolor sit amet consectetur, adipisicing elit. Laudantium aliquid esse fugiat!
        </div>
        <div class="child child3">
             consectetur adipisicing elit. Tempora totam, eos rerum ipsum consequuntur suscipit?
        </div>
    </div>
</body>
</html>

In the above HTML code, we created a ‘div’ container with two other ‘div’s as its content.

Next, let’s add some basic CSS styling to give it shape.

We made a custom demo for .
No really. Click here to check it out.

Add the below code to your ‘style.css’ file:

.child{
    background: rgb(231, 227, 227);
    padding:1em;
    font-size: 18px;
}

Now, let’s start applying Heldon’s method. We will add all the CSS code and then proceed to explain them one after the other. Let’s update our CSS file with the one below:

.container{
    display:flex;
    flex-wrap:wrap;
    gap:1em;

}
.child{
    flex-basis: calc( calc(500px - 100%) * 999);;
    flex-grow: 1;
    background: rgb(231, 227, 227);
    padding:1em;
    font-size: 18px;
}

We gave the container with the class of ‘.container’ a display of ‘flex’ and ‘flex-wrap’ of ‘wrap’. This is necessary as it helps our child elements to flex and breakout when necessary.

All the children of the main container are given a ‘flex-grow’ of 1. This allows the elements to grow beyond their original width and fill out remaining spaces.

The ‘flex-basis’ property helps us set what the ideal width of all the child elements should be. Note that flexbox does not follow this strictly, and it will make adjustments when necessary.

A large negative ‘flex-basis’ will result in the child elements eventually taking the row position from the initial column position.

What we did above in the ‘flex-basis’ property is that we made use of ‘calc()’ to set the ‘flex-basis’ property, such that it will give us a negative value somewhere below the 500px value. This will cause all child elements to take up the row position from the column position.

Flex-basis Property in Action

We can take the same approach as above and create two ‘p’ tags within the first child element that will move from column to row as the parent width reduces.

Let’s update the content of our first child element in the ‘index.html’ file with the code below:

<p>
    Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ducimus, perferendis!
</p>
<p>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum, soluta.
</p>

Add the below additional code to our ‘style.css’ file:

.child1{
    display:flex;
    flex-wrap:wrap;
}
.child1 p{
    flex-basis: calc( calc(400px - 100%) * 999);
    flex-grow: 1;
}

Just like in the first example, we are making use of the ‘flex-basis’ property to set an ideal width and then allow the elements with the ‘p’ tags to occupy the row position when the value turns negative.

Below is the resulting code:

Flex-basis Property With P Tags

Container query with CSS grid

Just like with flexbox, we can achieve conditional container styling with the help of CSS grid and its properties.

We are going to make use of the same HTML code that we used in the example above, so proceed and copy the HTML code in the example above your new index file.

Now, let’s copy the below code to our new CSS file. I will be explaining every addition accordingly:

.container{
    display:grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    grid-gap:1em;

}
.child{

    background: rgb(231, 227, 227);
    padding:1em;
    font-size: 18px;
}

We first set our display to grid, and then give our child containers a ‘grid-gap’ of 1em. The ‘grid-template-columns’ property does all the magic in this case. We are making use of ‘repeat()’ to create a grid with a minimum width of ‘300px’ and maximum width of ‘1fr’ with a limit of ‘auto-fit’. This allows the grid to fill out the whole viewport.

The result is a 3 column layout that switches to row when the parent container is below ‘300px’:

Three Column Layout

Watched box

Watched box was created with the sole aim of solving the no container query problem. To make use of it, we can import it after installation as follows into our code:

import WatchedBox from './path/to/watched-box.min.js';

We can then make use of it by wrapping it around our HTML code:

<watched-box widthBreaks="70ch, 900px" heightBreaks="50vh, 60em">
<!-- HTML and text stuff here -->
  </watched-box>

We set our width and height breakpoint with ‘widthBreaks’ and ‘heightBreaks’, respectively.

Finally, you can add the below code to your CSS file:

watched-box {
    display: block;
  }

Learn more about watched box by visiting the official Github repository here.

Conclusion

Though container queries are not yet an official addition to CSS, we can always walk around the limitation of not having them with any of the methods above. Bootstrap offers similar solutions as some of the above but with limitations, you can read more about bootstrap here.

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — .

Belinda Ijeoma Front end Engineer || Technical writer|| Tech Enthusiast

Leave a Reply