Create a Bootstrap grid that perfectly fits the viewport without any overflowing content

I'm currently utilizing Bootstrap 5 in an attempt to design a simplistic layout consisting of an MxN grid of cells, each of equal size. My goal is to have this grid fill the entire viewport without any scrollbars appearing in either direction. However, I am encountering difficulties with the scrollbars.

Various combinations of height and max-height on different div elements have been attempted. While this helped prevent the container div from becoming too tall, the rows end up overflowing vertically. Ideally, I would like everything to shrink down to eliminate the scrollbars, even if it means making the columns narrower. While I prefer using bootstrap, it's not mandatory for this task.

The code snippet below represents where I am at the moment. It appears to be approximately 20% taller than the viewport:

<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="284a47475c5b5c5a4958681d061a061b">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid">
  <div class="row p-0">
    <div class="col p-0 border">
      <span class="ratio ratio-16x9 d-flex align-items-center justify-content-center">
        Cell
      </span>
    </div>
    <div class="col p-0 border">
      <span class="ratio ratio-16x9 d-flex align-items-center justify-content-center">
        Cell
      </span>
    </div>
  </div>
  <div class="row p-0">
    <div class="col p-0 border">
      <span class="ratio ratio-16x9 d-flex align-items-center justify-content-center">
        Cell
      </span>
    </div>
    <div class="col p-0 border">
      <span class="ratio ratio-16x9 d-flex align-items-center justify-content-center">
        Cell
      </span>
    </div>
  </div>
</div>

Edit 1:

It seems that the issue lies with the aspect-ratio property. The current behavior fills the width even if it results in a larger height than desired for the cell.

Below is an updated example without the ratios. The rendering and responsiveness are now correct:

<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7b5b8b8a3a4a3a5b6a797e2f9e5f9e4">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid d-flex h-100 mh-100 vh-100 flex-column">
  <div class="row p-0 flex-grow-1">
    <div class="col p-0 border d-flex align-items-center justify-content-center">
      <div>
        Cell
      </div>
    </div>
    <div class="col p-0 border d-flex align-items-center justify-content-center">
      <div>
        Cell
      </div>
    </div>
  </div>
  <div class="row p-0 flex-grow-1">
    <div class="col p-0 border d-flex align-items-center justify-content-center">
      <div>
        Cell
      </div>
    </div>
    <div class="col p-0 border d-flex align-items-center justify-content-center">
      <div>
        Cell
      </div>
    </div>
  </div>
</div>

The main objective is to ensure that the cell divs always maintain a 16/9 aspect ratio without exceeding the parent div's dimensions while being centrally aligned both horizontally and vertically within the parent. In essence, the cell divs need to expand until either their height or width reaches the parent div, then stop expanding. Conversely, the current behavior allows the width to reach the parent's width first, even if the height extends beyond the parent's limits.

Furthermore, it should be noted that the number of rows/columns is dynamic, which might impact the solution since sizing cannot be hardcoded relative to the number of rows and columns.

To provide context, the end goal is to present a grid of videos on a single screen without requiring the user to scroll.

Edit 2:

Just to offer more clarity, here are the expectations for the solution:

  1. Eliminate all scrollbars completely, as users may not be able to scroll in certain situations.
  2. The solution must accommodate layouts with varying numbers of rows and columns while ensuring content remains easily visible.
  3. Each cell will contain video content.
  4. All videos must adhere to the same aspect ratio.
  5. Since cell dimensions may not match video aspect ratios, videos should be centered in both directions within the cell.
  6. Responsive resizing based on browser window changes must be supported.
  7. While bootstrap or CSS solutions are preferred, other options will be considered if necessary.

Answer №1

Not entirely certain if this is exactly what you're looking for, but take a peek. It involves utilizing the CSS4 property aspect-ratio. More information on this can be found here, and you can check browser support here

I haven't delved into bootstrap in quite some time, so I may not be as familiar with its classes now ;) However, if you're keen on using it, identifying the appropriate classes within the bootstrap framework to replicate the minimal CSS required for this implementation shouldn't be too challenging (pay attention to utility classes primarily)

PS: Disregard the JS code; it's solely for demonstrative purposes to illustrate how items can be dynamically added or removed from the grid and observe its behavior.

    function addItem(e) {
        document.querySelector('.container').appendChild(document.querySelector('.col:first-of-type').cloneNode(true));
    }

    function removeItem(e) {
        e.remove();
    }
body {
  margin: 0;
}

.container {
    display: grid;
    grid-gap: 12px;
    grid-template-columns: repeat(auto-fit, minmax(20%, 1fr));
    grid-template-rows: repeat(auto-fit, minmax(0, 1fr));
    width: 100%; height: 100vh;
}
.col {
    background: #444;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    align-content: center;
}
.col > * {
    background: #999;
    aspect-ratio: 16 / 9;
    object-fit: contain;
    max-height: 100%; max-width: 100%;
}
<div class="container">
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
    <div class="col" onclick="removeItem(this)">
        <img src="https://via.placeholder.com/720x405?text=16:9" alt="Thumbnail" title="Click me and I will disappear!" />
    </div>
</div>

<button onclick="addItem(this)" style="background: #be0000; color: white; border: 0; border-radius: 3px; padding: 8px 24px; position: fixed; top: 12px; left: 12px;">Add item</button>

<style>

</style>

<script>

</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Update the Ngrx reducer when the component is present on the page

One dilemma I am facing involves managing two components within a page - an update user form and a history of events. Each component has its own reducer (user and events). My goal is to update the list of events in the store through an API call once the us ...

Mobile devices consistently experiencing issues with JavaScript generated elements overlapping

I'm currently in the process of creating a quiz based on a tutorial I found at https://www.sitepoint.com/simple-javascript-quiz/. While I followed the tutorial closely and integrated Bootstrap, I am encountering an issue specifically with mobile devic ...

Angular2 import functions properly on the Windows operating system, however, it encounters issues on the Linux

import { Injectable } from '@angular/core'; import { Http, Response, Headers } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { User } from './../../class/User'; I am encountering the fol ...

An error occurred with code 1 when running the command "npm run build -- --prod"

I am currently working on a project in Visual Studio 2017 using Asp.Net Core 2 and Angular 5. While attempting to publish my project, I encountered the error message 'The command "npm run build -- --prod" exited with code 1' in the error list wi ...

Multiple Invocations of Angular NgrxStore Action Dispatched within Selector Function

Currently, I am working on an Angular project utilizing ngRx store for the first time. In this project, I need to dispatch an action to fetch users' courses after retrieving the user from the Store. However, I have encountered a problem where the acti ...

How to correctly deserialize dates in Angular 5

When working with Angular 5, I have encountered an issue where JSON data from an API is not properly deserialized into dates within an array. My model includes a definition like this: export interface ProcessDefinition { _id?: string; proces ...

Strange HTML pop-up keeps appearing every time I use styles in my code or insert anything with CSS

Recently, I created an OctoberCMS backend setup through my cPanel (I also have one on my localhost). Now, I am trying to add a background image but every time I attempt to do so, a strange HTML popup appears that I can't seem to figure out. Here is th ...

Can one obtain a public IP address using Typescript without relying on third-party links?

Though this question has been asked before, I am currently working on an Angular 4 application where I need to retrieve the public IP address of the user's system. I have searched on Stackoverflow for references, but most posts suggest consuming a th ...

Testbed: Issue encountered: Unable to resolve all parameters for PriDateInput component

I am facing an issue while creating an Angular Component with the help of TestBed. The error message I receive is as follows: Error: Can't resolve all parameters for PriDateInput: (?). error properties: Object({ ngSyntaxError: true }) ...

Adjust grid column sizes automatically when a smaller number is declared - tailwind

I am working with the tailwind grid system and have specified 6 columns for each row. However, if the number of elements is less than 6, I would like it to resize them to 3. <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 grid-flow-r ...

When viewed on a mobile device, the page defaults to displaying the NumPad instead of the Text Keyboard in Angular

The email field in my angular app is opening a Key Pad in mobile view and I'm not sure why. <form (ngSubmit)="onSubmit()" #emailForm="ngForm"> <div class="emailaddress" style="text-align:center;" *ngIf="!showEmail"& ...

An error encountered while trying to utilize the npm convert-units package within an Ionic 4 application

In my Ionic 4 app, I am utilizing version 2.3.4 of the npm package called convert-units. To install this package in my Ionic 4 application, I used the CLI command: npm i convert-units --save However, upon importing the library with import { convert } fro ...

Determine the amount of time that can be allocated based on the attributes contained within the object

I am faced with a JSON structure like the one below: var meetings = [ { id: '1', start_time: "2020-11-15T08:30:00+00:00", end_time: "2020-11-15T14:15:00+00:00" }, { id: '2', start_time: &quo ...

The JavaScript and CSS properties are not functioning properly with the HTML text field

I came across this CodePen example by dsholmes and made some modifications: Here Furthermore, I have developed my own form on another CodePen pen: Link The issue I'm facing is related to the placeholders/labels not disappearing when typing in text f ...

The differences between xPages and HTML templates are evident in the varying sizes of their elements

When using a html template in an xPages application, I noticed that all elements appear slightly larger compared to a plain html page. Even when checking the values in Chrome debugger, they all seem to be the same. https://i.sstatic.net/F7VdJ.png https:/ ...

What is the best way to deactivate div elements once an overlay has been applied to them?

My goal is to place an overlay on my form to prevent users from accessing the content. Even though I have added an overlay, users can still interact with input fields. How can I prevent that? .overlay { background: rgba(0, 0, 0, .75); text-align: ce ...

I am interested in adding a personalized icon to the progress bar in Material-UI

I am currently using the MUI linerProgressBar design. I would like to incorporate a custom UI Icon that moves along with the progress. Are there any examples of this available? I have searched for one in MUI but haven't found anything. If you know of ...

Leveraging both Angular Material UI and Tailwind CSS simultaneously

Recently, I've been incorporating Material UI with Angular. With the deprecation of flexlayout and the rise of Tailwind as a recommended alternative, I'm wondering if it's feasible to utilize both Material UI and Tailwind in tandem. How can ...

Can someone guide me on how to make a Carousel responsive using Angular?

HTML: <div class="voxel-row"> <div class="voxel-col-4"><h2 id="vagas_recentes">vagas recentes</h2></div> </div> <div id="carouselExampleControls" cl ...

When floating divs with varying heights are wrapped, they may become stuck in place

Hey there! Let's tackle a challenge: I've got a few divs, each with varying heights. These divs contain portlets that can expand in height. Here's a basic example: .clz { float: left; } <div class="container"> <div class="cl ...