Cannot change color of html5 video black bars in IE and iOS

18,600

Solution 1

I think I've managed to come up with a solution:

The problem is that it seems to be impossible to style these letterboxes cross-browser. So the trick then would be not to have letterboxes, by scaling the video element to the aspect ratio of the video file.

This solution has two potential drawbacks:

  1. it requires Javascript
  2. you need to know the dimensions of the video file and write them into data-attributes

    <video data-video-width="320" data-video-height="240" controls>
    

The reason for this is that the browser does not know the dimensions of the video file until it has started loading it. Most browsers do load a few bytes of the video before it is played, but not all - some older versions of Android wait until the user starts playing the video.

If you do not care about Android 2.3, waiting for the loadedmetadata event to get videoWidth and videoHeight as jaicabs answer does it is the right way.

Take a look at this: run fiddle / fiddle editor

We basically do three things:

  1. calculate the aspect ratio of the video
  2. resize it so that it fits snugly into its container
  3. center it horizontally and vertically within the container

You can now simply set the background-color of the container, and you're done.

I've tested it with iOS 7 on iPhone and iPad, Chrome, Firefox and Safari. No IE testing so far, since I currently don't have my virtual machines handy, but I foresee no problems here for the current IEs.

Solution 2

Solved! Link to the live jsbin: http://jsbin.com/AVOZoXu/9
The edit jsbin to follow the explanation: http://jsbin.com/AVOZoXu/9/edit
I couldn't test it on IE but it should work like a charm.

There is a real problem with iOS. You won't be able to set a background color to the player and the default player size is 150x300 as you can see in Safari Developer Library:

Because the native dimensions of a video are not known until the movie metadata loads, a default height and width of 150 x 300 is allocated on devices running iOS if the height or width is not specified. Currently, the default height and width do not change when the movie loads, [...]

So, what you have to do to remove the black bars is do change the default size and adapt it to the movie size as soon as you can. And yes, we'll need JavaScript.

// set height and width to native values
function naturalSize() {
  var myVideo = document.getElementById('theVideo');
  var myContent = document.getElementById('content');
  myVideo.height = myVideo.videoHeight;
  myVideo.width = myVideo.videoWidth;

  //if the video is bigger than the container it'll fit
  ratio = myVideo.videoWidth/myVideo.videoHeight;
  if(parseInt(myContent.offsetWidth,10)<myVideo.videoWidth){
   myVideo.height = myVideo.videoHeight*parseInt(myContent.offsetWidth,10)/myVideo.videoWidth;
     myVideo.width=parseInt(myContent.offsetWidth,10); 
  }
}
// register listener function on metadata load
function myAddListener(){
  var myVideo = document.getElementById('theVideo');
  myVideo.addEventListener('loadedmetadata', naturalSize, false);
}

window.onload = myAddListener();

And now you'll get a video player size of the video as soon as the meta data loads. Since the video doesn't have its black bars anymore, I just had to center it as text.

Oh! And you wanted it to be responsive? Check it out, it doesn't matter the width you set to the #content because naturalSize() checks the ratio and the container's width and sets a smaller height for the video than the original, preventing the black bars appearing in original video height with a smaller width.

The width is controlled with the max-width:100%; property so there's no need to change it manually.

#content{
  background:blue;
  width:50%;
  height:auto;
  text-align:center;
}
video {
  max-width:100%;
  vertical-align:top;
}

I know, I know, the video doesn't get resized till you have started playing it, but it's the closest you're gonna get on iOS to do what you want. Anyway, I think it's a great solution, I hope it helps you.

Solution 3

How about div with css as background? [I'm not familiar with iOS, tasted on IE11]

html:

<div id="container"> 
<video width="320" height="240" controls>
  <source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
  <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
</div>

CSS:

video {
    display: block;
    margin-left: auto;
    margin-right: auto;
}
#container{
    width: 500px;
    height: 240px;
    background: blue;
}

jsfiddle: http://jsfiddle.net/c9aHf/1/

Solution 4

I know some time has already passed since the question was asked, but I also had to implement a workaround for this problem and would like to share. The problem was similar to OP's, in that the video could be any size or aspect ratio.

If the HTML <video> element is contained within a <div> which specifies no size at all, the container will automatically fit itself around the video and it will have no black "padding".

Knowing this, we can take advantage of the loadedmetadata event: we don't actually need the video's dimensions for any calculations, but we must wait for this data to load so that the container will resize. As soon as that happens, we can adjust the container's position horizontally and/or vertically.

Here's a fiddle tested in IE11:

http://jsfiddle.net/j6Lnz31y/

Source (in case the fiddle ever becomes unavailable):

<div class="whatever-container" style="width:200px; height:600px; background-color:red;">
        <div class="video-container">
            <video controls>
              <source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
              <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
            Your browser does not support the video tag.
            </video>
        </div>
    </div>
    <br />


    <div class="whatever-container" style="width:600px; height:200px; background-color:red;">
        <div class="video-container">
            <video controls>
              <source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
              <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
            Your browser does not support the video tag.
        </video>
        </div>
    </div>

.whatever-container {
    position: relative;
}

.video-container {
    position: absolute;
    opacity: 0;
}

.video-container > video {
    position: relative;
    width: 100%;
    height: 100%;
}

/*
 * After the video dimentions have been acquired, its container will have
 * resized and we can adjust its position as necessary.
 */
function adjustVideoContainer() {
    console.log("video metadata loaded");
    var videoContainer = $(this).parent().filter(".video-container");

    if (videoContainer.length === 0) {
        //abort
        console.log(
            "adjustVideoContainer() was called but no it wasn't "+
            "wrapped in an appropriate container"
        );
        return;
    }
    var containerParent = videoContainer.parent();
    var parentWidth     = containerParent.width(),
        parentHeight    = containerParent.height(),
        containerWidth  = videoContainer.width(),
        containerHeight = videoContainer.height();

    if (containerWidth < parentWidth) {
        videoContainer.css(
            "left",
            (parentWidth - containerWidth) / 2
        );
    }

    if (containerHeight < parentHeight) {
        videoContainer.css(
            "top",
            (parentHeight - containerHeight) / 2
        );
    }
    else {
        videoContainer.height("100%");
    }
    videoContainer.css("opacity", 1);

}

$("video").on("loadedmetadata", adjustVideoContainer);
Share:
18,600

Related videos on Youtube

user319862
Author by

user319862

Updated on June 20, 2022

Comments

  • user319862
    user319862 almost 2 years

    I am attempting to display a video in a responsive design such that the scaling borders blend into the background.

    I allow the dimensions of the video element to vary within specified bounds. As a result, when the video playing doesn't fill the actual html element, I get the black padding bars around my video.

    Using the css background property I have been able to change the color of the bars shown in Chrome, FireFox, and Opera. I cannot figure out how to change the color shown for Internet Explorer or iOS (ipad).

    Can anyone help me out with this?

    fiddle as requested: http://jsfiddle.net/swaEe/

    html:
    
    <video width="320" height="240" controls>
      <source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
      <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
    Your browser does not support the video tag.
    </video>
    
    css:
    
    video {
        width: 500px;
        background: blue;
    }
    

    ***_ edit _***

    This is a better fiddle: http://jsfiddle.net/swaEe/40/

    The video playback should stay vertically and horizontally centered in the container. I want the "bars" to be transparent or the same color as the container (red in this case...).

    <div style="width:200px; height:600px; background-color:red;">
        <video width="100%" height="100%" style="background-color:red;" controls>
          <source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
          <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
        Your browser does not support the video tag.
        </video>
    </div>
    <br />
    <div style="width:600px; height:200px; background-color:red;">
        <video width="100%" height="100%" style="background-color:red;" controls>
          <source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
          <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
        Your browser does not support the video tag.
        </video>
    </div>
    
    • Bram Vanroy
      Bram Vanroy over 10 years
      Can you give us an example or a fiddle?
  • user319862
    user319862 over 10 years
    This fiddle shows the black bars still on IE: jsfiddle.net/X24m4 My video dimensions are set with a percentage padding for responsiveness. They are allowed to change within bounds. I do not want to distort the aspect ratio by setting a hard width or height either. I am trying to get rid of the black bars they cause.
  • user319862
    user319862 over 10 years
    I need the video to maintain an aspect ratio while sizing arbitrarily without black bars. This still shows black bars when the video playing doesn't match the video object dimensions in IE: jsfiddle.net/QHw2G
  • alexander farkas
    alexander farkas over 10 years
    I'm not sure, what you want to demonstrate here. You still use height="240" if you want to make it responsive simply use height="auto".
  • MeNa
    MeNa over 10 years
    What are you trying to do? you want put videos with different sizes in fixed size area?
  • user319862
    user319862 over 10 years
    I have a div that with percentage dimensions (like width=30%, height=100%). The video element is then 100% width and 100% height inside the container. The playback aspect ratio is unlikely to match the block dimensions. IE and iOS show "black bars" when it keeps the playback at the correct aspect ratio instead of blending into the background
  • user319862
    user319862 over 10 years
    Updated fiddle. The container dimensions are set by the viewport. I've demonstrated both cases (excluding the trivial case where the container dimensions equal the video dimensions). The video playback must stay centered because it is in a position:fixed overlay that scrolls with the screen
  • jaicab
    jaicab over 10 years
    Black bars in the horizontal video. It's still getting the 300px default width. Tested on iOS7 Safari, iPad 3g.
  • Mr. Mayers
    Mr. Mayers over 10 years
    Huh. It worked on the iPad I have here. Granted, that's a first-gen iPad... Oh well.
  • user319862
    user319862 over 10 years
    The container dimensions were an example of two states. The actual dimensions are determined by the viewport dimensions with css as a percentage. So two different solutions won't work =( since it is not predictable which state the video will display in.
  • Perry
    Perry over 8 years
    This solution is till working a year and a half later. Thx.

Related