Exposure in the Workplace - Colors, Containers, and Looking Up (the tree) to Parents
Jake Lundberg
Posted on September 7, 2023
Hang on, before you continue, everyone in the conference room!
For all you Office fans, this will NOT be a peak into Ryan's photography collection. That's not the kind of exposure I'm talking about...that would be awkward. 😳
No, the kind of exposure I'm referring to here is even better! ...exposure to new web development topics, features, and practices!
I always like having conversations with other web developers because I frequently get exposed to new stuff. Whether it's a new CSS property, some Javascript API, or just a different approach to solving a problem, I love learning new stuff like this. Which inspired me to start a new series to share and expose this stuff to more people. So in each episode, with the help of the Dunder Mifflin crew, I'm going to share a few (hopefully new for you) topics, along with an example or 2 of when they might be used.
In this first episode, I thought I'd share a few CSS things that I've been really excited about.
- using
oklch()
for colors - Container Queries (Finally!)
-
:has()
pseudo-class to target elements higher in the tree
Now before Michael finds a another way to distract us, let's dive in!
oklch()
If you haven't heard, we now have access to a whole bunch of new colors in CSS (on supporting devices) via the Display P3, CIELAB, Oklab colors spaces. Naturally, we wanted to use these new colors in CSS, so several new functions were added to support their use. Some of these new functions are lab(), lch(), and oklab()...but personally, the one I'm most excited about is oklch().
(I'm not going to do a deep dive here, but I highly recommend you take a look at the docs for these new color spaces and functions.)
With the use of the oklch()
function, we not only gain access to the Oklab color space (on supporting devices), but we can do so in a way that was much more intuitive for me (personally) to remember. the LCH
in the function name stands for L
ightness, C
hroma, and H
ue. Lightness represents how close the color is to pure black (0%) or pure white (100%). Chroma refers to the amount of color that is included, where 0 means no color...ie. some shade of gray. Lastly Hue is a number representing the hue angle of the color. For some reason this format just clicked for me, so I'm much more easily able to read code and know (roughly) what a code is without needing some external tool. But readability isn't all that makes this function great!
Not all devices support these new color spaces. But that's okay because oklch()
has a built in fallback. If you specify one of the new colors, and the user's device doesn't support it, the browser will automatically fallback to the closes representation of that color! As the developer, we don't have to do anything extra! Now, you may be asking, "how do we know what that fallback is?"...great question.
Thanks to @evilmartians there's a fantastic little color picker I like to use that shows you both the new color and the fallback color right next to each other! You should totally check the tool out and see what new colors are available. I was more surprised than Dwight when Michael returned after not getting the job at corporate (or rather, after Michel "removed himself from consideration")!
Container Queries
Another CSS feature I've been really excited about has been Container Queries. Many developers have been requesting this for a long time, and it's finally here! If you aren't familiar, imagine being able to write media queries, but instead of using the screen's information, you can use a container element's! This is great for components that can be used in a variety of places throughout an app (or more than one app). You specify style changes based on the component's container size, and it will look good wherever that component gets used, regardless of the layout it's in!
But why talk about it, when we can see an example!
Let's say we have a component that looks like this:
And it's structure looks like this:
<div class="card">
<header>
<img src="https://i.imgur.com/8Km9tLL.jpg" alt="Dwight Schrute" />
<div>
<h2>Dwight K. Shrute</h2>
<p>Assistant to the Regional Manager</p>
</div>
</header>
<main>
<ul>
<li><strong>D</strong>etermined</li>
<li><strong>W</strong>orker</li>
<li><strong>I</strong>ntense</li>
<li><strong>G</strong>ood Worker</li>
<li><strong>H</strong>ard Worker</li>
<li><strong>T</strong>errific</li>
</ul>
</main>
</div>
This card looks good on mobile, but what if we want to change the layout when the component gets a bit wider?
In the past, we would've had to something like
.card { ... }
@media (min-width: 768px) {
.card { ... }
}
But this limits us to using the screen width...what if we want to change the component's layout whenever it's wide enough? ...regardless if the screen is 300px wide, or 3000px! Enter Container Queries.
We can now easily make this happen by specifying our .card
element as a container, like this:
.card {
container-type: inline-size;
...
}
And then creating a container query to target elements inside when our container reaches a certain width:
@container (min-width: 500px) {
.card header {
flex-direction: row;
& img {
margin: 0 20px 0 0;
}
& h2 {
text-align: left;
}
}
}
Now, whenever our .card
is 500px wide (or more), our header will change it's layout so the contents are displayed horizontally.
And according to caniuse.com they are supported in the latest versions of the big 4 browsers!
:has()
The last thing I'd like to expose you to is another thing developers have been asking for for a long time. It's the new :has()
pseudo-class in CSS, which allows us to conditionally style an element based on elements that come after it WITHOUT JAVASCRIPT.
You heard me right! CSS no longer just flows from top to bottom!
And even better, it's incredibly easy to use!
Let's say we want our images to have margin-bottom: 2rem;
unless they are immediately followed by a <p>
that has a class of caption
. This would have required Javascript to first test for a caption to exist and to add a class to the image (or some other similar approach). But now, we can do this entirely in CSS.
img {
margin-bottom: 2rem;
}
img:has(+ p.caption) {
margin-bottom: 0;
}
Easy Peazy!
We can also style a parent element based on it's children in the same way.
Let's say we want to give all our .cards
from the previous section a red border when a child <div>
is found with an employee-of-the-month
class inside it. Again, this is super easy!
.card:has(div.employee-of-the-month) {
border: 2px solid red;
}
How awesome is that?!
According to caniuse.com, we're still waiting on Firefox to add full support for this. But it's currently an optional feature that a user can enable for testing in Firefox, so hopefully we'll see it released soon!
Conclusion
oklch()
, Container Queries, and :has()
are just a few of the things I'm really excited about having been released in CSS over the last year or 2. And hopefully you discovered something new here!
What are some of your favorite CSS features that other developers may not know about? I'm sure other's would love to get exposure to your thoughts!
Thanks for taking the time to expose yourself to something (hopefully) new. Until next time, Happy Hacking!
Posted on September 7, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.