Contrast logos & text with background photos using CSS blend modes

While experimenting with a lightweight photography portfolio, I needed a way to contrast the logo and text in the page header with the photos behind them — regardless of if the photo was dark or light. There are techniques like using box shadows, text shadows, or gradients to lighten/darken the area behind a logo or text, but this is not a perfect solution. Instead, I wanted the logo and text to change colour to contrast with whatever background is beneath it.

Examples of the logo contrasting against different backgrounds

To achieve this I used CSS blend modes. If you have used blend modes in image editing before (e.g. Photoshop) then this will be familiar to you. Blend modes essentially blend the object into the background in different ways. This is different than just modifying opacity in that the blend will differ depending on the luminance values of the object and of the background it is being blended into.

Comparison of opacity (left) vs overlay blend mode (right)

As the name suggests, blend modes are often used to blend two layers together. In my case, however, I wanted to make the two layers stand out from each other. I used a white logo (which is an SVG) and white text with the exclusion blend mode. This results the in the colour of the logo and text being the inverse of the colour of the background photo beneath it.

It’s as simple as adding the mix-blend-mode property to whatever you want to blend:

.blend-me {
mix-blend-mode: exclusion;
}

Also make sure that the layer you want it to blend into is below it (a sibling, not a child) in the DOM. In this example, the h1 will blend into the figure element:

<h1 class="blend-me">Hello world</h1>
<figure>
...
</figure>

Check out the link to my portfolio below to see the live example, or follow me on Instagram to see more photos.