Use `currentColor` to Keep CSS DRY and Component Colors Flexible

Stephanie Eckles - Feb 16 '20 - - Dev Community

What is currentColor

currentColor is a special CSS keyword that can be used to request the color value for use in other CSS properties.

Given the following CSS:

p {
  color: blue;
  border-color: currentColor;
}
Enter fullscreen mode Exit fullscreen mode

Both the text color and the paragraph border will be blue.

If the p was a child of another element and didn't set its own color value, then border-color would pick up the value set in the ancestor.

Given the following, the border-color would now be red.

article {
  color: red;
}

article p {
  border-color: currentColor;
}
Enter fullscreen mode Exit fullscreen mode

How currentColor Keeps CSS DRY

DRY is an acronym for a popular coding principle: Don't Repeat Yourself.

So instead of creating classes for every brand or theme color and repeating or overriding styles such as border-color and box-shadow, you can create color classes that simply set the color property.

Using Sass, we can quickly create 3 classes representing our 3 brand colors:

$theme-colors: (
  "primary": #D73846,
  "secondary": #5D5DDE,
  "tertiary": #19965B
);

@each $key, $value in $theme-colors {
  .ink-#{$key} {
    color: $value;
  }
}
Enter fullscreen mode Exit fullscreen mode

Then for each component that intends to use the theme color across child elements, use the currentColor keyword for those properties.

Example (reduced to relevant properties using currentColor):

.card {
  border-color: 1px solid currentColor;

  &:hover {
    box-shadow: 0 0 1px 2px currentColor;

    &:before {
      // Use for background-color
      background-color: currentcolor;
      // Combine with opacity to use as a screen effect
      opacity: 0.08;
    }
  }

  svg {
    // Use currentColor for svg fill
    fill: currentColor;
  }
}
Enter fullscreen mode Exit fullscreen mode

The following Codepen demonstrates the full .card component with each card using one of the .ink-[theme color] classes:

currentColor Offers Flexibility in Component Colors

Without the use of currentColor you would traditionally have repeated all the styles in the above block to handle the individual brand/theme values for all those properties. For a 3 color theme system, in this example the compiled, minified CSS for separate classes v. not using currentColor would add up to about 520b. Spread across a comprehensive design system, this can add up to kb off on the final production build meaning better overall performance.

In addition, currentColor means those components can intake a one-off color rule just by passing a new color value to .card instead of write yet another entire block to change each value.

#special-card {
  color: pink;
}
Enter fullscreen mode Exit fullscreen mode

Dangers of currentColor

The drawback of using currentColor is the possibility of color combinations that do not appropriately pass contrast guidelines for accessibility. The advantage Sass has here is the ability to include functions within your component color-related rules to check for passing contrast. Considering the intent and expected use cases of a given element or component will help you decide whether to use currentColor over more defined color rules.

One way you may anticipate and overcome conflict is by preemptively declaring contrast-passing styles, particularly for typography, such as:

.card {
  // Perhaps support is a very light color, like pink
  &.ink-support {
    h3, a {
      color: scale-color(pink, $lightness: -23%);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player