SuperGeekery: A blog probably of interest only to nerds by John F Morton.

A blog prob­a­bly of inter­est only to nerds by John F Mor­ton.

Video with transparency in Chrome, Edge, Firefox, Safari, iOS and Android, circa 2022

Transparent video

This post on using video with a trans­par­ent back­ground will prob­a­bly not age well. At least I hope that is the case! Ide­al­ly, in the future, you can use a sin­gle .webm video file and it will work every­where.

But, as I write this post in Jan­u­ary 2022, after a full day of research and try­ing dif­fer­ent approach­es, I’ve got a <video> tag that will play a video with a trans­par­ent back­ground across a wide vari­ety of browsers.

  • Chrome
  • Fire­fox
  • Safari on Desk­top
  • Safari on iPhone
  • Android

I assume that the oth­er browsers based on Chromi­um will also work, although I’ve not test­ed them when I write this.

If you’re try­ing to get a video with trans­paren­cy work­ing, let me show you what I’ve done. I hope this saves you some time.

This post on using video with a trans­par­ent back­ground will prob­a­bly not age well. At least I hope that is the case! Ide­al­ly, in the future, you can use a sin­gle .webm video file and it will work every­where. 

But, as I write this post in Jan­u­ary 2022, after a full day of research and try­ing dif­fer­ent approach­es, I’ve got a <video> tag that will play a video with a trans­par­ent back­ground across a wide vari­ety of browsers.

  • Chrome
  • Fire­fox
  • Safari on Desk­top
  • Safari on iPhone
  • Android

I assume that the oth­er browsers based on Chromi­um will also work, although I’ve not test­ed them when I write this. 

If you’re try­ing to get a video with trans­paren­cy work­ing, let me show you what I’ve done. I hope this saves you some time.


controls = 1 to show player controls color = This parameter specifies the color that will be used in the player's video progress bar to highlight the amount of the video that the viewer has already seen. Valid parameter values are red and white, and, by default, the player uses the color red in the video progress bar. See the YouTube API blog for more information about color options. Note: Setting the color parameter to white will disable the modestbranding option.

Source material

I’m lucky in that I’m start­ing with a nice short piece of pro­fes­sion­al­ly-pro­duced video with an alpha chan­nel. If you don’t have an alpha chan­nel in your source video, you need to solve that prob­lem first.

The source video I had was very big. I used Adobe After Effects to trim and resize it to meet my needs. I want­ed no audio chan­nel on the video which allows me to auto­play the video using Javascript. I also resized the video dimen­sions. Pro tip: web video does not have to be the tra­di­tion­al video aspect ratio.

I export­ed that video using the Apple ProRes 4444 XQ. This will result in a file that is still not usable on the web, but it will be ready for the next step in the process.

Source mate­r­i­al #

I’m lucky in that I’m start­ing with a nice short piece of pro­fes­­sion­al­­ly-pro­­duced video with an alpha chan­nel. If you don’t have an alpha chan­nel in your source video, you need to solve that prob­lem first.

The source video I had was very big. I used Adobe After Effects to trim and resize it to meet my needs. I want­ed no audio chan­nel on the video which allows me to auto­play the video using Javascript. I also resized the video dimen­sions. Pro tip: web video does not have to be the tra­di­tion­al video aspect ratio.

I export­ed that video using the Apple ProRes 4444 XQ. This will result in a file that is still not usable on the web, but it will be ready for the next step in the process.


After effect video export settings

After Effect Output Module Settings


My hardware

Before going fur­ther, you should know I am using an Apple Sil­i­con Mac, a Mac­Book Pro. If you’re on any oth­er plat­form, your result may vary since I use the hard­ware accel­er­a­tion option in one of the video con­ver­sions we’ll dis­cuss below. This does­n’t mean you need a Mac, but I don’t have the hard­ware to test on oth­er plat­forms.

My hard­ware #

Before going fur­ther, you should know I am using an Apple Sil­i­con Mac, a Mac­Book Pro. If you’re on any oth­er plat­form, your result may vary since I use the hard­ware accel­er­a­tion option in one of the video con­ver­sions we’ll dis­cuss below. This doesn’t mean you need a Mac, but I don’t have the hard­ware to test on oth­er plat­forms.


Shutter Encoder

After many tests, I’ve cho­sen Shut­ter Encoder as the best encoder for this process. I tried FFm­peg, Hand­brake, Adobe Media Encoder, and sev­er­al oth­er online video encod­ing ser­vices. None of them worked as well as Shut­ter Encoder, which is free. If you find the app use­ful, you should sup­port the author. I did because I like the soft­ware I use to stick around.

Update, 10MAY2022: When I wrote this post orig­i­nal­ly, I used Shut­tle Encoder ver­sion 15.7 dur­ing the encod­ing process. I worked on encod­ing anoth­er video, as described here, using Shut­tle Encoder ver­sion 15.9, which failed. Based on what I’ve read, there is some issue with FFM­PEG in ver­sions after 15.7. Rein­stalling ver­sion 15.7 allowed me to con­tin­ue to con­vert videos suc­cess­ful­ly. I hope the bug is fixed in future ver­sions of the soft­ware.

Update, 25MAY2023: I recent­ly went through the process of cre­at­ing a video with an alpha chan­nel, as described in this post. I’m hap­py to report that using Shut­ter Encoder ver­sion 17.1, the cur­rent ver­sion as of May 2023, suc­cess­ful­ly encodes the alpha chan­nel. Based on the changel­og, it looks like this was fixed in Shut­ter Encoder ver­sion 16.8.

Creating a webm version of the video

I’ve made two ver­sions of the video. The first is a .webm ver­sion. Shut­ter Encoder will allow you to pre­serve the alpha chan­nel when you’re cre­at­ing your webm. Let’s review the options I used.

Shut­ter Encoder #

After many tests, I’ve cho­sen Shut­ter Encoder as the best encoder for this process. I tried FFm­peg, Hand­brake, Adobe Media Encoder, and sev­er­al oth­er online video encod­ing ser­vices. None of them worked as well as Shut­ter Encoder, which is free. If you find the app use­ful, you should sup­port the author. I did because I like the soft­ware I use to stick around.

Update, 10MAY2022: When I wrote this post orig­i­nal­ly, I used Shut­tle Encoder ver­sion 15.7 dur­ing the encod­ing process. I worked on encod­ing anoth­er video, as described here, using Shut­tle Encoder ver­sion 15.9, which failed. Based on what I’ve read, there is some issue with FFM­PEG in ver­sions after 15.7. Rein­stalling ver­sion 15.7 allowed me to con­tin­ue to con­vert videos suc­cess­ful­ly. I hope the bug is fixed in future ver­sions of the soft­ware.

Update, 25MAY2023: I recent­ly went through the process of cre­at­ing a video with an alpha chan­nel, as described in this post. I’m hap­py to report that using Shut­ter Encoder ver­sion 17.1, the cur­rent ver­sion as of May 2023, suc­cess­ful­ly encodes the alpha chan­nel. Based on the changel­og, it looks like this was fixed in Shut­ter Encoder ver­sion 16.8.

Cre­at­ing a webm ver­sion of the video #

I’ve made two ver­sions of the video. The first is a .webm ver­sion. Shut­ter Encoder will allow you to pre­serve the alpha chan­nel when you’re cre­at­ing your webm. Let’s review the options I used.


Shutter Encoder settings for webm video

Shutter Encoder settings for creating .webm with alpha channel


Add your source video in the Choose files area then select VP9 as your func­tion. Under the Advanced fea­tures area, choose Enable alpha chan­nel.

Now click the Start func­tion but­ton and gen­er­ate your .webm video.

Add your source video in the Choose files area then select VP9 as your func­tion. Under the Advanced fea­tures area, choose Enable alpha chan­nel.

Now click the Start func­tion but­ton and gen­er­ate your .webm video.


Creating an H.265 version of the video, and not an H.264 video

Now that Safari added sup­port for .webm, you might be won­der­ing why we’re mak­ing anoth­er ver­sion of the video at all. In my tests, Safar­i’s sup­port of .webm video does­n’t include sup­port for the alpha chan­nel. A black back­ground is shown where you’d expect the trans­paren­cy to be used.

Why not use an .mp4 with an alpha chan­nel? That’s what we’re going to do, but it’s not the tra­di­tion­al H.264 video you may be famil­iar with.

After a lit­tle online research, you may incor­rect­ly dis­cov­er the .mp4 video file does not sup­port an alpha chan­nel. This was my assump­tion, too, but I was con­flat­ing an mp4 file and an H.264 video file as the same thing. There is a dif­fer­ence though. H.264 is the codec, the piece of soft­ware, that con­verts the uncom­pressed video into a stream of com­pressed bits. The file­type, .mp4 (or .webm, or .avi, etc.) con­tains the stream of video and/​or audio.

In oth­er words, the .mp4 file can use the H.264 codec. The H.264 cod­ed does­n’t sup­port hav­ing an alpha chan­nel. But there is a new­er codec called H.265. Spoil­er alert: it sup­ports the alpha chan­nel.

Using Shut­tle Encoder again, make the H.265 ver­sion of the video. Let’s review the options I used.

Cre­at­ing an H.265 ver­sion of the video, and not an H.264 video #

Now that Safari added sup­port for .webm, you might be won­der­ing why we’re mak­ing anoth­er ver­sion of the video at all. In my tests, Safari’s sup­port of .webm video doesn’t include sup­port for the alpha chan­nel. A black back­ground is shown where you’d expect the trans­paren­cy to be used. 

Why not use an .mp4 with an alpha chan­nel? That’s what we’re going to do, but it’s not the tra­di­tion­al H.264 video you may be famil­iar with. 

After a lit­tle online research, you may incor­rect­ly dis­cov­er the .mp4 video file does not sup­port an alpha chan­nel. This was my assump­tion, too, but I was con­flat­ing an mp4 file and an H.264 video file as the same thing. There is a dif­fer­ence though. H.264 is the codec, the piece of soft­ware, that con­verts the uncom­pressed video into a stream of com­pressed bits. The file­type, .mp4 (or .webm, or .avi, etc.) con­tains the stream of video and/​or audio. 

In oth­er words, the .mp4 file can use the H.264 codec. The H.264 cod­ed doesn’t sup­port hav­ing an alpha chan­nel. But there is a new­er codec called H.265. Spoil­er alert: it sup­ports the alpha chan­nel.

Using Shut­tle Encoder again, make the H.265 ver­sion of the video. Let’s review the options I used.


Shutter Encoder settings for H.265 video

Shutter Encoder settings for creating .mp4 with alpha channel


There are three options in the screen­shot above.

After you’ve added your source video, select H.265 as your func­tion. Under the Advanced fea­tures area, the Enable alpha chan­nel option should be checked auto­mat­i­cal­ly. Also, turn on the Hard­ware accel­er­a­tion option. In my tests, the hard­ware accel­er­a­tion was the only way to get Shut­tle Encoder to cre­ate the alpha chan­nel suc­cess­ful­ly. Depend­ing on your com­put­er, you may achieve dif­fer­ent results when using hard­ware accel­er­a­tion.

Now click the Start func­tion but­ton and gen­er­ate your .mp4 video.

There are three options in the screen­shot above. 

After you’ve added your source video, select H.265 as your func­tion. Under the Advanced fea­tures area, the Enable alpha chan­nel option should be checked auto­mat­i­cal­ly. Also, turn on the Hard­ware accel­er­a­tion option. In my tests, the hard­ware accel­er­a­tion was the only way to get Shut­tle Encoder to cre­ate the alpha chan­nel suc­cess­ful­ly. Depend­ing on your com­put­er, you may achieve dif­fer­ent results when using hard­ware accel­er­a­tion. 

Now click the Start func­tion but­ton and gen­er­ate your .mp4 video.


The video tag for your HTML

Let’s look at <video> tag I’m using.

<video muted playsinline id='ambientVideo'>
  <source src="~@/assets/my_video_H.265_2.mp4" type='video/mp4;codecs=hvc1'>
  <source src="~@/assets/my_video_VP9_3.webm" type="video/webm">
</video>

This video tag is for a small ani­ma­tion that plays inline and it has no audio. You can see those para­me­ters at the begin­ning of the video tag. I also have an id of ambientVideo which I use to trig­ger the ani­ma­tion with an Inter­sec­tion Observ­er that I’ll describe at the end of this post. (Read more about the options for the video tag in the MDN Web Docs.)

The two most impor­tant things are the order of the source tags and the type of each source.

The .mp4 source tag is the first tag. Browsers will see this as the first source, and if they can play it, that’s the one they’ll choose to use. In my tests, Safari on desk­top and on mobile will use this. Be sure you’ve got the type set to include the codecs por­tion. With­out that, you’ll find browsers that think they know how to play a .mp4 try­ing to play that video unsuc­cess­ful­ly because they are not aware of the hvc1 codec.

Next, include the link to the .webm source. This is what most browsers will end up dis­play­ing.

In case you’re won­der­ing, the ~@/assets path is how I refer to the root of my pub­lic fold­er. You need to use the path to the video that makes sense to your envi­ron­ment.

The video tag for your HTML #

Let’s look at <video> tag I’m using.

<video muted playsinline id='ambientVideo'>
  <source src="~@/assets/my_video_H.265_2.mp4" type='video/mp4;codecs=hvc1'>
  <source src="~@/assets/my_video_VP9_3.webm" type="video/webm">
</video>

This video tag is for a small ani­ma­tion that plays inline and it has no audio. You can see those para­me­ters at the begin­ning of the video tag. I also have an id of ambientVideo which I use to trig­ger the ani­ma­tion with an Inter­sec­tion Observ­er that I’ll describe at the end of this post. (Read more about the options for the video tag in the MDN Web Docs.)

The two most impor­tant things are the order of the source tags and the type of each source.

The .mp4 source tag is the first tag. Browsers will see this as the first source, and if they can play it, that’s the one they’ll choose to use. In my tests, Safari on desk­top and on mobile will use this. Be sure you’ve got the type set to include the codecs por­tion. With­out that, you’ll find browsers that think they know how to play a .mp4 try­ing to play that video unsuc­cess­ful­ly because they are not aware of the hvc1 codec. 

Next, include the link to the .webm source. This is what most browsers will end up dis­play­ing.

In case you’re won­der­ing, the ~@/assets path is how I refer to the root of my pub­lic fold­er. You need to use the path to the video that makes sense to your envi­ron­ment.


Bonus: Play video when it appears on the screen

In my video tag, I’ve got an ID of ambientVideo.

I’ve post­ed the Javascript file I’m using in this gist: ambient-video-play-on-enter.js

Since you are here already, I’ll share it in this post too.

var ambientVideo = document.getElementById("ambientVideo");

var io = new IntersectionObserver(
  entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        ambientVideo.play();
      } else {
        ambientVideo.pause();
      }
    });
  },
  {
    root: null,
    rootMargin: "0px",
    threshold: 0.5
  }
);

// after confirming the element exists, look for the #ambientVideo when visible in viewport
if (ambientVideo) {
  io.observe(ambientVideo)
}

In the first line, I look for my video tag with the id of ambientVideo. Next, I cre­ate a new Inter­sec­tionOb­serv­er. Yes, this code could be made to be more reusable, but it works for this pur­pose.

What does this code do?

Basi­cal­ly, when the video ele­ment comes into frame, we tell it to play. When it leaves the frame, it gets paused.

If you want to cus­tomize when the Inter­sec­tion Observ­er trig­gers, check out the Inter­sec­tion observ­er options. As an exam­ple, my thresh­old set­ting of 0.5 means I want to detect the vis­i­bil­i­ty of my video when 50% of it is vis­i­ble. You may need dif­fer­ent set­tings.

To make it work, I have the Inter­sec­tion Observ­er that I cre­ate start observ­ing, look­ing for the ambientVideo video ele­ment.

Good luck!

Bonus: Play video when it appears on the screen #

In my video tag, I’ve got an ID of ambientVideo.

I’ve post­ed the Javascript file I’m using in this gist: ambient-video-play-on-enter.js

Since you are here already, I’ll share it in this post too. 

var ambientVideo = document.getElementById("ambientVideo");

var io = new IntersectionObserver(
  entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        ambientVideo.play();
      } else {
        ambientVideo.pause();
      }
    });
  },
  {
    root: null,
    rootMargin: "0px",
    threshold: 0.5
  }
);

// after confirming the element exists, look for the #ambientVideo when visible in viewport
if (ambientVideo) {
  io.observe(ambientVideo)
}

In the first line, I look for my video tag with the id of ambientVideo. Next, I cre­ate a new Inter­sec­tionOb­serv­er. Yes, this code could be made to be more reusable, but it works for this pur­pose. 

What does this code do? #

Basi­cal­ly, when the video ele­ment comes into frame, we tell it to play. When it leaves the frame, it gets paused. 

If you want to cus­tomize when the Inter­sec­tion Observ­er trig­gers, check out the Inter­sec­tion observ­er options. As an exam­ple, my thresh­old set­ting of 0.5 means I want to detect the vis­i­bil­i­ty of my video when 50% of it is vis­i­ble. You may need dif­fer­ent set­tings.

To make it work, I have the Inter­sec­tion Observ­er that I cre­ate start observ­ing, look­ing for the ambientVideo video ele­ment. 

Good luck!