Development Web

Advanced Tailwind: Container Queries

July 28, 2023
Advanced Tailwind: Container Queries

Tail­wind pro­vides a lot of val­ue for stan­dard­iz­ing design tokens and stylesheets. I’ve been using it in every web based project for the last year, and being able to share com­po­nents between projects and domains with­out restruc­tur­ing style sheets is an incred­i­ble boost to pro­duc­tiv­i­ty. Tailwind’s media queries, more specif­i­cal­ly, are one of my favorite fea­tures. With such ease you can define stan­dard­ized style behav­iors for dif­fer­ent screen sizes direct­ly in the className props:

<div className="sm:col-2 md:col-4 lg:col-8"/>

Tail­wind pro­vides a list of alias­es for these queries, which are by default mapped to stan­dard screen sizes. We can always extend this to match our own num­bers, of course.

So where’s the prob­lem? This post isn’t about media queries, but con­tain­er queries. I con­sid­er con­tain­er queries to be an advanced tech­nique for Tail­wind as it involves using plu­g­ins, and fits a spe­cif­ic use-case. Before I explain what a con­tain­er query is, let’s look at the prob­lem we’re try­ing to solve that media queries cannot.

Con­sid­er a web­site that has a user-con­trolled, resiz­able pan­el which is used for side-by-side views. This is often used for cross-ref­er­enc­ing web­sites where you can see mul­ti­ple, com­plete­ly dif­fer­ent pieces of con­tent at the same time. I put togeth­er a bare-bones exam­ple using Nex­tJs to illus­trate this below:

example of a not responsive resizable container

I cre­at­ed the pan­els using the react-resiz­able-pan­els library, and am just dis­play­ing the default Nex­tJs land­ing com­po­nent in both panels:

The issue is that the default Nex­tJs land­ing page includes media queries to han­dle mobile views! Why aren’t they being respect­ed when the pan­els are resized? Why do they look dumb when the pan­els are small? Look at the default code below and spot the media queries. They’re def­i­nite­ly there, but nothing’s happening!

screenshot of default NextJs landing page

This is sim­ply because Tail­wind media queries are based on the brows­er window’s size. They will nev­er change unless the brows­er win­dow is changed. They don’t know any­thing about the pan­el sizes. How do we get a media query to mon­i­tor the size of its par­ent div, instead of the brows­er win­dow? This is where con­tain­er queries come in, because this is exact­ly what they’re for.

Instal­la­tion #

Con­tain­er queries are a Tail­wind plu­g­in, so they need to be installed first by fol­low­ing these steps:

  1. npm install @tailwindcss/container-queries
  2. Add this to your tailwind.config.js file:
    plugins: [
     require('@tailwindcss/container-queries'),
     // ...
      ],
    

Usage #

Essen­tial­ly, we mark our media query alias­es with a new con­tain­er flag @container, or if you want a unique name in the case of more com­plex designs, you can write @container/{name}:

screenshot of using new container flag

This tells any child com­po­nents that if their media queries are also flagged, they will mon­i­tor only the parent’s size. See the @lg:flex flag in the div? The @ will make the lg: alias track the @container.

So with this new tech, we can just do a find-all on media queries in this com­po­nent, and add the @ mark­er. It will begin to look like this:

screenshot of improved NextJS Typescript code

After run­ning this now, we’ll see that our con­tent inside the pan­els are now respect­ing the par­ent com­po­nent sizes, and we didn’t have to rewrite our media queries at all! Aside from just adding a @ to each one.

animated GIF of the improved layout container

I think this is amaz­ing if you have a sim­i­lar use-case, and makes con­tain­er queries incred­i­bly easy to imple­ment. The next time you have to deal with resiz­able pan­els, or even just child com­po­nents that need a slight­ly more advanced twist on their styling, take a look at Tailwind’s con­tain­er query plugin!

You can check out the live exam­ple of con­tain­er queries run­ning with the pan­els here: https://advanced-tailwind.vercel.app/

And the source code is here: https://​github​.com/​D​a​v​e​A​l​d​o​n​/​a​d​v​a​n​c​e​d​-​t​a​i​lwind

David Crawford
David Crawford
Software Developer

Looking for more like this?

Sign up for our monthly newsletter to receive helpful articles, case studies, and stories from our team.

Kotlin Multiplatform
Android Development iOS

Kotlin Multiplatform

July 14, 2022

A brief look at Kotlin Multiplatform Mobile, a newer cross-platform mobile application framework.

Read more
The Pareto Principle at work in software
Business Process

The Pareto Principle at work in software

December 4, 2023

Read more
How brain-computer-interfaces could improve human health
Business

How brain-computer-interfaces could improve human health

May 13, 2024

Read more
View more articles