Pure CSS Halftone Effect

2 minutes read · 2018-02-24
Mona Lisa (Prado's version)

The demo above uses CSS filters, gradients and blend modes to approximate a CMY halftone effect in pure CSS.

Surprisingly, the resulting animation runs at a reasonable framerate even on my 2-year-old phone. Not bad!

Browser Comparison

Inconsistencies in color handling and hardware acceleration cause the effect to render and perform differently across browsers and operating systems.

For fun, here's a (rather subjective) comparison of how the effect looks and performs across a variety of browsers:

Browser (Platform)VisualsPerformance
Firefox (Win)AB
Firefox (Mac)AD
Chrome (Win)CA
Chrome (Mac)CA
Safari (Mac)AA
Safari (iOS)AA
Edge (Win)F*


.halftone {
    background: white;
    position: relative;
    filter: contrast(25000%);
    overflow: hidden;
    transform: translateZ(0); /* force a HW accelerated layer */

.halftone > * {
    filter: brightness(0.5) blur(4px);
    animation: 10s animation-filter infinite alternate;

.halftone::after {
    content: '';
    position: absolute;
    top: -100%;
    left: -100%;
    right: -100%;
    bottom: -100%;
    background-blend-mode: multiply;
        radial-gradient(8px 8px, cyan, white),
        radial-gradient(8px 8px, magenta, white),
        radial-gradient(8px 8px, yellow, white);
    background-size: 8px 8px;
    background-position: 0 -3px, -2px 0, 2px 0;
    mix-blend-mode: screen;
    pointer-events: none;
    transform: rotate(11.25deg);
    transition: 1s ease-in-out transform;
    z-index: 1;
    animation: 10s animation-overlay infinite alternate;

@keyframes animation-overlay {
    0% {
        transform: rotate(45.25deg) scale(10);

    100% {
        transform: rotate(11.25deg);

@keyframes animation-filter {
    0% {
        filter: brightness(0.5) blur(40px);

    100% {
        filter: brightness(0.5) blur(4px);
View on CodePen

* Microsoft Edge doesn't support CSS filters or blend modes, so the effect doesn't work at all.