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.

HTML5 Video Effects with CSS Blend Modes

Creating video effects with CSS

Cet article est également disponible en français

Traditional video effects such as filters, cross-fades and blends are usually applied in an editing application, such as Adobe Premiere or Apple’s Final Cut. While there are obvious advantages to such a process, any changes made in an editor are “baked in” to each video frame, and can’t be manipulated or undone once the video is exported.

Yesterday, teaching a class in HTML5 multimedia, I realized that by using CSS filters and the newer blend modes it would be possible to duplicate many of the simpler video effects directly in CSS: the <video> element is like any other, and is equally affected by filter and mix-blend-mode on supporting browsers. This shifts the rendering task onto the GPU of the machine, but the result can still be surprisingly effective.

Simple Color Blends

Before I explain the complete example, let’s take the simpler case of a color overlay, frequently used as a background for text on video. In this case, I’ll use a gradient behind the video itself:

<figure>
<video>
<source src="lina.webm">
<source src="lina.mp4">
</video>
</figure>

The CSS:

figure {
background: linear-gradient(90deg,#00f 50%,transparent 50.1%);
}
figure video {
mix-blend-mode: overlay;
}

Because the gradient is behind the video, it won’t be seen by browsers that don’t support mix-blend-mode: they will only see the video itself.

Video To Black & White

It’s also possible to affect the <video> element with CSS filters, just like images:

video { filter: grayscale(1); }

This can be extremely useful to make quick changes to video without having to convert, edit and re-export the original.

Animated Overlays

Finally, it’s also possible to create more sophisticated effects, as shown in the example at the top of this article. With this HTML:

<figure id="fashion">
<video controls>
<source src="fashion-export.webm">
<source src="fashion-export.mp4">
</video>
<div id="vid-cover"></div>
<figcaption>Summer Sale <span>Now On</span></figcaption>
</figure>
<button id="play-button">Play</button>

And this CSS:

@keyframes overlay {
30% { left: 0; width: 50%; }
50% { background: #00f; }
80% { left: 80%; width: 20%; }
100% { left: 60%; width: 40%; background: #00f; }
}
figure#fashion {
display: inline-block;
position: relative;
font-size: 0; margin: 0;
}
figure#fashion video { width: 100%; }
figure#fashion div {
width: 10%; height: 100%;
background: #f00;
position: absolute; top: 0;
mix-blend-mode: multiply;
left: 0;
}
video.playing ~ div#vid-cover {
animation: overlay 10s forwards;
}
figure#fashion video.playing ~ figcaption {
opacity: 1;
}
figure#fashion figcaption {
font-size: 50px;
font-family: Avenir, sans-serif;
color: white;
position: absolute;
width: 40%; right: 0; top: 30%;
text-transform: uppercase;
text-align: center;
opacity: 0;
transition: 3s 9s opacity;
}
figure#fashion figcaption span {
font-size: 40px;
text-transform: lowercase;
display: block;
}

And a bit of JavaScript applied to the video and associated button:

var playbutton = document.getElementById("play-button");
var fashion = document.querySelector("#fashion video");
fashion.removeAttribute("controls");
playbutton.addEventListener("click", function() {
fashion.play();
fashion.classList.add("playing");
})

The resulting combination plays the result on top of the video, as seen at the top of this article. I’ve deliberately not reset the animations at the end so that you see the result when you play the video again. One potential downside of this approach is that browsers that support CSS animations but not yet mix-blend-mode will have a solid rectangle moving over the video, rather than one that interacts with the pixels of the movie underneath; you could avoid that by placing the moving element underneath the video, as in the first example.

Video by Maximilian Kempe, licensed under Creative Commons. Inspect the code for this example on CodePen

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.