I'm Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with HTML, CSS and SVG. To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

my books

Pro CSS3 Animation book coverPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head CanonMassive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

The New DefaultsThe New Defaults — A Sass color keyword system for designers.

CSSslidyCSSslidy — an auto-generated #RWD image slider. 3.8K of JS, no JQuery.

Automatic Text Contrast with CSS Blend Modes

Fixing text problems with mix-blend-mode

In previous articles I’ve created various graphical effects with CSS blend modes, but potentially one of the most useful applications for blends is within text on web pages.

Contrast is a basic accessibility concern often overlooked by designers in love with subtlety, shading, and thin sans-serif fonts. But contrast becomes an inescapable issue when text crosses into an area similar in color to itself:

body {
text-align: center;
font-family: Montserrat, sans-serif;
color: #000;
background-image: linear-gradient(90deg,#fff 49.9%,#000 50%);
}
h1 {
font-size: 10vw;
}

You can see the result in Figure 1.

Figure 1: Text made illegible by a background

Without any treatment, the second word is completely unreadable. In traditional web design, there just two equally discouraging ways of dealing with this:

  1. Turn the text into an image;

But with blend modes, we can flip the color of the text wherever it crosses into the black background:

h1 {
	color: #fff;
	mix-blend-mode: difference; 
}

The result is what you see at the top of the page.

This remains in effect even if a letter only partially crosses the black-white terminator:

…or if the background is an image:

Progressive Enhancement with Blend Modes

Because Internet Explorer does not yet support blend modes (although it is listed as being “under consideration” for Microsoft Edge), you must ensure that web page text remains legible even if blend modes are not applied. For the example at the top of this page, that’s fairly straightforward: if you can assume that the text always remains on a single line, you could simply make the text black and wrap the second word in a <span> element, coloring it white with CSS, creating the same effect regardless of the browser used.

A more sophisticated approach would be to detect if the browser supported blends and apply color changes based on that information. You could do so using Modernizr:

Modernizr.addTest("mix-blend-mode", function(){
return Modernizr.testProp("mixBlendMode");
});

Or @supports tested via JavaScript:

if ("CSS" in window && "supports" in window.CSS) {
var support = window.CSS.supports("mix-blend-mode","difference");
support = support?"mix-blend-mode":"no-mix-blend-mode";
document.documentElement.className += support;
}

With the following in your stylesheet:

h1 { color: #000; }
.mix-blend-mode body {
background-image: linear-gradient(90deg,#fff 49.9%,#000 50%);
}
.mix-blend-mode h1 { color: #fff; }

Or more directly, via @supports in CSS, with no dependency on JavaScript at all:

@supports (mix-blend-mode: difference) {
body {
background-image: linear-gradient(90deg,#fff 49.9%,#000 50%);
}
h1 { color: #fff; }
}

However you achieve it, the goal is the same: create a web page that looks good without blend modes, and use advanced CSS to enhance it.

Not A Cure-All

As the name implies, difference works best for contrast when the base color is significantly darker than, or the same as, the text color. As the background gets lighter, contrast changes tend to become less effective against white text: you’ll see this by experimenting with color values of the gradient and text in the CodePen demo. difference is not a panacea for a poorly planned color scheme, but it can be very effective in many cases. Explore this code further on CodePen

Photograph by Andrew Stein, licensed under Creative Commons.

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.