get your pixels movin'
The logo does tricks:

Invert SVG Text With A Mask

We’ll be using a clipPath and a mask to invert SVG text. What can you use this for in the real world? A couple of examples would be a loader counting a percentage or a hover effect on a button. It’s a pretty easy effect to create.

Setting up your SVG

You can use any SVG you like. For my example, I’m using a simple 500×100 SVG with text centered in middle of the stage.

<svg id="demo" xmlns="" viewBox="0 0 500 100" width="500" height="100">
<rect x="0" y="0" width="500" height="100" fill="#fff" /> 
<text text-anchor="middle" x="250" y="60" font-size="36">Change the text</text>

There are two important elements to make this happen.

Rectangle in our <defs>

The first thing we need is a rectangle in our clipPath elements. I’ve made this one the full size of the SVG, but you can choose any size you like. It just depends on the element you’re masking or clipping.

<clipPath id="theClipPath">
   <rect class="masker" x="0" y="0" width="500" height="100" fill="#444" />

Duplicate text layer

We’ll be placing a duplicate text layer on top of the original text. You can simply copy and paste the original into a new group like I did or you can use a bit of JavaScript to clone the original. That group will be revealed by the mask or clipPath.

<!-- Original -->
<text text-anchor="middle" x="250" y="60" font-size="36">Change the text</text>

<!-- Duplicate in a clipped or masked group -->
<g clip-path="url(#theClipPath)">
<text text-anchor="middle" x="250" y="60" font-size="36" fill="white">Change the text</text>
You can use the mask or clipPath directly on the element, but in my experience you’ll deal with fewer headaches by placing the element in a group and masking the group.

One more rectangle

You’ll also notice another rectangle with a class of masker in the HTML.

<rect class="masker" x="0" y="0" width="500" height="100" fill="#42a6e0" />

The additional rectangle isn’t necessary for this to work. I’m just using it as a new background for the white text that we’ll be revealing. Since it’s lower in the stack, the text will appear on top of it. Giving it the same class as the rectangle in the clipPath allows GSAP to animate both with one tween.

The GSAP code

First, we set the scaleX property of the masking rectangle so the duplicate layer is not visible on page load.

gsap.set(".masker", {
  scaleX: 0,
  transformOrigin: "left center"

After that, we just need to create a timeline and populate it with the two tweens. You’ll notice we originally set the transformOrigin to “left center” which is exactly what we want on the first tween. That way, the rectangle will expand from left to right. When we want it to shrink back down to the right, we set the transformOrigin to “right center”.

const tl = gsap
  .timeline({ paused: true, defaults: { duration: 1.2 } })
  .to(".masker", {
    scaleX: 1,
    ease: ""
  .to(".masker", {
    scaleX: 0,
    ease: "power2",
    transformOrigin: "right center"

The result

After setting up the SVG and creating the timeline, we now have a nice little SVG text effect.

See the Pen Invert SVG Text Color With A <clipPath> by Craig Roblewsky (@PointC) on CodePen.

A more complex demo

In the following demo, I’ve used a mask instead of a clipPath. The use of a mask is not really necessary in this case, but I wanted to show you both versions.

Using a mask is an excellent choice if you want the stroke to be part of the mask or perhaps, you want to use a gradient.

See the Pen Invert SVG Text Color With A Mask by Craig Roblewsky (@PointC) on CodePen.

Closing thoughts

I hope this gave you some inspiration for using a mask or clip-path in your next SVG project. Until next time, keep your pixels movin’.

If you found this information useful, please help me get the word out to the interwebs. I appreciate it. You're awesome!

Published: June 17, 2020 Last Updated: July 13, 2020

You might dig these articles too

No algorithm. Just hand chosen artisanal links.