42

I want to use a 4:3 video as a background on a site. However, setting the width and height to 100% doesn't work since the aspect ratio is kept intact, so the video doesn't fill the whole width of the site.

Here is my HTML and CSS code.

HTML:

<!DOCTYPE HTML>
<html land="en">

<head>

<link rel="stylesheet" type="text/css" href="html5video.css" />


<title>html 5 video test</title>


</head>

<body id="index">

<video id="vidtest" autoplay>
<source src="data/comp.ogv" type="video/ogg" width="auto" >
</video>

<div class="cv">

<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>

</div>


</body>
</html>

CSS:

body
{
background-color:#000000;
}



#vidtest {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
width: 200%;
height: 100%;
z-index: -1000;
}

.cv
{
width: 800px;
position:relative;
text-align:center;
margin-top: 100px;
color:#FFFFFF;
font-family:"Arial";
font-size: 10px;
line-height: 2em;
text-shadow: 3px 3px 2px #383838;
margin-left: auto;
margin-right: auto;
}
Null
  • 1,950
  • 9
  • 30
  • 33
Roland
  • 1,908
  • 4
  • 21
  • 34

10 Answers10

118

this a really old thread, I know, and what I'm proposing is not necessarily the solution you are looking for, but for all people that land here because of searching what I searched: scale the video to fill the video container element, keeping ratio intact

If you want the video to fill the size of the <video> element but the video is scaled correctly to fill the container while keeping the aspect ratio in tact you can do this with CSS using object-fit. Much like background-size for background images you can use the following:

video {
    width: 230px;
    height: 300px;
    object-fit: cover;
}

I hope this can be of help for some people.

EDIT: works in most browsers but IE

Mathias
  • 2,484
  • 1
  • 19
  • 17
  • 21
    object-fit: cover; OMG I LOVE YOU – moeiscool Nov 26 '16 at 19:47
  • 3
    It's sad that despite the combined humanitarian efforts of Google, Mozilla, and Otello, so many still suffer from IE. – dynamichael Sep 15 '18 at 04:31
  • 1
    So nice, works like a charm. Just a note here that object-fit: fill will cause the image to skew the ratio as it scales, which seems to be what the OP was asking for. – Nathan Mar 03 '20 at 17:04
  • 2
    Agree with @Nathan, `object-fit: fill;` is what the OP and I were looking for, but thanks a lot for showing the right direction! ;) – Jay Dadhania Aug 09 '20 at 01:19
  • Thank you! This really helped! In my specific case, I needed to set `object-fit: fill;`, as Chrome appears to default to `object-fit: contain;` in the user agent stylesheet. – sbgib Nov 13 '20 at 15:49
  • The problem with that is that being cover, the video edges are not visible and if you need a snapshot the resulting snapshot is larger than the visible part of the video. – Adrian P. Apr 04 '21 at 23:23
  • object-fit: cover and height: 100% are closer to what I think most people would want. – Emperor Eto Jul 07 '22 at 13:38
14


you can use:

min-width: 100%;
min-height: 100%;

http://www.codesynthesis.co.uk/tutorials/html-5-full-screen-and-responsive-videos

Ouadie
  • 13,005
  • 4
  • 52
  • 62
  • 2
    Surely this would be max-width: 100%; max-height: 100%; with the width and height properties set to 100vw and 100vh respectively and object-fit and possibly margin auto ? – MrMesees Aug 17 '20 at 09:40
10

http://dev.opera.com/articles/view/everything-you-need-to-know-about-html5-video-and-audio/

[...] in the same way as the img element — if you only set one of width and height, the other dimension is automatically adjusted appropriately so that the video retains its aspect ratio. However — unlike the img element — if you set width and height to something that doesn't match the aspect ratio of the video, the video is not stretched to fill the box. Instead, the video retains the correct aspect ratio and is letterboxed inside the video element. The video will be rendered as large as possible inside the video element while retaining the aspect ratio.

drudge
  • 35,471
  • 7
  • 34
  • 45
  • 1
    thanks, where is the best place to complain about this though? Its just an unneeded restiction in my opinion. – Roland Oct 24 '10 at 11:53
  • you could always use the space where the video **isn't** playing to add widgets and things. :) – drudge Oct 24 '10 at 19:32
  • @Roland The HTML5 specifications are still in the drafting stages, so if you want to complain I'm sure you can look for ways to do so :) – Yi Jiang Jan 01 '11 at 12:07
  • true Yi! I am not too sure though whom to write about this ;) the W3c site isn't exactly user friendly in this regard – Roland Aug 08 '11 at 17:40
9

What worked for me is

video {
object-fit: fill;
}
JAck
  • 99
  • 1
  • 1
8

Picked this up yesterday and have been wrestling for an answer. This is somewhat similar to Jim Jeffers suggestion, but it works for x and y scaling, is in javascript syntax and only relies on jQuery. It seems to work pretty well:

function scaleToFill(videoTag) {
    var $video = $(videoTag),
        videoRatio = videoTag.videoWidth / videoTag.videoHeight,
        tagRatio = $video.width() / $video.height();
    if (videoRatio < tagRatio) {
        $video.css('-webkit-transform','scaleX(' + tagRatio / videoRatio  + ')')
    } else if (tagRatio < videoRatio) {
        $video.css('-webkit-transform','scaleY(' + videoRatio / tagRatio  + ')')
    }
}

You'll run into some issues if you are using the native controls as you can see in this fiddle: http://jsfiddle.net/MxxAv/

I have some unusual requirements because of all the abstraction layers in my current project. Because of that I'm using a wrapper div in the example and scaling the video to 100% inside the wrapper to prevent problems in some of the corner cases I have encountered.

Shane
  • 4,921
  • 5
  • 37
  • 53
5

If the object-fit property is not working for you (WebView, Android, etc.), you can calculate the height of your video yourself.

For example, for video 16:9 the height is calc(100vw * 9 / 16)

.video-wrapper {
    width: 100%;
    height: calc(100vw * 9 / 16);
    position: relative;
}

video {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
}
Dmitry Grinko
  • 13,806
  • 14
  • 62
  • 86
1

I use this to fill either width OR height... (requires jQuery) This KEEPS the aspect ratio and fills the div. I know the question was to break the aspect ration, but it isn't necessary.

var fillVideo = function(vid){
    var video = $(vid);
    var actualRatio = vid.videoWidth/vid.videoHeight;
    var targetRatio = video.width()/video.height();
    var adjustmentRatio = targetRatio/actualRatio;
    var scale = actualRatio < targetRatio ? targetRatio / actualRatio : actualRatio / targetRatio;
    video.css('-webkit-transform','scale(' + scale  + ')');
};

as long as the <video> has width and height set to 100% and your container div has css overflow:hidden just pass it the video tag.

var vid = document.getElementsByTagName("video")[0];
fillVideo(vid);
Mulhoon
  • 1,852
  • 21
  • 26
0

The correct CSS option for this is object-fit: contain;

The following example will stretch a background image across the width of the screen (while BREAKING the aspect ratio), and maintaining a constant fixed height.

body {
    background-image:url(/path/to/background.png)
    background-repeat: no-repeat;
    background-position: top center;
    background-size: 100% 346px;
    object-fit: contain;
}

For a video in the OP's context it would then be:

video#vidtest {
    width: 100%;
    height: 100%;
    object-fit: contain;
}
user2121874
  • 171
  • 1
  • 8
0

After some struggling, this is what I ended up with. It will automatically scale the video in the right moment.

var videoTag = $('video').get(0);
videoTag.addEventListener("loadedmetadata", function(event) {
   videoRatio = videoTag.videoWidth / videoTag.videoHeight;
   targetRatio = $(videoTag).width() / $(videoTag).height();
    if (videoRatio < targetRatio) {
      $(videoTag).css("transform", "scaleX(" + (targetRatio / videoRatio) + ")");
    } else if (targetRatio < videoRatio) {
      $(videoTag).css("transform", "scaleY(" + (videoRatio / targetRatio) + ")");
    } else {
      $(videoTag).css("transform", "");
    }
});

Just put that code in a $(document).ready() block.

Tested on Chrome 53 , Firefox 49, Safari 9, IE 11 (IE does scale the video correctly, but might do other funny stuff around it though).

jox
  • 2,218
  • 22
  • 32
0

I found that the only solution for this problem is that you increase the video width and height by rem units, like so:

width: 188rem;
height: 60rem;
position: relative;
-o-object-fit: cover;
object-fit: cover;

and if you have an overlay div that is sibling to the video tag set it's height to 100%

and finally set the parent height to match the video tag height in this case:

text-align: center;
position: relative;
overflow: hidden;
height: 60rem;

That what worked for me.

Omar Hegazi
  • 122
  • 1
  • 6