Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

Fancy Image Decorations: Masks and Advanced Hover Effects | Style-Tricks

Welcome to Half 2 of this three-part collection! We’re nonetheless adorning pictures with none additional parts and pseudo-elements. I hope you already took the time to digest Half 1 as a result of we’ll proceed working with lots of gradients to create superior visible results. We’re additionally going to introduce the CSS masks property for extra complicated decorations and hover results.

Fancy Picture Decorations collection

  • Single Aspect Magic
  • Masks and Superior Hover Results (you might be right here!)
  • Outlines and Complicated Animations (coming October 28 )

Let’s flip to the primary instance we’re engaged on collectively…

The Postage Stamp

Consider or not, all it takes to make postage stamp CSS impact is 2 gradients and a filter:

img {
  --r: 10px; /* management the radius of the circles */
  padding: calc(2 * var(--r));
  filter: grayscale(.4);
  background: 
    radial-gradient(var(--r),#0000 98%,#fff) spherical
      calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)),
    linear-gradient(#fff 0 0) no-repeat
      50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r));
}

As we noticed within the earlier article, step one is to create space across the picture with padding so we will draw a background gradient and see it there. Then we use a mixture of radial-gradient() and linear-gradient() to chop these circles across the picture.

Here’s a step-by-step illustration that exhibits how the gradients are configured:

Notice using the spherical worth within the second step. It’s crucial for the trick because it ensures the dimensions of the gradient is adjusted to be completely aligned on all the edges, it doesn’t matter what the picture width or top is.

From the specification: The picture is repeated as typically as will match throughout the background positioning space. If it doesn’t match an entire variety of occasions, it’s rescaled in order that it does.

The Rounded Body

Let’s have a look at one other picture ornament that makes use of circles…

This instance additionally makes use of a radial-gradient(), however this time I’ve created circles round the picture as a substitute of the cut-out impact. Discover that I’m additionally utilizing the spherical worth once more. The trickiest half right here is the clear hole between the body and the picture, which is the place I attain for the CSS masks property:

img {
  --s: 20px; /* measurement of the body */
  --g: 10px; /* the hole */
  --c: #FA6900; 

  padding: calc(var(--g) + var(--s));
  background: 
    radial-gradient(farthest-side, var(--c) 97%, #0000) 
      0 0 / calc(2 * var(--s)) calc(2 * var(--s)) spherical;
  masks:
    conic-gradient(from 90deg at calc(2 * var(--s)) calc(2 * var(--s)), #0000 25%, #000 0)
      calc(-1 * var(--s)) calc(-1 * var(--s)),
    linear-gradient(#000 0 0) content-box;
}

Masking permits us to point out the realm of the picture — due to the linear-gradient() in there — in addition to 20px round all sides of it — due to the conic-gradient(). The 20px is nothing however the variable --s that defines the dimensions of the body. In different phrases, we have to cover the hole.

Right here’s what I imply:

The linear gradient is the blue a part of the background whereas the conic gradient is the pink a part of the background. That clear half between each gradients is what we minimize from our component to create the phantasm of an interior clear border.

The Interior Clear Border

For this one, we’re not going to create a body however reasonably attempt one thing completely different. We’re going to create a clear interior border inside our picture. In all probability not that helpful in a real-world situation, nevertheless it’s good observe with CSS masks.

Much like the earlier instance, we’re going to depend on two gradients: a linear-gradient() for the interior half, and a conic-gradient() for the outer half. We’ll go away an area between them to create the clear border impact.

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the gap from the sting */

  --_g: calc(100% - 2 * (var(--d) + var(--b)));
  masks:
    conic-gradient(from 90deg at var(--d) var(--d), #0000 25%, #000 0)
      0 0 / calc(100% - var(--d)) calc(100% - var(--d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
}

You’ll have seen that the conic gradient of this instance has a distinct syntax from the earlier instance. Each are purported to create the identical form, so why are they completely different? It’s as a result of we will attain the identical consequence utilizing completely different syntaxes. This will likely look complicated at first, nevertheless it’s a very good characteristic. You aren’t obliged to seek out the resolution to attain a specific form. You solely want to seek out one resolution that works for you out of the various prospects on the market.

Listed below are 4 methods to create the outer sq. utilizing gradients:

There are much more methods to tug this off, however you get the purpose.

There is no such thing as a Greatest™ strategy. Personally, I attempt to discover the one with the smallest and most optimized code. For me, any resolution that requires fewer gradients, fewer calculations, and fewer repeated values is essentially the most appropriate. Typically I select a extra verbose syntax as a result of it offers me extra flexibility to vary variables and modify issues. It comes with expertise and observe. The extra you play with gradients, the extra you already know what syntax to make use of and when.

Let’s get again to our interior clear border and dig into the hover impact. In case you didn’t discover, there’s a cool hover impact that strikes that clear border utilizing a font-size trick. The thought is to outline the --d variable with a worth of 1em. This variables controls the gap of the border from the sting. We will rework like this:

--_d: calc(var(--d) + var(--s) * 1em)

…giving us the next up to date CSS:

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the gap from the sting */
  --o: 15px; /* the offset on hover */
  --s: 1;    /* the path of the hover impact (+1 or -1)*/

  --_d: calc(var(--d) + var(--s) * 1em);
  --_g: calc(100% - 2 * (var(--_d) + var(--b)));
  masks:
    conic-gradient(from 90deg at var(--_d) var(--_d), #0000 25%, #000 0)
     0 0 / calc(100% - var(--_d)) calc(100% - var(--_d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
  font-size: 0;
  transition: .35s;
}
img:hover {
  font-size: var(--o);
}

The font-size is initially equal to 0 ,so 1em can also be equal to 0 and --_d is be equal to --d. On hover, although, the font-size is the same as a worth outlined by an --o variable that units the border’s offset. This, in flip, updates the --_d variable, shifting the border by the offset. Then I add one other variable, --s, to manage the signal that decides whether or not the border strikes to the within or the surface.

The font-size trick is de facto helpful if we wish to animate properties which might be in any other case unanimatable. Customized properties outlined with @property can resolve this however support for it continues to be missing on the time I’m penning this.

The Body Reveal

We made the next reveal animation within the first a part of this collection:

We will take the identical concept, however as a substitute of a border with a strong coloration we’ll use a gradient like this:

For those who evaluate each codes you’ll discover the next modifications:

  1. I used the identical gradient configuration from the primary instance contained in the masks property. I merely moved the gradients from the background property to the masks property.
  2. I added a repeating-linear-gradient() to create the gradient border.

That’s it! I re-used many of the similar code we already noticed — with tremendous small tweaks — and received one other cool picture ornament with a hover impact.

/* Strong coloration border */

img {
  --c: #8A9B0F; /* the border coloration */
  --b: 10px;   /* the border thickness*/
  --g: 5px;  /* the hole on hover */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at high var(--b) proper var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b)) no-repeat,
    conic-gradient(at backside var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200% no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}
/* Gradient coloration border */

img {
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the hole on hover */
  background: repeating-linear-gradient(135deg, #F8CA00 0 10px, #E97F02 0 20px, #BD1550 0 30px);

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, #000 0;
  masks: 
    conic-gradient(from 180deg at high var(--b) proper var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b)) no-repeat,
    conic-gradient(at backside var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200% no-repeat,
    linear-gradient(#000 0 0) content-box;
  transition: .3s, mask-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, mask-size .3s .3s;
}

Let’s attempt one other body animation. This one is a bit tough because it has a three-step animation:

Step one of the animation is to make the underside edge greater. For this, we modify the background-size of a linear-gradient():

You’re in all probability questioning why I’m additionally including the highest edge. We’d like it for the third step. I at all times attempt to optimize the code I write, so I’m utilizing one gradient to cowl each the highest and backside sides, however the high one is hidden and revealed later with a masks.

For the second step, we add a second gradient to point out the left and proper edges. However this time, we do it utilizing background-position:

We will cease right here as we have already got a pleasant impact with two gradients however we’re right here to push the boundaries so let’s add a contact of masks to attain the third step.

The trick is to make the highest edge hidden till we present the underside and the edges after which we replace the mask-size (or mask-position) to point out the highest half. As I mentioned beforehand, we will discover lots of gradient configurations to attain the identical impact.

Right here is an illustration of the gradients I will likely be utilizing:

I’m utilizing two conic gradients having a width equal to 200%. Each gradients cowl the realm leaving solely the highest half uncovered (that half will likely be invisible later). On hover, I slide each gradients to cowl that half.

Here’s a higher illustration of one of many gradients to provide you a greater concept of what’s taking place:

Now we put this contained in the masks property and we’re executed! Right here is the total code:

img {
  --b: 6px;  /* the border thickness*/
  --g: 10px; /* the hole */
  --c: #0E8D94;

  padding: calc(var(--b) + var(--g));
  --_l: var(--c) var(--b), #0000 0 calc(100% - var(--b)), var(--c) 0;
  background:
    linear-gradient(var(--_l)) 50%/calc(100% - var(--_i,80%)) 100% no-repeat,
    linear-gradient(90deg, var(--_l)) 50% var(--_i,-100%)/100% 200% no-repeat;  
  masks:
    conic-gradient(at 50% var(--b),#0000 25%, #000 0) calc(50% + var(--_i, 50%)) / 200%,
    conic-gradient(at 50% var(--b),#000 75%, #0000 0) calc(50% - var(--_i, 50%)) / 200%;
  transition: 
    .3s calc(.6s - var(--_t,.6s)) mask-position, 
    .3s .3s background-position,
    .3s var(--_t,.6s) background-size,
    .4s rework;
  cursor: pointer;
}
img:hover {
  --_i: 0%;
  --_t: 0s;
  rework: scale(1.2);
}

I’ve additionally launched some variables to optimize the code, however you need to be used to this proper now.

What a couple of four-step animation? Sure, it’s potential!

No clarification for this as a result of it’s your homework! Take all that you’ve got realized on this article to dissect the code and attempt to articulate what it’s doing. The logic is much like all of the earlier examples. The bottom line is to isolate every gradient to know every step of the animation. I saved the code un-optimized to make issues slightly simpler to learn. I do have an optimized version if you’re , however you too can attempt to optimize the code your self and evaluate it with my model for added observe.

Wrapping up

That’s it for Half 2 of this three-part collection on artistic picture decorations utilizing solely the <img> component. We now have a very good deal with on how gradients and masks will be mixed to create superior visible results, and even animations — with out reaching for additional parts or pseudo-elements. Sure, a single <img> tag is sufficient!

Now we have another article on this collection to go. Till then, here’s a bonus demo with a cool hover impact the place I exploit masks to assemble a damaged picture.

Fancy Picture Decorations collection

  • Single Aspect Magic
  • Masks and Superior Hover Results (you might be right here!)
  • Outlines and Complicated Animations (coming October 28 )

Add a Comment

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?