I want to apply an animating glinting effect to certain images on my web page. The images are all randomly shaped and have transparent parts. I want the glint to only be applied to the opaque parts of these images. I have prepared the glint itself in an animated .webp file; it contains moving wavy half-transparent streaks of colors. It is complex enough that I do not want to create it with css (if that is even possible).
My attempt at this was to stack two images on top of each other with position: absolute;
. The lower image is the one to be glinted and the upper one the glint itself. And then apply mix-blend-mode: lighten;
(or overlay, or whatever turns out best) to the glint image. This works, but the glint doesn't contain itself to only the opaque parts of the image.
Now I wonder if this effect can be realized with plain css at all? The alternative is to prepare pre-glinted versions of all relevant images, but due to file size and maintenance concerns I'd rather not do that.
The code I have so far is:
.icon {
position: relative;
display: inline-block;
background-color: #000080;
}
.icon .type {
width: 24px;
height: 24px;
position: absolute;
top: 0px;
left: 0px;
object-fit: none;
object-position: 0px 0px; /* its a css image sprite */
z-order: 10;
}
.icon .glint {
width: 24px;
height: 24px;
position: absolute;
top: 0px;
left: 0px;
z-order: 11;
mix-blend-mode: overlay;
}
<div class="icon">
<img class="type" src="https://omeo.one/images/icons.png">
<img class="glint" src="https://omeo.one/images/glint.webp">
</div>
The icons are just regular 24x24 images arranged in an image sprite (link; the lower half is what I use now as 'glinted' version, but I want to make it animated). I haven't yet finalized the glint image, but I've uploaded a proof of concept (link). I first tried to upload the glint webp image file but StackOverflow refused to take it? To see it in context, my site (OMEO) now uses a static pre-glinted image, next to the item drop downs. For the curious: I want to replicate the Minecraft glinting effect for enchanted items.
If you want the glint to "contain itself to only the opaque parts of the image" then mask is the answer. I also changed the img
s to pseudo elements to tidy up the HTML code a bit.
.icon {
position: relative;
display: inline-block;
background-color: #fff;
width: 24px;
height: 24px;
overflow: hidden;
}
.icon::before {
content: '';
display: block;
position: absolute;
inset: 0;
background-image: url('https://omeo.one/images/icons.png');
background-position: calc(-24px * (var(--index, 1) - 1)) 0px;
}
.icon::after {
content: '';
display: block;
position: absolute;
inset: 0;
background-image: url('https://omeo.one/images/glint.webp');
mix-blend-mode: lighten;
mask-image: url(https://omeo.one/images/icons.png);
mask-position: calc(-24px * (var(--index, 1) - 1)) 0px;
}
.icon:nth-child(2) {
background: #800;
}
.icon:nth-child(3) {
background: #080;
}
.icon:nth-child(4) {
background: #008;
}
.icon:nth-child(5) {
background: #888;
}
<div class="icon" style="--index:1;"></div>
<div class="icon" style="--index:2;"></div>
<div class="icon" style="--index:3;"></div>
<div class="icon" style="--index:4;"></div>
<div class="icon" style="--index:5;"></div>