The custom WordPress themes we build use brand colors for certain design elements and the Gutenberg color palette.
We usually have three versions of each color: the main color, and lighter/darker versions for hover effects. We’ll often auto-generate the lighter/darker versions, but sometimes we need to specify a custom color.
In the past I’ve added all of the colors as their own independent variables:
// Brand Colors
// -- normal / darker / lighter
$blue_1: #59BACC;
$blue_2: darken( $blue_1, 10% );
$blue_3: lighten( $blue_1, 10% );
$green_1: #58AD69;
$green_2: #458D53;
$green_3: #7ABE88;
I’ve recently shifted to using a custom SASS function, brand-color()
, that makes it easier to select the color.
a {
color: brand-color( 'blue' );
&:hover {
color: brand-color( 'blue', 'darken' );
}
Inside my theme I define a map of $brand_colors
. If you only specify the main color, it will auto-generate the lighten
and darken
variants. But you can also manually specify your own colors for those.
The list of 6 variables above has been reduce to:
$brand_colors: (
'blue' : #59BACC,
'green' : #58AD69,
'green_darken' : #458D53,
'green_lighten' : #7ABE88,
);
And here’s my custom brand-color()
function. Take a look at my base theme to see how it’s included.
If you’d like to build your own SASS functions, take a look at the @function documentation.
/**
* Brand Color
*
*/
@function brand-color( $key, $variant: null ) {
@if map-has-key( $brand_colors, $key ) {
$color: map-get( $brand_colors, $key );
@if ( 'lighten' == $variant ) {
$lighten_key: $key + '_lighten';
@if map-has-key( $brand_colors, $lighten_key ) {
$color: #{map-get( $brand_colors, $lighten_key )};
} @else {
$color: lighten( $color, 10% );
}
}
@else if( 'darken' == $variant ) {
$darken_key: $key + '_darken';
@if map-has-key( $brand_colors, $darken_key ) {
$color: #{map-get( $brand_colors, $darken_key )};
} @else {
$color: darken( $color, 10% );
}
}
@return $color;
} @else {
@error "The #{$key} color could not be found in $brand_colors";
}
}
Skylar says
We’ve been looking into a similar setup, but using native CSS variables (custom properties) instead: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
SASS requires compiling before being deployed on a customer site, correct?
Have you run into any situations where CSS variables wouldn’t be suitable for use on live sites?
Bill Erickson says
Correct, SASS requires compiling, but all of our styles are so dependent upon SASS that this is not an issue.
We use version control and deployment tools like DeployHQ or WPEngine’s git push for pushing code updates, so compiling is not an issue.
There’s a lot of benefits to using SASS for your styles:
font-sizes( $mobile, $tablet, $desktop );
orcolumns( $columns, $element, $gap );
for generating CSS grid styling with float-based fallbackCSS variables are definitely interesting, but I haven’t had a need for the useful features they offer over SASS variables.
Stuart Gamblen says
Is there a way to call this SASS colour function but pass in a custom darken or lighten percentage that overrides the default?
I’ve tried this but it doesn’t seem to work:
border-bottom: 2px solid brand-color( $default, $variant: +17% );
Bill Erickson says
I haven’t figured out how to do it yet. When I need that, I’m using
map-get()
on the array. Ex:border-bottom: 2px solid darken( map-get( $brand_colors, 'primary_darken' ), 17% );
Stuart Gamblen says
Hi Bill,
Thanks for the response. I couldn’t figure that out but if it helps anyone else I found a solution using:
@each $name, $color in $brand_colors {
&.has-#{$name}-background-color:hover,
&.has-#{$name}-background-color:focus {
background-color: brand-color( $name, ‘darken’ );
border: 2px solid brand-color( $name, ‘darken’ );
// Bypass the default 10% ‘darken’
border-bottom: 2px solid darken( $color, 17% );
}
}