How to lock a 3x3 grid to the viewport regardless of content size?

55 Views Asked by At

I'm trying to create a page for CCTV camera streams that displays 9 streams in a 3x3 grid, using the full available width and height, without scrolling. The streams are different resolutions but I want the grid to resize the videos (ignoring aspect ratio, the video player handles this) so every video is visible.

I have this so far but I can't get the grid to resize the video elements so everything stays in the viewport.

body {
  margin: 0;
}

#container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  height: 100vh;
}

.item {
  border: 2px solid red;
  background-color: blue;
}

.item video {
  width: 100%;
  height: 100%;
}
<div id="container">
  <div class="item">
    <video src="https://placehold.co/600x500.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
</div>

2

There are 2 best solutions below

1
A Haworth On BEST ANSWER

To ensure the 9 cells take up exactly the viewport all elements have had box sizing defined, so borders are within their dimensions, all margins have been set to 0, and the videos are positioned absolute within their cells and given object-fit contain so it is certain the whole video will be seen without stretching.

If you want instead the videos to fill their cells then use cover instead, but of course they will probably get cropped.

* {
  margin: 0;
  box-sizing: border-box;
}

#container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  height: 100vh;
}

.item {
  border: 2px solid red;
  background-color: blue;
  position: relative;
}

.item video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  position: absolute;
}
<div id="container">
  <div class="item">
    <video src="https://placehold.co/600x500.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
  <div class="item">
    <video src="https://placehold.co/600x400.mp4" />
  </div>
</div>

3
Aayush singh On

ok then let me update it a little bit

body {
  margin: 0;
}

#container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  height: 100vh;
}

.item {
  border: 2px solid #222;
  background-color:black;
  position: relative;
  overflow: hidden;
}

.item video {
 width: 100%;
 height: 100%;
 object-position: center;
}

**Here is the result (every video is responsive **

enter image description here

*

  1. Added grid-template-rows: repeat(3, 1fr); to ensure the grid has 3 rows.
  2. Added position: relative; and overflow: hidden; to the .item class to contain the video within the grid item.
  3. The video has width and height of 100% that means it won't cut any angle *