Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Tue, 22 Apr 2025 18:31:19 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 225069128 Using currentColor in 2025 https://frontendmasters.com/blog/using-currentcolor-in-2025/ https://frontendmasters.com/blog/using-currentcolor-in-2025/#comments Thu, 10 Apr 2025 15:59:27 +0000 https://frontendmasters.com/blog/?p=5519 Gotta give props to currentColor. It’s a keyword in CSS that is the OG variable. It wasn’t always there, but it was relatively usable in browsers by, say, 2010.

currentColor is a value, that you have control over, that represents something else.

.card {
  color: red;
  border: 3px solid currentColor;
}

What do you think the color of that border is gonna be? Not a trick question, it’s red my friend. You don’t have to type red twice. You don’t have to worry those colors that you’ve so elegantly tied together are going to drift apart. The power of computer programming lives here.

The value currentColor resolves to is whatever the color value resolves to at the element being effected by the selector. The color property cascades, so it could be set three levels up from the current element, or not at all, or whatever. It’ll always be something.

p.s. it can be currentColor, currentcolor, CURRENTCOLOR, cUrrENtCoLOr or whatever. CSS is unbothered. Just spel it right.

Hard Times

Business just isn’t rolling in thick anymore for currentColor. Search a 10 year old codebase and you’ll find a few hits, but these days, custom properties are a far more popular choice. Are you turning your back on an old friend? Yes. Is new friend better? Also yes. Just saying.

.card {
  --mainColor: red;
 
  color: var(--mainColor);
  border: 3px solid var(--mainColor);
}

This does the same thing. It’s an extra line of code, but your fellow computer programmers will all agree that it’s much more clear and versatile.

Versatile?

Definitely. Custom properties can be just about anything. It’s almost weird how permissive the value of a custom property can be. But it’s certainly not just colors. Hopefully obviously: currentColor only references color. There is no currentPadding or currentEmotionalState or anything.

Bugs?

I figured I’d have a play for old times sake. While I was doing that, I noticed a few oddities.

body {
  color: orange;
  accent-color: currentColor; /* doesn't work 🤷‍♀️ */
}

That one just doesn’t work (across the three major browsers I tried). Why? No I’m asking you. lol.

Here’s another:

body {
  color: rebeccaPurple;
}
button {
  border: 1px solid currentColor;
}

That one isn’t a bug, I suppose, as the trouble is that user agent stylesheets tend to set the color of buttons themselves (e.g. color: buttontext;), so if you want it to work, you’ll have to set the color explicitly, or force inherit it.

button {
  color: inherit;
  border: 1px solid currentColor;
}

I also swore I found an issue with relative color syntax and currentColor, but now that I’m typing and fact checking I can’t find it again so I’ll just leave it at that.

I will say that using currentColor with the relative color syntax is awesome, like:

a {
  color: orange;
  text-decoration-color: oklch(from currentColor calc(l + 0.1) c h / 90%);
}

Which is basically what I was doing in Chilled Out Text Underlines.

But is it still cool though?

I feel like I’ve made the point that it’s not amazingly useful anymore, but I might also argue that it’s not a terrible idea when the intentionality matches up just right. For instance, say you’ve got icons where the fill should always match the text color. That’s a fine use case really.

nav {
  color: salmon;

  svg.icon {
    fill: currentColor;
  }
}

Another step further, we could pop a little shadow on those icons that is based on that color.

nav {
  color: salmon;

  svg.icon {
    fill: currentColor;
    filter: drop-shadow(
      0 1px 0 oklch(from currentcolor calc(l - 0.25) c h));
  }
}

Here’s a video of that and some other stuff working together. No custom properties here, all currentColor:

I have stuck in my memory a Simurai post from 2014 where he showed off the power of this as well.

Nice.
]]>
https://frontendmasters.com/blog/using-currentcolor-in-2025/feed/ 13 5519
Relative Colors https://frontendmasters.com/blog/relative-colors/ https://frontendmasters.com/blog/relative-colors/#respond Thu, 20 Mar 2025 13:33:51 +0000 https://frontendmasters.com/blog/?p=5431 I love the idea of being able to take a color you already have in CSS, like currentColor, a custom property, or a color pulled from an attr(), and manipulate it. The big examples being darken, lighten, or apply opacity to it for different adjacent elements or states.

We have a ton of “newly available” power in CSS with this in the form of the relative color syntax, and Ahmad’s new post about this is great. The color-mix() function has a bit better browser support and has a good amount of overlap in what it can do, but I prefer the syntax and power of the relative color syntax.

]]>
https://frontendmasters.com/blog/relative-colors/feed/ 0 5431
Chilled Out Text Underlines https://frontendmasters.com/blog/chilled-out-text-underlines/ https://frontendmasters.com/blog/chilled-out-text-underlines/#comments Wed, 12 Mar 2025 18:46:33 +0000 https://frontendmasters.com/blog/?p=5316 I sometimes struggle with what the perfect look for a link within body text should look like. It needs to be clearly a link, but also not styled so intensely it distracts from reading a paragraph. I generally like the idea that links are blue and underlined, as that’s as close to a default familiar look as we have for links, but I’m flexible. Links that are a “brand” color and distinct from the text color seem fine to me, particularly if also underlined.

Here’s how links look with entirely default styles:

Me, I think that look is a bit intense. I think it can be improved by keeping the spirit of what is going on there but chilling it out a bit.

Nudge the Underline Away

I think the characters are a bit more legible if we move that underline away a little. Let’s make the font system-ui and kick that underline away a smidge:

a {
  text-underline-offset: 2px;
}

I think that’s broadly better, regardless of font-family, line-height, etc.

Add Opacity to the Underline

This is the part that chills the link style out the most, while still reading strongly as a link. We’ve got text-decoration-color to use for this, which we can just apply a chilled out color directly. But we can be a bit smarter!

  • Rather than setting a 2nd static color, let’s leverage the currentColor. That way it’s not yet-another-color we have to manage.
  • Let’s use this alteration for our :hover and :focus styles, which can be another hard choice!

The relative color syntax would be cool here, but full cross-browser support is a smidge away on that yet, so let’s use the better-supported color-mix() instead.

For a smidge of extra trickery we’ll only apply the opacity underline when the link is “not” hovered or focused, meaning when it is that will be removed:

a:not(:is(:hover, :focus)) {
  text-decoration-color: 
    color-mix(in srgb, currentColor, transparent 75%);
}

Color Away!

By using currentColor it means that whatever color the links are, we get this chilled out style that comes along for the ride no matter what.

Possibly a decent candidate for a default stylesheet.

Is all this accessible? My guess is that as long as the color of the link has enough contrast against the background, and the keyboard focus styles are strong, it’s fine. But if I’m wrong feel free to correct me here.

Demo

]]>
https://frontendmasters.com/blog/chilled-out-text-underlines/feed/ 16 5316
Relative Color Syntax — Basic Use Cases https://frontendmasters.com/blog/relative-color-syntax-basic-use-cases/ https://frontendmasters.com/blog/relative-color-syntax-basic-use-cases/#comments Mon, 12 Aug 2024 18:38:35 +0000 https://frontendmasters.com/blog/?p=3448 As of last month, Firefox 128’s support of the relative color syntax means we’ve now got support across the board. I’m excited about that as it’s an extremely powerful way to manipulate colors in CSS. Plus it was part of Interop this year so that is further proof that is trucking along nicely.

The syntax with generic names looks like this:

color-function(from origin-color channel1 channel2 channel3 / alpha)

Here’s how it works in my head:

Add Opacity to a Color you Already Have

It’s common to have CSS custom properties set up for colors on a project.

html {
  --color-yellow: oklch(80% 0.15 94);
  --color-green:  oklch(70% 0.25 140);

  ...
}

Now you want to use that yellow, but at about 50% opacity. How do you do that? There are actually a couple of ways to add transparency to an existing color, but in my opinion the relative color syntax is the nicest.

In the past, I’ve split out the color values like this:

html {
  --color-yellow-lch: 80% 0.15 94;
  --color-yellow: oklch(var(--color-yellow-lch);

  ...
}

That way I could either use the color all together, or use the split out values to apply opacity:

.box {
  background: var(--color-yellow);
  border-color: oklch(var(--color-yellow-lch) / 50%);
}

But that can get out of hand! You could also split each color into L, C, and H, the combine those, giving you five variables for every color. Too much.

With the relative color syntax, breaking down colors isn’t necessary. You apply alpha (and other transformations) on demand, leaving the original single color as the only variable (token) you need.

.box {
  background: var(--color-yellow);
  border-color: oklch(from var(--color-yellow) l c h / 50%); 
}

I much prefer the idea of keeping the main colors tokenized as custom properties, then tweaking them as needed on demand.

Darken a Color you Already Have

In the above example, we had --color-yellow and I ended by saying I prefer doing one-off tweaks on demand rather than making a whole new variable. If you have a ton of usage of a slightly-darker version of a color, then sure, make a new variable and stay consistent. But if it’s more of a one-off, relative color syntax is awesome:

.box {
  background: var(--gray-5);

  h2 {
    color: var(--color-yellow);
    /* Darkened version of yellow */
    border-bottom: 2px solid oklch(from var(--color-yellow) calc(l - 0.4) c h);
  }
}

Lighten a Color you Already Have

Same deal here. I’m using OKLCH because I like it, particularly the “uniform brightness” characteristic. Meaning when doing this darkening and lightening across different colors, it feels like it lightens/darkens the same amount. Which feels weird to write, but it’s true. Other color spaces do not lighten and darken consistently.

.box {
  background: var(--gray-5);

  h2 {
    color: var(--color-orange);
    /* Darkened version of orange */
    border-bottom: 2px solid oklch(from var(--color-orange) calc(l + 0.4) c h);
  }
}

Easy Variations

Avoiding making too many variables is a nice consequence of the relative color syntax, but you can still use the relative color syntax to make variables if it’s useful to have them.

I like the idea of starting with a base color, perhaps a slightly tinted gray, and then making the official variations with the relative color syntax.

html {
  --base-gray: oklch(12.94% 0.02 159);
  
  --gray-1: var(--base-gray);
  --gray-2: oklch(from var(--base-gray) calc(l + 0.1) c h);
  --gray-3: oklch(from var(--base-gray) calc(l + 0.2) c h);
  --gray-4: oklch(from var(--base-gray) calc(l + 0.3) c h);
  --gray-5: oklch(from var(--base-gray) calc(l + 0.4) c h);
  --gray-6: oklch(from var(--base-gray) calc(l + 0.5) c h);
  --gray-7: oklch(from var(--base-gray) calc(l + 0.6) c h);
  --gray-8: oklch(from var(--base-gray) calc(l + 0.7) c h);
}

The fact that you can start with any color, use any color function, and manipulate any part of the color is incredibly powerful. The above use cases are pretty basic. I’m sure more talented designers or developers who deeply know color will be able to do much more interesting things!

]]>
https://frontendmasters.com/blog/relative-color-syntax-basic-use-cases/feed/ 2 3448