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.

How to Prepare for our Associate Software Developer Position
Team

How to Prepare for our Associate Software Developer Position

June 30, 2023

Tips for applying to MichiganLab's Associate Software Developer program

Read more
Information Experience can make or break a product
Design Process

Information Experience can make or break a product

January 4, 2023

Kai discusses how writing impacts user experience, providing an overview of the types of writing that are involved in product development and how to approach it from a very high level.

Read more
The 5 Minute Accessibility Strategy
Android Development iOS

The 5 Minute Accessibility Strategy

May 18, 2023

We discuss how you can make a plan in just 5 minutes to provide accessibility in your mobile app.

Read more
View more articles