HTML5 video fit width OR height
Asked Answered
A

9

18

The width=100% height="auto" scales my videos to fit the whole width of the browser window, but if the height of the window is lower than the aspect ratio the video gets cropped in height.

I want the video to scale to fit either width or height so that I can always see the whole video without crop, filling the closest ratio (adding empty space to sides if window ratio is lower).

I can't figure out how to do this however.
First any height value, % or px, seems to be disregarded, I can't set the size at all using height, only width. Same for min-width/height.

How can this be done?

My code:

<video id="video" width=100% height="auto" onclick=playPause()></video>

Video is loaded by javascript where v is a video link from an array:

video.addEventListener('play', function() { v.play();}, false);
Allyson answered 4/1, 2016 at 12:36 Comment(3)
Have you checked out fitvidsjs.com ?Sora
Checked it now and it seems to be scaling only based on width as well. Seems to be an old method predating html5 video and width="auto".Allyson
Does this answer your question? HTML5 Video dimensions in Safari IOSHellraiser
A
7

Solved it myself with a javascript function:

window.addEventListener('resize', resize, false);

video.height = 100; /* to get an initial width to work with*/
resize();

function resize() {
videoRatio = video.height / video.width;
windowRatio = window.innerHeight / window.innerWidth; /* browser size */

    if (windowRatio < videoRatio) {
        if (window.innerHeight > 50) { /* smallest video height */
                video.height = window.innerHeight;
        } else {
            video.height = 50;
    }
    } else {
        video.width = window.innerWidth;
    }

};
Allyson answered 13/1, 2016 at 15:15 Comment(0)
B
16

Try wrapping the value inside quotes

<div class="videoContainer">
   <video id="video" width="100%" height="auto" onclick="playPause();"></video>
</div>

you can add these class

.videoContainer
{
   position:absolute;
   height:100%;
   width:100%;
    overflow: hidden;
}

.videoContainer video
{
  min-width: 100%;
  min-height: 100%;
}

Or alternatively use this

video {
  object-fit: cover;
}
Becalmed answered 4/1, 2016 at 12:55 Comment(3)
Thanks, no difference though.Allyson
Still no go. It scales only based on width using this.Allyson
Instead of "min-width: 100%;min-height: 100%;" use "max-width: 100%; max-height: 100%;". Then this works for me and the whole video is visible.Occupancy
A
7

Solved it myself with a javascript function:

window.addEventListener('resize', resize, false);

video.height = 100; /* to get an initial width to work with*/
resize();

function resize() {
videoRatio = video.height / video.width;
windowRatio = window.innerHeight / window.innerWidth; /* browser size */

    if (windowRatio < videoRatio) {
        if (window.innerHeight > 50) { /* smallest video height */
                video.height = window.innerHeight;
        } else {
            video.height = 50;
    }
    } else {
        video.width = window.innerWidth;
    }

};
Allyson answered 13/1, 2016 at 15:15 Comment(0)
T
2

In Angular if video player (shaka player in my case) is a separate component, this works perfectly (either height or width of container will cause resize of the player)

HTML

 <div id="videoContainer"        
      class="videoContainer">
   <video id="videoPlayer"></video>
 </div>

CSS

.videoContainer
{
   height:100%;
   width:100%;
}

.videoContainer video
{
  width: 100%;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}
Tocopherol answered 6/4, 2022 at 14:43 Comment(1)
This is best answer, just add: object-fit: contain; under max-height: 100%;Ardis
R
1

Thanks to qfactor77's answer, I was guided towards the PERFECT solution. It works for both width and height, to become both larger or smaller than the video's actual dimensions, to fit in whatever container you throw it in, without the height ever becoming a problem.

<div class="videoContainer">
  <video class="video" ... />
</div>
.videoContainer {
  position: relative;
  width: 100%;
  height: 100%;
}

.video {
  position: absolute;
  width: 100%;
  height: 100%;
  object-fit: contain; /* Not necessary in Chrome */
}

That's it. You don't need anything else.

Note: Chrome automatically applies object-fit: contain; to video elements, so you can omit it. But I include it anyway to ensure it applies if the browser didn't apply it.

Tip: Using other values of object-fit can give you different results on how the video is fit inside its container.

Radiant answered 2/1 at 19:34 Comment(0)
T
0

There's a great auto width/height trick called intrinsic ratios that can be used on images/videos and the likes! The trick is to have your desired element in a wrapper that then has a percentage-valued padding applied to it.

Your markup would then be:

<div class="video-wrapper">
  <video class="video" id="video" onclick=playPause()></video>
</div>

And your CSS:

.video-wrapper {
  position: relative;
  padding-bottom: 20%;
  height: 0;
}

.video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #ccc; /* Random BG colour for unloaded video elements */
}

You can limit the dimensions of your video container by playing with min-width or max-width of the .video-wrapper styles.

Hope this helps!

Textual answered 4/1, 2016 at 14:7 Comment(1)
Nope, same thing. Scales only based on width. Uses same technique as fitvidsjs.com suggsted earlier.Allyson
R
0

I had a similar problem. I have made a `slideshow' with various objects as slides, some of them are videos of various sizes. I did not found any conceptual solution, so I have found a trick.

I have explicitely specified all real video sizes in tags and collected the information of all of them:

var vids = document.getElementsByClassName("vid"); // videos
var vidl = vids.length;
var vidH = [ ];
var vidW = [ ];

// Get original widths and heights of videos
for (i=0; i<vidl; i++) { // >
    vidH.push(vids[i].height);
    vidW.push(vids[i].width);
}

Then (when necessary) I define the window size as follows:

// Current inner height of the browser window (in pixels)

var iH = window.innerHeight
         || document.documentElement.clientHeight
         || document.body.clientHeight;
// Current inner width of the browser window (in pixels)
var iW = window.innerWidth
         || document.documentElement.clientWidth
         || document.body.clientWidth;

To rescale a rectangle into another rectangle we have to find a minimal scale:

var r, rh, rw;

// Scale videos to fit window
for (i=0; i<vidl; i++) { // >
    rh=iH / vidH[i]; rw=iW / vidW[i]; r=Math.min(rh, rw);
    if (rh>rw) {
       vids[i].height=Math.floor(vidH[i]*r);
       vids[i].width=iW;
    }
    else {
       vids[i].height=iH-5;
       vids[i].width=Math.floor(vidW[i]*r);
    }
}

Unfotunately, here appeared some extra space; in FireFox I have found its minimal value as 5 that I negate form windows height value (iH) as the new video size.

Richly answered 19/12, 2016 at 18:9 Comment(0)
H
0

Duplicate issue on the height posted at HTML5 Video dimensions in Safari IOS

Pure CSS solution provided in: https://mcmap.net/q/740915/-html5-video-dimensions-in-safari-ios

Hellraiser answered 27/3, 2020 at 1:39 Comment(0)
S
0

You can add style:

object-fit: contain;
Spindell answered 23/2, 2022 at 14:49 Comment(0)
P
0

I found this style settings in the user agent stylesheet when open an mp4 directly in the address bar:

style="position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px;
       max-height: 100%; max-width: 100%; margin: auto;"

just add it in line in the video tag in your html or anyway you want.

Works for me in Chrome and Edge.

Piers answered 5/5, 2023 at 19:43 Comment(1)
Thank you for shining the light to show me the way! I improved upon your answer in my own.Radiant

© 2022 - 2024 — McMap. All rights reserved.