Skip to content

Software Engineer at Polygon

Background video made easy

We love videos! It’s a pleasure for our eyes to see a little bit of modern looking movement on a website. Unfortunately our browser doesn’t love videos like we do. Good performance isn’t a friend with videos neither. I have come across many websites with autoplayed videos hosted on Vimeo or youtube that use crazy amount of bandwidth. Some minimal looking websites with full HD video in the background even triggered the fans on my laptop. I believe that there is nothing wrong with using a looped video as a background, as long as it is done correctly. Have a look at Squarespace, This Also or Big Cartel to name few — it looks nice.

HTML5 introduced the video tag and list of settings which we can control via attributes or via JavaScript media events. Browser support is really great — luckily I don’t have to target IE8 anymore. If you need to, I’m really sorry but this tutorial won’t cover any fallback. We are going to create a section and with small positioning trick apply a background video that will always cover the entire space of this section. Essentially it behaves exactly the same as background-size: cover; in CSS. If you still don’t get it, have a look at the picture below. Kate, I love you!

background-size: cover in CSS

Let’s have a word about videos & performance #

It’s worth mentioning that if performance is something that you would like to improve, you should leave this article now. Companies like PayPal or The Royal Albert Hall prioritised speed over visual experiences and recently removed videos from their websites. You need to know what the main aim of your project is and bare in mind the cost that the video comes with.

Markup and CSS #

Less talk more action.

<div class="banner">
  <video autoplay loop muted class="banner__video" poster="video.jpg">
    <source src="video.webm" type="video/webm">
    <source src="video.mp4" type="video/mp4">
  </video>
</div>

That’s all we need. As you can see I have added some attributes to video tag. Hopefully autoplay, loop and muted don’t need any explanation. poster includes a path to the image that will be displayed on the mobile devices. When the video isn’t ready or it’s paused, you browser will show this poster instead. It is a good practice to create a poster from the first frame of your video.

Multiply source element is needed to provide a cross browser experience. If you need to support old Firefox browsers you need to add ogg format as well. You can generate all those formats with tools like Miro Converter or my favourite online HTML5 Video Converter. Please control the size of your files. It is a difficult task to find a compromise between length, quality and file size. I always try to compress my videos to something between 500kb - 1000kb, and avoid videos longer than 10 - 15 seconds. HandBrake is open source video transcoder that can help you with compression.

.banner {
  position: relative;
  overflow: hidden;
}

.banner__video {
  position: absolute;
  top: 50%;
  left: 50%;
  width: auto;
  min-width: 100%;
  height: auto;
  min-height: 100%;
  transform: translateX(-50%) translateY(-50%);
  z-index: -1;
}

This is the trick. Position everything on centre, add minimum width and height to fill the space of the parent div, hide everything that is outside of the box, and place the video behind the content of the parent.

We made it, it works fine but that doesn’t mean it can’t be improved. Let’s have a look at few more tricks that can enhance this effect and the user experience.

Video poster on iOS #

Mobile browsers are very clever and they ignore autoplay attribute to save valuable bandwidth. All Android devices will display the poster image but iOS devices will display huge play button in the middle of a player. It sucks.

Play icon iOS video tag

We definitely don’t want to keep it like that. A few lines of JavaScript comes in help here. Essentially we need to grab the value of the poster attribute and apply it as a background-image of the parent element. Additionally we need to add a correct background-size and background-position to this div and hide video tag. Done!

var banner = document.querySelector('.banner');
var bannerVideo = document.querySelector('.banner__video');

if (/iPad|iPhone|iPod/.test(navigator.platform)) {
  banner.style.backgroundImage = 'url("' + bannerVideo.poster + '")';
  banner.style.backgroundSize = 'cover';
  banner.style.backgroundPosition = 'center';
  bannerVideo.style.display = 'none';
}

A little bit of make up #

If we cannot provide high quality video, we need to find a way to mask artifacts. We need to create a small pattern and then overlay it over the video by adding a background-image on the parent element. These files are normally very small so we can easily convert them to base64 data to save server requests (it doesn’t really matter in age of HTTP2). If you use Emmet in Sublime Text or Atom, you can use a shortcut Shift + Ctrl + D.

ENcode Decode base 64 Emmet in Sublime Text 3

Paternity is a super cool tool that you can use to quickly generate base64 patters. It takes few seconds to create one and get a code to paste straight into your project. I created few ready to copy/paste examples for you.

See the Pen JGjLeM by Pawel Grzybek (@pawelgrzybek) on CodePen.

Final result #

Hopefully you found it useful. If you have any advice on how can I improve my technique, please let me know in the comments below. If you liked it, please follow me on twitter to don’t miss future articles on my blog.

See the Pen Background video test by Pawel Grzybek (@pawelgrzybek) on CodePen.

Comments

  • K
    Kim Ruddock

    Another great post Pawel and a nice clever solution for iOS. Out of interest what is the size of that skate video in the pen at the bottom?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thank you mate. Size of a video is very small, thats why I put this raster pattern on top of it. Exact size is 562 × 332 px. Despite small size I think it looks good enough as a looped background.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • E
    Emeraldo

    I am testing it on iPad and it doesn't work, sorry. Just put this page URL on an iPad safari and check if the video background right here is playing. It doesn't. Do you have any tricks to solve it? Thank you.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Are you sure that you read the whole post before commenting?

      https://pawelgrzybek.com/ba...

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • J
    Joshua Duncan

    If you want your video to play on mobile browsers use BrowsePlay as your cdn and it will work.

    https://browseplay.com

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • K
    Kirsty Harris

    This is quite buggy imho. Ive used this, and on page refresh your vid disappears :S

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Can you show me a CodePen example with your implementation? It work like a charm for me on multiple projects.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • C
    Chris Nguyen

    Can you still use vimeo with this as your src?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Yes, sure! Just instead of using a `video` tag use an `iframe` from your video provider. I am sure it will look amazing!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • K
    Katherine

    Thanks a million, so helpful, saved my bacon!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      I am glad that it helped you out. This is nearly 6 years old article so there is a high chance that there is a better way of doing it, but there is nothing wrong with the solution above. I am glad my article helped you out :)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!