Since the last post on CSS was popular here is another simple CSS trick that I found useful in the past.

Let’s say we want to find the difference between these two images:

You can do this by simply inverting the colors and then stacking them together at 50% opacity. This can be achieved with a single CSS filter:
-webkit-filter: invert(100%) opacity(50%);

What you should get back is a gray image except for places where the two images differ. This works because inverting will flip the color (255 - c) and opacity will blend the two colors equally (c1 + c2 / 2). So the resulting color is ((255 - c1) + c2) / 2 which is just rgb(127.5, 127.5, 127.5) whenever the overlapping pixel colors c1 and c2 are the same.

Firefox 34 and older doesn’t support this but you can fallback to an equivalent SVG filter:
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='invert' color-interpolation-filters='srgb'><feColorMatrix color-interpolation-filters='srgb' in='SourceGraphic' type='matrix' values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 0 0.5'/></filter></svg>#invert");
Or use mix-blend-mode: difference which actually produces prettier diffs but isn’t supported on Chrome. EDIT(10-2015): Ed in the comments below verified that mix-blend-mode now works on Chrome too! Check out his example.

Doing the visual diff using pure CSS is nice because it is possible even if you don’t have access to the raw pixel data (which is usually only available by loading the image into a canvas or using Chrome extension’s captureVisibleTab). But with CSS you can do a visual diff of any element as long as you can overlap things on top of it.

In particular, let’s say your designer mocked up something in Photoshop and gave it to you as a png to build. To layout elements matching the design, the usual workflow might involve manually measuring dimensions or overlaying a semitransparent mockup as a template. This process is usually pretty tedious since humans are surprisingly bad at detecting changes so you might miss subtle differences between the design and what you built.

So you can use this CSS trick to get a quick visual diff instead. For example, let’s say someone gave you a screenshot of google.com and asked you to replicate it. To help position things you can overlay the inverted mock (see first section of the js tab) and then tweak the dimensions/margin/padding in inspector until everything is aligned:

See the Pen vEGmKR by Franklin Ta (@fta) on CodePen.

When everything is solid gray, you know you got everything pixel perfect!

## 15 thoughts on “Image diffing using CSS”

1. josekerekes says:

Great effect! Though I keep thinking in what other situations I could use this.

2. that’s great, good idea

3. Couple this with the element() CSS function and you could diff arbitrary parts of the page.

1. I was thinking the EXACT same thing.

At the very least this could potentially speed up visual regression testing and at best perhaps let you do continuous UI checks in semi real-time.

4. ed says:

“mix-blend-mode: difference” seems to work fine in Chrome (v45), testing with http://jsfiddle.net/ekeewj53/. Could you elaborate on what was not working?

1. Franklin Ta says:

This post was written a long time ago so the information is probably out of date. I will edit it when I find time. Thanks for the info and the example!

5. Wow! At this rate, soon the police will be using CSS to solve crimes,

6. For regression testing there’s csscritic[1]
From when I was looking at them it was easier to set up than huddle/PhantomCSS

7. DensoDave says:

Didn’t seem to work in IE11. Worked well for other browsers.