Welcome to Half 2 of this three-part collection! We’re nonetheless adorning photographs with none further components 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’re right here!)
- Outlines and Advanced 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 in 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 mix of radial-gradient()
and linear-gradient()
to chop these circles across the picture.
Here’s a step-by-step illustration that reveals how the gradients are configured:
Word the usage of the spherical
worth within the second step. It’s essential for the trick because it ensures the dimensions of the gradient is adjusted to be completely aligned on all the perimeters, it doesn’t matter what the picture width or peak is.
From the specification: The picture is repeated as typically as will match throughout the background positioning space. If it doesn’t match a complete variety of occasions, it’s rescaled in order that it does.
The Rounded Body
Let’s take 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 an alternative 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 both 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 disguise 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 crimson a part of the background. That clear half between each gradients is what we minimize from our aspect to create the phantasm of an internal clear border.
The Inside Clear Border
For this one, we aren’t going to create a body however slightly strive one thing completely different. We’re going to create a clear internal border inside our picture. Most likely not that helpful in a real-world situation, however it’s good follow with CSS masks.
Much like the earlier instance, we’re going to depend on two gradients: a linear-gradient()
for the internal 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 space 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 could have observed that the conic gradient of this instance has a unique syntax from the earlier instance. Each are imagined to create the identical form, so why are they completely different? It’s as a result of we will attain the identical end result utilizing completely different syntaxes. This will look complicated at first, however it’s an excellent function. You aren’t obliged to seek out the answer to realize a specific form. You solely want to seek out one answer that works for you out of the various potentialities on the market.
Listed here are 4 methods to create the outer sq. utilizing gradients:
There are much more methods to drag this off, however you get the purpose.
There isn’t a Finest™ strategy. Personally, I attempt to discover the one with the smallest and most optimized code. For me, any answer that requires fewer gradients, fewer calculations, and fewer repeated values is probably the most appropriate. Generally I select a extra verbose syntax as a result of it provides me extra flexibility to alter variables and modify issues. It comes with expertise and follow. The extra you play with gradients, the extra you understand what syntax to make use of and when.
Let’s get again to our internal 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 concept is to outline the --d
variable with a worth of 1em
. This variables controls the space of the border from the sting. We will remodel 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 space from the sting */
--o: 15px; /* the offset on hover */
--s: 1; /* the route 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 absolutely helpful if we need to animate properties which are in any other case unanimatable. Customized properties outlined with @property
can clear up this however assist for it remains 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 an alternative of a border with a stable shade we’ll use a gradient like this:
For those who examine each codes you’ll discover the next modifications:
- I used the identical gradient configuration from the primary instance contained in the
masks
property. I merely moved the gradients from thebackground
property to themasks
property. - I added a
repeating-linear-gradient()
to create the gradient border.
That’s it! I re-used a lot of the identical code we already noticed — with tremendous small tweaks — and bought one other cool picture ornament with a hover impact.
/* Strong shade border */
img {
--c: #8A9B0F; /* the border shade */
--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 shade 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 strive 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 larger. For this, we regulate the background-size
of a linear-gradient()
:
You’re most likely questioning why I’m additionally including the highest edge. We want 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 realize the third step.
The trick is to make the highest edge hidden till we present the underside and the perimeters after which we replace the mask-size
(or mask-position
) to point out the highest half. As I stated beforehand, we will discover lots of gradient configurations to realize 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 offer you a greater concept of what’s taking place:
Now we put this contained in the masks
property and we’re achieved! Right here is the complete 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 remodel;
cursor: pointer;
}
img:hover {
--_i: 0%;
--_t: 0s;
remodel: scale(1.2);
}
I’ve additionally launched some variables to optimize the code, however you have to be used to this proper now.
What a couple of four-step animation? Sure, it’s doable!
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 just like all of the earlier examples. The secret is to isolate every gradient to grasp every step of the animation. I stored the code un-optimized to make issues just a little simpler to learn. I do have an optimized model in case you are , however you may also attempt to optimize the code your self and examine it with my model for extra follow.
Wrapping up
That’s it for Half 2 of this three-part collection on artistic picture decorations utilizing solely the <img>
aspect. We now have an excellent deal with on how gradients and masks could be mixed to create superior visible results, and even animations — with out reaching for further components or pseudo-elements. Sure, a single <img>
tag is sufficient!
We’ve another article on this collection to go. Till then, here’s a bonus demo with a cool hover impact the place I take advantage of masks
to assemble a damaged picture.
Fancy Picture Decorations collection
- Single Aspect Magic
- Masks and Superior Hover Results (you’re right here!)
- Outlines and Advanced Animations (coming October 28 )