A Dynamic Gradient Text Function in Sass

Cathy Dutton
Cathy Dutton
Share

In this post a common text color function will be extended to work with gradient backgrounds. The effect is achieved by first creating a gradient background from a list of values. The function then appends corresponding color values to a new list to create a text gradient.

A little background…

The ability to change the color of text depending on its background is a common request, one way to do this is to test for the lightness of the background and then modify the text accordingly. A popular and well documented function exists to do just that…

@function set-notification-text-color($color) {
  @if (lightness($color) > 50) {
    @return #000000; // Lighter background, return dark color
  } 
  @else {
    @return #ffffff; // Darker background, return light color
  }
}

The above function is applied like this:

.notification-confirm {
  background: $notification-confirm;
  color: set-notification-text-color($notification-confirm);
}

Step 1 – The background gradient mixin

Before we look at the text gradient function we need to create a list to hold the values for our background gradient and create the mixin…

$list: $orange, $white, $orange, $white;

This list above and a direction are used as the arguments for the background mixin. Using a list has two main advantages, firstly it has an open ended number of arguments allowing for any combination of colors and/or percentages. Secondly, and importantly for this function we can iterate through the list to create the same number of new values for the text gradient. More information on mixin arguments and when to use them can be found in this post.

The gradient mixin looks like this:

@mixin gradient($direction, $list) {
  background: -webkit-linear-gradient($direction, $list);
}

and is applied like this:

.text {
  @include gradient(left, $list);
}

Step 2 – The text gradient function

In webkit/blink based browsers it is possible to display text gradients using the text clip property along with text-fill-color as shown below:

.text {
  background: -webkit-linear-gradient(left, #000, #fff); // We will need to generate gradient colors to complement the background.
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

Firstly we need to create a function with the same $list value as the argument. The function will create a new empty list to store our new values and then return them:

@function text-color($list){
  $text-list:();
  @return $text-list;
}

Then we run through each value in $list:

@function text-color($list){
  $text-list:();
  @each $color in $list {
    // Do something...
  }
  @return $text-list;
}

Inside our for each loop we can run the same check as the solid color function mentioned at the beginning of this post:

@function text-color($list){
  $text-list:();
  @each $color in $list {
    @if lightness($color) > 50% {
      // Create a dark text color
    } 
    @else {
      // Create a light text color
    }
  }
  @return $text-list;
}

To create the dark or light text color we need to add the value to $text-list. This is done using the append function:

$text-list:append($text-list, $black, comma);  // Adds $black to $text-list
$text-list:append($text-list, $white, comma); // Adds $white to $text-list

The final function would therefore be:

@function text-color($list){
  $text-list:();
  @each $color in $list {
    @if lightness($color) > 50% {
      $text-list:append($text-list, $black, comma);
    } 
    @else {
      $text-list:append($text-list, $white, comma);
    }
  }
  @return $text-list;
}

The function is applied to the $list gradient argument on the text element:

.text-block {
  @include gradient(left, $list);
  p {
    @include gradient(left, text-color($list));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

Sass color functions:

This function is fine in most cases but is a little restrictive in that the text can only be black or white. By using some of the built in Sass color manipulations the function can generate a text color dynamically based on input, removing the need for the if statement. A few examples of this would be:

@function text-color($list){
  $text-list:();
  @each $color in $list {
    $text-list:append($text-list, invert($color), comma);
  }
  @return $text-list;
}

@function text-color($list){
  $text-list:();
  @each $color in $list {
    $text-list:append($text-list, complement($color), comma);
  }
  @return $text-list;
}

@function text-color($list){
  $text-list:();
  @each $color in $list {
    $text-list:append($text-list, adjust-hue($color, 40deg), comma);
  }
  @return $text-list;
}

Taking things a little further:

As I mentioned earlier a key reason for using a list as the gradient parameter is the ability to use it as a multidimensional list. The example below adds percentages to give a little more control over the gradient…

$list: ($orange 0%),
       ($orange 50%),
       ($white 50%),
       ($white 100%);

This percentage value also needs to be added to the function:

@function text-color($list){
  $text-list:();
  @each $color, $percentage in $list {
    $text-list:append($text-list, invert($color), $percentage, comma);
  }
  @return $text-list;
}

Using CSS Keyframes we can animate a gradient to create some interesting effects for progress bars or loading animations. Demonstrations of some of the effects discussed can be found in this CodePen.

Limitations and fallbacks

As I mentioned previously text gradients work in blink/webkit browsers only, we can however ensure they degrade gracefully in other browsers. To do this simply use the webkit prefix only for your gradient, fill-color and background clip properties for this technique. You could also add a fallback color and background to the mixin…

@mixin gradient($direction, $list) {
  background: $white; // Fallback solid background color for unsupported browsers
  background: -webkit-linear-gradient($direction, $list);
}

p {
  color: $orange; // Fallback solid text color for unsupported browsers
  @include gradient(left, text-color($list));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

Frequently Asked Questions (FAQs) on Dynamic Gradient Text Function in Sass

How can I create a dynamic gradient text function in Sass?

Creating a dynamic gradient text function in Sass involves a few steps. First, you need to define a function that will generate a gradient. This function will take two parameters: the start color and the end color. You can use the mix() function in Sass to mix these two colors together, creating a gradient effect. Next, you need to create a mixin that will apply this gradient to text. This mixin will use the -webkit-background-clip and -webkit-text-fill-color properties to apply the gradient to the text. Finally, you can use this mixin in your Sass code to apply the gradient to any text element.

What is the role of the mix() function in creating a gradient text in Sass?

The mix() function in Sass is used to mix two colors together. It takes two color values and a weight as its parameters. The weight determines how much of each color is included in the final mix. In the context of creating a gradient text, the mix() function is used to generate the gradient by mixing the start and end colors together.

Can I use the dynamic gradient text function in Sass with other CSS properties?

Yes, you can use the dynamic gradient text function in Sass with other CSS properties. For instance, you can use it with the font-size property to change the size of the gradient text, or with the text-align property to change the alignment of the text. The dynamic gradient text function in Sass is just a mixin, so it can be used in conjunction with any other CSS property.

Why do I need to use the -webkit-background-clip and -webkit-text-fill-color properties in the dynamic gradient text function in Sass?

The -webkit-background-clip and -webkit-text-fill-color properties are used to apply the gradient to the text. The -webkit-background-clip property specifies the area that the background extends into. When set to text, it means the background will extend into the text, creating a gradient effect. The -webkit-text-fill-color property specifies the fill color of the text. When set to transparent, it allows the background (in this case, the gradient) to show through the text.

How can I customize the dynamic gradient text function in Sass?

You can customize the dynamic gradient text function in Sass by changing the start and end colors of the gradient. These colors are passed as parameters to the function, so you can easily change them to create different gradient effects. You can also customize the weight used in the mix() function to change the balance of the two colors in the gradient.