Why doesn't `width:100%; height:100%; object-fit: contain;` make a <video> fit its container?
So I have a page with a grid layout, with a header and a footer and a black content container in the middle.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.container {
display: grid;
height: 100%;
grid-template-rows: max-content 1fr max-content;
}
.container div {
border: 1px solid red;
}
.videoContainer {
background-color: black;
}
video {
width: 100%;
height: 100%;
object-fit: contain;
}
<div class="container">
<div>This is the header</div>
<div class="videoContainer">
</div>
<div>This is the footer</div>
</div>
So far so good.
Now I want to put a video that will stretch to fit this container (and be centered). Here's attempt with object-fit: contain;
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.container {
display: grid;
height: 100%;
grid-template-rows: max-content 1fr max-content;
}
.container div {
border: 1px solid red;
}
.videoContainer {
background-color: black;
}
video {
width: 100%;
height: 100%;
object-fit: contain;
}
<div class="container">
<div>This is the header</div>
<div class="videoContainer">
<video width="400" controls>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
</div>
<div>This is the footer</div>
</div>
But it doesn't work. Instead of fitting the video to the container, the container expands to fit the video.
How can I keep the container at its inherent dimensions and make the video fit its container?
Solution 1:
1fr
The first thing you need to know is that 1fr
is equivalent to minmax(auto, 1fr)
, meaning that the container won't be smaller than its content, by default.
So, start by replacing 1fr
with minmax(0, 1fr)
. That will solve the overflow problem.
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.container {
display: grid;
height: 100%;
grid-template-rows: max-content minmax(0, 1fr) max-content;
}
.container div {
border: 1px solid red;
}
.videoContainer {
background-color: black;
}
video {
width: 100%;
height: 100%;
object-fit: contain;
}
<div class="container">
<div>This is the header</div>
<div class="videoContainer">
<video width="400" controls>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
</div>
<div>This is the footer</div>
</div>
- Reference: Why does minmax(0, 1fr) work for long elements while 1fr doesn't?
object-fit
If you want the video to actually "fit this container" (as in cover the full width and height), then try object-fit: cover
as opposed to contain
.