Day 89: higher-order custom properties

posted on

It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.


Style queries may change the way we write CSS significantly.

Caution: If you’re a fan of Tailwind or similar utility frameworks, you might find this post offensive because it suggests using fewer classes instead of more.

On day 80 I’ve introduced you to container style queries. I’ve showed you a practical example from a project I was working on where style queries would’ve been really useful: When the following component has a dark background color, I set a light text color on all children.

<div class="card">
  <h2>light</h2>
</div>

<div class="card" style="--bg: var(--dark)">
  <h2>dark</h2>
</div>
:root {
  --dark: #000;
  --light: aqua;
}

.card {
  --bg: var(--light);

  background-color: var(--bg);
  color: #000;
}

@container style(--bg: var(--dark)) {
  * {
    color: #fff;
  }
}

Yeah, I know, not the best example in the world, but you get the point.

What’s even more interesting than querying custom properties, we’ve applied to a property of a container, is querying custom properties whose sole purpose it is to tell us something about the container. Doesn’t make sense? Okay, here’s an example.

Let's say we have a basic card component.

My title

Lorem ipsum dolor sit amet consectetur adipisicing elit. Non id sint pariatur excepturi delectus, quas saepe, adipisci nemo, beatae quo minima molestiae mollitia expedita assumenda doloremque.

If I want a larger variation of this component, I do this:

<div class="card" style="--card-size: large">
  …
</div>

You can also create a separate class, if you're not a fan of inline styles.

.card-large {
  --card-size: large;
}
<div class="card card-large">
  …
</div>

My title

Lorem ipsum dolor sit amet consectetur adipisicing elit. Non id sint pariatur excepturi delectus, quas saepe, adipisci nemo, beatae quo minima molestiae mollitia expedita assumenda doloremque.

Same component but larger and larger text

Note: Container style queries are still only supported in Chrome behind a flag.

Or if I want a vertical layout for the large card, I do this:

<div class="card" style="--card-size: large; --card-style: vertical">
  …
</div>

My title

Lorem ipsum dolor sit amet consectetur adipisicing elit. Non id sint pariatur excepturi delectus, quas saepe, adipisci nemo, beatae quo minima molestiae mollitia expedita assumenda doloremque. Magni nesciunt animi recusandae.

Same component but larger, larger text, and a vertical layout.

Here are the style queries that make this possible:


@container style(--card-size: large) {
  .card-wrapper {
    --width: 30rem;
  }

  h2 {
    font-size: 2rem;
  }
}

@container style(--card-style: vertical) {
  .card-wrapper {
    --width: 40rem;
    --direction: row;
    gap: 1rem;
  }

  h2 {
    margin-top: 0.5em;
  }

  .card-image {
    aspect-ratio: 1;
  }
}

Okay, cool, but can't we just use a class for that? Yes, but…

Container style queries are so brand new they aren’t even there yet. I can’t wait for browsers to support them to see if and how they will change the way we write CSS.

See on CodePen

Further reading

Do you want to learn even more awesome CSS?

I'm running a workshop with my friends at Smashing Magazine in which I introduce you to the most useful modern features in CSS and show how you can implement them today in your code base to improve scalability, maintainability, and productivity.

Learn more about the workshop!

Overview: 100 Days Of More Or Less Modern CSS