This article introduces an interesting property in CSS called mask.

Mask, as the name suggests, translates as a mask. In CSS, the mask attribute allows the user to hide part or all of the visible area of an element by masking or cropping the image of the specific area.

In fact, masks have been used for some time, but there are not many practical scenes, and they are rarely used in actual combat. This article will list some interesting scenes created by using masks.

grammar

The most basic way to use a mask is to use an image like this:

{
    /* Image values */
    mask: url(mask.png);                       /* Use bitmap to mask */
    mask: url(masks.svg#star);                 /* Use shapes in SVG graphics to mask */
}
Copy the code

Of course, we’ll talk more about how to use pictures. Using images is actually a bit cumbersome, because we first have to prepare the corresponding image material, in addition to the image, mask can also accept a similar background parameter, which is the gradient.

Use methods similar to the following:

{
    mask: linear-gradient(#000, transparent)                      /* Use a gradient to mask */
}
Copy the code

How do you use it? For a very simple example, we created a gradient from black to transparent. We put it into practice. The code looks like this:

Here’s an image with a gradient from transparent to black overlay,

{
    background: url(image.png) ;
    mask: linear-gradient(90deg, transparent, #fff);
}
Copy the code

When the mask is applied, it looks like this:

In this DEMO, you can first understand the basic use of mask.

Here’s the most important takeaway from using masks: The overlap between the image and the gradient of transparent generated by the mask will become transparent.

Note that the gradient above uses linear gradient(90deg, transparent, # FFF). The # FFF solid color can be changed to any color without affecting the effect.

CodePen Demo – Basic use of MASK

Use MASK to crop the image

Using the simple application above, we can use mask to achieve simple image cropping.

Use mask to implement a corner mask

Using linear gradients, we implement a simple angular cut:

.notching{
    width: 200px;
    height: 120px;
    background:
    linear-gradient(135deg, transparent 15px, deeppink 0)
    top left,
    linear-gradient(-135deg, transparent 15px, deeppink 0)
    top right,
    linear-gradient(-45deg, transparent 15px, deeppink 0)
    bottom right,
    linear-gradient(45deg, transparent 15px, deeppink 0)
    bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
}
Copy the code

Something like this:

We apply the gradient above the mask and replace the background with an image to get the image with the cut effect:

    background: url(image.png);
    mask:
        linear-gradient(135deg.transparent 15px.#fff 0)
        top left.linear-gradient(-135deg.transparent 15px.#fff 0)
        top right.linear-gradient(-45deg.transparent 15px.#fff 0)
        bottom right.linear-gradient(45deg.transparent 15px.#fff 0)
        bottom left;
    mask-size: 50% 50%;
    mask-repeat: no-repeat;
Copy the code

The results are as follows:

CodePen Demo – Use MASK to implement a corner cutting MASK

Of course, there are many other ways to do this, such as clip-path, where mask is also one way.

Use a mask for multiple images

Above is a single image using a mask. Let’s take a look at some of the images and see what kind of sparks can be generated by using a mask.

Let’s say we have two images. Using a mask, we can display them superimposed on top of each other. One of the most common uses:

div { position: relative; background: url(image1.jpg); &::before { position: absolute; content: ""; top: 0; left: 0; right: 0; bottom: 0; background: url(image2.jpg); mask: linear-gradient(45deg, #000 50%, transparent 50%); }}Copy the code

Two images, one on top of the other, and then use mask: linear gradient(45deg, #000 50%, transparent 50%) to divide the two images:

CodePen Demo — basic use of MASK, basic use of multiple pictures

Of course, notice that the mask gradient we used above is a full solid color change with no overwork.

Let’s modify the gradient in the mask a little bit:

{
- mask: linear-gradient(45deg, #000 50%, transparent 50%)
+ mask: linear-gradient(45deg, #000 40%, transparent 60%)
}
Copy the code

You can get the effect of transitioning from Picture 1 to Picture 2:

CodePen Demo — basic use of MASK, basic use of multiple pictures 2

Use MASK for transition animation

With the setup above. Using some of the techniques described above, we can use masks to perform some transitions between images.

Use linear gradient mask:linear-gradient() to switch

In the Demo above, we dynamically change the mask value to achieve the image display/transition effect.

The code might look like this:

div {
    background: url(image1.jpg);
    animation: maskMove 2s linear;
}

@keyframes{{0%mask: linear-gradient(45deg, #000 0%, transparent 5%, transparent 5%); 1%} {mask: linear-gradient(45deg, #000 1%, transparent 6%, transparent 6%); }... 100% {mask: linear-gradient(45deg, #000 100%, transparent 105%, transparent 105%); }}Copy the code

Of course, it takes a lot of effort to do this, and we usually use a preprocessor like SASS/LESS to do this. Something like this:

div { position: relative; background: url(image2.jpg) no-repeat; &::before { position: absolute; content: ""; top: 0; left: 0; right: 0; bottom: 0; background: url(image1.jpg); Animation: maskRotate 1.2 s ease - in-out; } } @keyframes maskRotate { @for $i from 0 through 100 { #{$i}% { mask: linear-gradient(45deg, #000 #{$i + '%'}, transparent #{$i + 5 + '%'}, transparent 1%); }}}Copy the code

You can get something like this (hidden and clear on a single image and switch between two images) :

CodePen Demo — MASK Linear gradient transition

Use the angular gradient mask: conic-gradient() to switch

Of course, in addition to the mask: linear-gradient(), it is also possible to use either radial gradient or angular gradient. The principle of using angular gradient is the same:

@keyframes maskRotate { @for $i from 0 through 100 { #{$i}% { mask: conic-gradient(#000 #{$i - 10 + '%'}, transparent #{$i + '%'}, transparent); }}}Copy the code

Can realize the image Angle to fade/switch:

CodePen Demo — MASK conic-gradient transition

There are more rich examples of this technique in Zhang Xinxu’s article, which can be read below:

Those CSS transitions you use can be changed

Using this technique, we can achieve many interesting image effects. Something like this:

Mask collision filter with blend mode

Let’s move on to the next step. There are a lot of interesting properties in CSS, and when you combine them with filters and blend modes, they create even more sparks.

Mask & contrast filter: contrast()

First, we implement such a diagram using multiple radial gradients.

{
  background: radial-gradient(#000, transparent);
  background-size: 20px 20px;
}
Copy the code

It looks nothing special, so let’s use the filter: contrast() to change it. The code looks something like this:

html,body { width: 100%; height: 100%; filter: contrast(5); } div { position: relative; width: 100%; height: 100%; background: #fff; &::before { content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: radial-gradient(#000, transparent); background-size: 20px 20px; }}Copy the code

You get this image, you use the contrast filter, you make it very sharp.

At this point, we add different masks. You get all sorts of interesting graphics.

body { filter: contrast(5); } div { position: relative; background: #fff; &::before { background: radial-gradient(#000, transparent); background-size: 20px 20px; + mask: linear-gradient(-180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, .5)); }}Copy the code

CodePen Demo – Contrast with mask

We overlay a linear gradient mask linear-gradient(-180deg, Rgba (255, 255, 255, 1), RGBA (255, 255, 255,.5)). Note that both gradient colors are transparent.

Or use a radial gradient:

{
    mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), # 000 25%);
}
Copy the code

CodePen Demo – Contrast with mask

Ok, so next, just like we did before, we add the animation.

div { ... &::before { background: radial-gradient(#000, transparent); background-size: 20px 20px; mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 25%); animation: maskMove 15s infinite linear; } } @keyframes maskMove { @for $i from 0 through 100 { #{$i}% { mask: repeating-radial-gradient(circle at 35% 65%, #000, rgba(0, 0, 0, .5), #000 #{$i + 10 + '%'}); }}}Copy the code

And look at that, you get a really cool animation:

CodePen Demo – Contrast with mask and animation

Remember to use the Filter: Hue-rotate () hue filter. And with that, we can change the color as well.

CodePen Demo – Contrast with mask and animation 2

Mask & filter: contrast() & blend mode

Next we’ll add the blend mode.

Notice above that our container background color is actually white # FFF.

We can create a different effect by nesting multiple layers, adding a container background color, and overlaying the blend mode.

Without adding the mask, reconstruct the structure. The final pseudocode looks like this:

<div class="wrap">
    <div class="inner"></div>
</div>
Copy the code
.wrap { position: relative; height: 100%; background: linear-gradient(45deg, #f44336, #ff9800, #ffeb3b, #8bc34a, #00bcd4, #673ab7); } .inner { height: 100%; background: #000; filter: contrast(700%); mix-blend-mode: multiply; &::before { content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: radial-gradient(#fff, transparent); background-size: 12px 12px; }}Copy the code

The schematic diagram is as follows:

We can get the following effect:

OK, at this point, the mask hasn’t been applied, so let’s add the mask again.

.wrap { background: linear-gradient(45deg, #f44336, #ff9800, #ffeb3b, #8bc34a, #00bcd4, #673ab7); } .inner { ... filter: contrast(700%); mix-blend-mode: multiply; &::before { background: radial-gradient(#fff, transparent); background-size: 12px 12px; + mask: linear-gradient(#000, rgba(0, 0, 0, .5)); }}Copy the code

CodePen Demo — mask & filter & blend-mode

The actual effect is much better than the screenshot, you can click the Demo to see.

Multiply is mix-blend-mode: multiply, so you can try other blending modes to get different results.

For example, overlay mix-blend-mode: difference, etc., etc.

More interesting superposition, interested students need to try more.

Mask and pictures

Of course, the most essential role of mask should be on the image. Important conclusions from the above:

The overlap between the image and the mask generated gradient transparent will become transparent.

It can also be applied to the image passed in by the mask attribute. In other words, the mask can be passed in the image material, and it will become transparent by following the transparent overlap between the background-image and the mask image.

Using this technique, you can make some really cool transitions:

In fact, this is the image used in the mask:

Then, using a frame-by-frame animation, quickly switch the mask for each frame:

.img1 {
    background: url(image1.jpg) no-repeat left top;
}

.img2 {
    mask: url(https://i.imgur.com/AYJuRke.png);
    mask-size: 3000% 100%;
    animation: maskMove 2s steps(29) infinite;
}

.img2::before {
    background: url(image2.jpg) no-repeat left top;
}

@keyframes maskMove {
    from {
        mask-position: 0 0;
    }
    to {
        mask-position: 100% 0; }}Copy the code

CodePen Demo — Mask makes transitions

Of course, this one can also be animated. This has been done many times, so if you’re interested, you can try it out for yourself.

The last

Having said all this, mask actually belongs to a relatively obscure attribute. There are not many opportunities to apply them in day-to-day business.

And the compatibility is not particularly good, open MDN, you can see that a lot of mask related attributes are still in the laboratory stage.

Of course, even so, from the property itself, I think masks are very interesting and bring more possibilities to CSS.


Ok, this article is over, hope to help you 🙂

More exciting CSS technical articles are summarized in my Github – iCSS, continue to update, welcome to click the star subscription favorites.

If there are any questions or suggestions, you can communicate more, original article, writing style is limited, talent is shallow, if there is something wrong in the article, hope to inform.