CSS blend modes, clipping paths and filters make a number of effects that were previously available only in PhotoShop possible on the web.
One possibility that combines these CSS properties is overlaying images, for before-and-after comparisons or to achieve other visual effects. An example might be the placement of Hugh Jackman’s face over a contemporary photo of Clint Eastwood; particularly effective since both of them possess such similar bone structure and facial features.
For the first example, the markup looks something like this:
<figure id="eastwood-jackman-blend">
<img src="eastwood.jpg" alt="Black and white photograph of Clint Eastwood">
<figcaption>X</figcaption>
<img src="jackman.jpg" alt="Color photograph of Hugh Jackman">
</figure>
This effectively “sandwiches” a capital X between the two photos. Then, applying the following CSS (in this case, written as Sass):
.eastwood-jackman {
width: 40%
padding-top: 50%;
margin: 0;
img, figcaption {
position: absolute;
top: 0;
}
img:last-child {
mix-blend-mode: multiply;
}
figcaption {
font-family: Futura-CondensedExtraBold;
font-weight: 400;
font-size: 45vw
color: hsla(55,100%,50%,0.8);
line-height: .77;
margin-left: 50px;
}
}
By placing mix-blend-mode: multiply
on the last image, it blends with the yellow “X” and photograph beneath it. As the “X” is a true letter, it is extremely adaptable (and because it uses vw
units, responsive); the only problem is that it’s appearance is entirely dependent on the user having that font already installed or embedded. This can never be completely guaranteed, so a better approach might be to clip the upper image. Using much the same markup, for the second example:
<figure id="eastwood-jackman-clip">
<img src="eastwood.jpg" alt>
<img src="jackman.jpg" alt>
</figure>
The opening CSS remains the same, so I’ll just concentrate on the last image in the markup, sans vendor prefixes:
img:last-child {
clip-path: url(#y-shape);
clip-path: polygon(16% 0, 40% 57%, 40% 100%, 72% 100%, 72% 57%, 100% 0, 72% 0%, 57% 28%, 48% 0);
filter: hue-rotate(120deg);
}
I’ve covered the SVG equivalent markup necessary for Firefox to clip the image in an earlier article:
<svg id="shapeclipper">
<defs>
<clipPath id="y-shape" clipPathUnits="objectBoundingBox">
<polygon points=".16 0, .40 .57, .40 1, .72 1, .72 .57, 1 0, .72 0, .57 .28, .48 0" />
</clipPath>
</defs>
</svg>
The result can be quite effective… and entirely written in CSS.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/KwLvYg