Chicago

Houston

There are many ways to do text clipping masks (the appearance of graphics or effects inside letterforms) on the web, but the techniques are all somewhat scattershot: Chrome and Safari have long supported -webkit-background-clip:text;, but that only addresses two browsers; there is also an SVG technique, but that has limitations also.

After experimenting with blend modes I realized it was possible to use them to create text clipping masks by “sandwiching” text and backgrounds. One nice advantage is the technique is not only fully cross-browser (with the exception of IE), but it’s also naturally progressive, with elegant fallbacks.

The Technique

The essence of the method is to wrap text with a container element:

<div class="dark">
	<h1>Chicago</h1>
</div>

The text is sized and given a background color that floods its container:

.dark h1 {
	margin: 0;
	font-size: 20vw;
	text-transform: uppercase;
	font-family: Montserrat, sans-serif;
	line-height: 1.9;
	color: #fff;
	background: #000;
}

The colors used will work best if they’re in complete opposition; here I’ve used a black background with white text.

The container is provided with a ; this image won’t be seen at this stage, as it’s obscured by the flood background on the text:

.dark {
	text-align: center;
	background-size: cover;
	background-image: url(chicago.jpg);
}

Finally, mix-blend-mode is applied to the text element, opposite to its background color:

.dark h1 {
	mix-blend-mode: darken;
}

That is, if the background is black, use darken; if the colors are reversed (black text on a white background, like the “Houston” example above) use lighten:

.light h1 {
	mix-blend-mode: lighten;
}

The really great part? If the browser doesn’t support mix-blend-mode, the user just sees the text, against a plain background with maximum contrast. Either way, the text remains true text: you can select it, copy it, and change it at will.

Reversal

If you want the image to take precedence in browsers with no mix-blend-mode support, rather than the text, the code complicates just slightly. The background image becomes a real image, placed on top of the text:

<div class="dark">
	<h1>Chicago</h1>
	<img src="chicago.jpg" alt="Photograph of the Chicago skyline taken from the water during the day">
</div>

The <h1> is treated the same in the CSS, except it lacks any background. The image is positioned absolutely on top of the text.

div.dark {
	text-align: center;
	position: relative;
	background: #000;
}
.dark h1 {
	margin: 0;
	font-size: 20vw;
	text-transform: uppercase;
	font-family: Montserrat, sans-serif;
	line-height: 1.9;
	color: #fff;
}
div.dark img { 
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
}

Then the image is set to the appropriate mix-blend-mode:

.dark img {
	mix-blend-mode: darken;
}

Again, the opposite effect (black text, white background) is also achievable; see the CodePen demo for more details. Visually, the effect is the same as the first example; the only difference is which element takes precedence during selection and graceful degradation.

Conclusion

Blend modes are one of the newest aspects of CSS, and have untapped richness for design and UI. In the next article, I’ll look at still more possibilities with text and blends.

Photographs by Daniel Schwen and Ron Kikuchi, licensed under Creative Commons.