Now let’s animate it

I worked on a project recently where I wanted headers, paragraphs, and general elements to have a smooth wiping reveal; masked gradient from left to right. A major requirement was that the reveal had to work above a graphic background.

It’s a fairly common reveal, but there are some limitations related to the implementation on the web.

TL;DR Example: https://jsfiddle.net/7my6copn/2/

Parameters

Due to the non-simple background behind the text, it excluded all methods of opaque cover masks; meaning we couldn’t use a PNG-24 transparent to opaque white image over top of the text. That type of masking technique could work well here on Medium.com because of the background color, but not in my case.

That left more traditional masking techniques. The first obvious option is SVG, but it would have been impractical for me to use SVG for all of the text.

Clip-paths won’t work with alpha masks, so that leaves us with mask-image.

Attempt #1 (failure)

My first idea was to use apply linear gradients on mask-image within keyframe animations. That theoretically would work like in this example.

Black alpha colors. 0,0 -> 0,F -> F,F

You’d think this would work, but it doesn’t. CSS Animations can’t interpolate gradients between keyframes. The only way to get this to work (very unrealistically), would be to create all 0%, 1%, 2%, 3%, etc.

After a bit of research online, I found that many others tried and failed with the same idea. Unfortunately, none of the threads I came across had proper solutions.

Attempt #2 (successful)

Knowing that I still needed to use masks and that I couldn’t animate the gradient itself, I started to flip through some MDN docs. I found that both mask-position and mask-size exist. The goal now was to see if we could animate the motion of a mask. (spoiler, you can)

This technique sets the linear gradient mask on the object you want, increases the size it substantially to overflow left and right, and animates the position of the mask. This allows the alpha mask to easily grow with the container, animate in full at any speed/easing, and work on any HTML element (text, shapes, etc).

Here’s a link to the working example.

Below is a simple diagram explaining the concept of the technique. The mask is oversized by a multiple of the target’s width. This allows for there to be a full transparent section, a transitional section, and a full opaque section. When you land on the full opaque section, it should be fully revealed.

Oversized masks that wipe across a viewbox

If you have any suggestions, different techniques, or thoughts… leave ’em down below.