2

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?

Peter Olson
  • 139,199
  • 49
  • 202
  • 242
  • You never gave your `videoContainer` any `max-height` or `height`. – Yong Jan 21 '22 at 00:42
  • @YongPin It's `1fr` from the `grid-template-rows`, so it's supposed to be everything in the middle of the page between the header and footer. But even if I give `.videoContainer` a `height: 100%` the problem is the same. – Peter Olson Jan 21 '22 at 00:44
  • 2
    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. [revised demo](https://jsfiddle.net/fr5c8w6u/) | [more details](https://stackoverflow.com/q/52861086/3597276) – Michael Benjamin Jan 21 '22 at 00:45
  • change the unit to something static, e.g. `90vh` – Yong Jan 21 '22 at 00:46
  • @MichaelBenjamin Aha! Thanks, can you post that as an answer? – Peter Olson Jan 21 '22 at 00:47

1 Answers1

3

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>

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.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701