Bootstrap 4 row fill remaining height - html

I'm struggling to make the a row stretch to fill the rest of the available height. I tried adding h-100 to the row class but that causes a white space at the bottom of the screen. There must be a way to do it but I'm totally stumped.. Here is my code:
<div class="container-fluid h-100">
<div class="row justify-content-center h-100">
<div class="col-4 bg-red">
<div class="h-100">
<div class="row justify-content-center bg-purple">
<div class="text-white">
<div style="height:200px">ROW 1</div>
</div>
</div>
<div class="row justify-content-center bg-blue">
<div class="text-white">ROW 2</div>
</div>
</div>
</div>
<div class="col-8 bg-gray"></div>
</div>
</div>
codepen: https://codepen.io/ee92/pen/zjpjXW/?editors=1100
I'd like to make the the blue row (ROW 2) fill all the red space. Any suggestions?
Thanks

Use the Bootstrap 4.1 flex-grow-1 class...
https://codeply.com/go/Iyjsd8djnz
html,body{height:100%;}
.bg-purple {
background: rgb(48,0,50);
}
.bg-gray {
background: rgb(74,74,74);
}
.bg-blue {
background: rgb(50,101,196);
}
.bg-red {
background: rgb(196,50,53);
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container-fluid h-100">
<div class="row justify-content-center h-100">
<div class="col-4 bg-red">
<div class="h-100 d-flex flex-column">
<div class="row justify-content-center bg-purple">
<div class="text-white">
<div style="height:150px">ROW 1 - fixed height</div>
</div>
</div>
<div class="row justify-content-center bg-blue flex-grow-1">
<div class="text-white">ROW 2 - grow remaining height</div>
</div>
</div>
</div>
<div class="col-8 bg-gray"></div>
</div>
</div>
Update 4.3.1: Another example using the vh-100 utility class
https://codeply.com/go/h3bZbM6eSS
.bg-purple {
background: rgb(48,0,50);
}
.bg-gray {
background: rgb(74,74,74);
}
.bg-blue {
background: rgb(50,101,196);
}
.bg-red {
background: rgb(196,50,53);
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container-fluid">
<div class="row justify-content-center min-vh-100">
<div class="col-4 bg-red">
<div class="d-flex flex-column h-100">
<div class="row justify-content-center bg-purple">
<div class="text-white">
<div style="height:150px">ROW 1 - fixed height</div>
</div>
</div>
<div class="row justify-content-center bg-blue flex-grow-1">
<div class="text-white">ROW 2 - grow remaining height</div>
</div>
</div>
</div>
<div class="col-8 bg-gray"></div>
</div>
</div>
Related: How to make the row stretch remaining height

This is a solution. The wrapper div has to have h-100, the div that adapts to height has to have flex-grow-1 and overflow-auto. This way, the div will grow to fill the space when its content is minor than the available space and will show the scrollbar when its content is higher than the available space.
Demo jsfiddle
<div class="h-100 d-flex flex-column bg-yellow px-2">
<div class="flex-column justify-content-center bg-purple px-2">
<div class="text-white p-0" style="height:50px">HEADER</div>
</div>
<div class="flex-column justify-content-center bg-red text-white px-2 flex-grow-1 overflow-auto">
<div>Item1</div>
<div>Item2</div>
INNER text 1<br>
INNER text 2<br>
</div>
<div class="flex-column justify-content-center bg-darkblue px-2">
<div class="text-white p-0" style="height:50px">FOOTER</div>
</div>

If anyone has tired of getting this to work, here is a super easy solution which will work in most scenarios. Just add the below class to the div for which you are trying to fill the remaining height:
Please note that 100vh is 100% of visible height and 200px is the total fixed height of the remainging divs above.
.fillRemaining {
height: calc(100vh - 200px);
}

Related

Force <div> element to expand and fill remaining screen space, but never expand beyond the screen view port

I want to size a div element to fill all remaining space available to it. However, if/when its contents exceed the remaining space, any overflow should be contained within without resizing or changing it's height. The element should have a fixed height which fills the remaining space.
My example is using Bootstrap.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<div class="row mx-0 flex-grow-1">
<div class="d-flex col-4 flex-column h-100 border border-dark">
<!--This column should expand down with its parent but never be able to expand off the screen-->
<div class="row py-2">
<div class="col">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Friends</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Friend Requests</a>
</li>
</ul>
</div>
</div>
<div class="row flex-grow-1 overflow-auto">
<div class="col flex-column">
<!--If this list takes up more space than it's parents, it should overflow scroll without changing its height -->
<ul class="list-group-flush" style="padding: 0;">
<li class="list-group-item">
<h3 class="col lead">Friend</h3>
</li>
<li class="list-group-item">
<h3 class="col lead">Friend</h3>
</li>
</ul>
</div>
</div>
</div>
<!--Chat-->
<div class="col-8 flex-column h-100 border-top border-end border-bottom border-dark">
</div>
</div>
In this image, the above code rendered, the red box is the area of the screen that the above code is affecting. The length "x" height of the red square (badly drawn) should never be any less nor more than the screen height minus the combined heights of all other elements on the screen.
I want the element sizes to remain the same and the list should scroll within its parent column instead.
I can almost achieve the desired effect by setting the max-height to 520px: <div class="row mx-0 flex-grow-1" style="max-height: 520px;"> This gives a good idea of what I want to achieve.
However, I'm hoping to find a responsive solution that works regardless of screen height.
Update
After applying #RokoC.Buljan answer to my work I had the following layout. Note the desired nested scroll-able areas. Thanks again for the help. Example is using Bootstrap 5.1
html {
font-size: 14px;
position: relative;
height: 100%;
}
#media (min-width: 768px) {
html {
font-size: 16px;
}
}
.site-root {
display: grid;
grid-template-rows: auto 1fr auto;
height: 100%;
}
.footer {
position: static!important;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<body class="site-root h-100">
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<h3>Header</h3>
</div>
</nav>
</header>
<main class="container d-flex flex-column flex-grow-1 overflow-hidden">
<div class="row"><h1>Jumbotron</h1></div> <!--Hub Jumbotron-->
<div class="row flex-grow-1 overflow-auto" style="flex-flow:nowrap;">
<div class="col-3 flex-grow-1 overflow-auto">
<!--Left Side Panel-->
<h3>Left Panel</h3>
</div>
<div class="col-9 d-flex flex-column flex-grow-1">
<div class="row"><h3>Hub Nav</h3></div> <!--Hub Nav-->
<div class="row flex-grow-1 overflow-auto" style="flex-flow:nowrap;">
<div class="col-3 d-flex flex-column flex-grow-1">
<!--Friend List-->
<div class="row"><h4>Friends List</h4></div>
<div class="row flex-grow-1 overflow-auto" style="flex-flow:nowrap;">
<div class="col flex-column flex-grow-1 overflow-auto">
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
<div class="p-2">Friend</div>
</div>
</div>
</div>
<div class="col-9 d-flex flex-column-reverse flex-grow-1">
<!--Chat-->
<div class="row"><h4>Message Bar</h4></div>
<div class="row flex-grow-1 overflow-auto" style="flex-flow:nowrap;">
<div class="col flex-grow-1 overflow-auto">
<p style="height:300vh;">1. Some paragraph to force scrollbars...</p>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<footer id="site-footer" class="border-top footer">
<div class="container">
<h3>Footer</h3>
</div>
</footer>
</body>
If I got you right, all you need to do is to flex the desired items, and don't forget to set overflow: auto; to the ones you want to independently scroll:
* { margin: 0; box-sizing: border-box; }
body {
height: 100vh;
display: flex;
flex-flow: column nowrap;
overflow: hidden;
}
.flex {
flex: 1;
overflow: auto;
}
.row {
display: flex;
flex-flow: row nowrap;
}
.cell-3 { flex-basis: 25%; }
.cell-9 { flex-basis: 75%; }
<header class="row" style="background: #bf0">
HEADER<br>
WELCOME!
</header>
<main class="row flex">
<section class="cell-3 flex" style="background: #0bf">
<p style="height: 200vh">Some paragraph to force scrollbars...</p>End.
</section>
<section class="cell-9 flex" style="background: #f0b">
<p style="height: 300vh">Some even taller paragraph as well...</p>End.
</section>
</main>
<!-- PS avoid inline `style`. The above is just for demo -->
which is basically an extension of this answer: Flex max height content with dynamic header and footer

How to set the height of two Bootstrap 4 columns to content height when the columns wrap?

I have 2 scrollable columns in Bootstrap 4 and they work ok:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row flex-grow-1 overflow-hidden">
<div class="col-6 mh-100 overflow-auto">
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
</div>
<div class='col-6 mh-100 overflow-auto'>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
For mobile, I use #media to change mh-100 and overflow and wrap the 2 columns into 1 column like this:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
</div>
<div class='col-12 overflow-visible'>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
This is OK, when scrollbar is visible.
But when there is no scrollbar, both columns have 50% height:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello
</div>
<div class='col-12 overflow-visible'>
World
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
How can I set the height of the first column to fit the content when there is no scrollbar?
I don't want to loose the existing functionality.
I know that the columns will fit the content if I remove flex-grow-1 from the row.
The answer is to use #media to add display: block!important to the row on mobile:
Now it works with the scrollbar:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row d-block flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>
</div>
<div class='col-12 overflow-visible'>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
World<br>World<br>World<br>World<br>World<br>World<br>World<br>
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>
And it works when there is no scrollbar:
html,
body {
height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid d-flex flex-column vh-100">
<div class="row border flex-shrink-0">
Header
</div>
<div class="row d-block flex-grow-1 mh-100 overflow-auto">
<div class="col-12 overflow-visible">
Hello
</div>
<div class='col-12 overflow-visible'>
World
</div>
</div>
<div class="row border flex-shrink-0">
Footer
</div>
</div>

Issue converting container rows into columns for responsiveness

I am working on writing the html for the above image with responsiveness. Below is my code for the design so far
HTML:
<div class="container-fluid">
<div
class="row low-height box border bg-light justify-content-start align-content-start overflow-box"
>
<div class="col-1 border bg-primary small-box m-2"></div>
<div class="col-1 border bg-primary small-box m-2"></div>
</div>
<div
class="row low-height box border bg-light justify-content-end align-content-end"
>
<div class="col-1 border small-box bg-success m-1"></div>
</div>
<div
class="row low-height box border bg-light justify-content-center align-content-center"
>
<div class="col-lg-12 text-center"><h4>Title</h4></div>
</div>
</div>
CSS:
.box {
height: 200px;
margin-bottom: 10px;
}
.small-box {
height: 100px;
}
.overflow-box {
overflow: auto;
}
Problem:
For the browser height lower than 600px, the 3 main sections should become horizontally arranged as shown in the below image.
This is the part I am unable to solve and cant find anything on the bootstrap site as well. May be I am doing something wrong fundamentally. Please help.
You can add a media query in your css,
#media(max-height:600px) {
//here you can write your custom css for that condition
//in this case,
[class*="col"]{
width:33%!important;
}
}
Here's an example
#media(max-height:600px) {
[class*="col"]{
width:33%!important;
}
}
.box {
text-align:center;
padding:5rem;
background-color: #22ccff;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<div class="container-fluid">
<div class="px-lg-12 px-md-12 px-sm-12">
<div class="row">
<div class="col-xl-12 col-lg-12 col-md-12 mb-4">
<div class="box">Box-1
</div>
</div>
<div class="col-xl-12 col-lg-12 col-md-12 mb-4">
<div class="box">Box-2
</div>
</div>
<div class="col-xl-12 col-lg-12 col-md-12 mb-4">
<div class="box">Box-3
</div>
</div>
</div>
</div>
</div>
Instead of putting each of the three grey boxes in its own row, they should be cols within a responsive Boostrap grid.
I've updated your code to put each of those grey boxes in a <div class="col-4 col-sm-12" ...> to make them format to 3 columns on XS screens, and 1 column on all larger size screens per your request. (Although that's backwards from how responsive sites usually work: usually on the smallest screen size the grid collapses to one column, and on larger sizes the grid expands to more columns.)
.box {
height: 200px;
margin-bottom: 10px;
}
.small-box {
height: 100px;
}
.overflow-box {
overflow: auto;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<div class="container-fluid">
<div class="row">
<div class="col-4 col-sm-12 low-height box border bg-light justify-content-start align-content-start overflow-box">
<div class="row">
<div class="col-1 border bg-primary small-box m-2"></div>
<div class="col-1 border bg-primary small-box m-2"></div>
</div>
</div>
<div class="col-4 col-sm-12 low-height box border bg-light">
<div class="row justify-content-end align-content-end">
<div class="col-1 border small-box bg-success m-1"></div>
</div>
</div>
<div class="col-4 col-sm-12 low-height box border bg-light justify-content-center align-content-center">
<div class="row">
<div class="col-lg-12 text-center">
<h4>Title</h4>
</div>
</div>
</div>
</div>
</div>

Bootstrap 4 ordering columns on mobile/desktop

I'm making a responsive layout for a ecommerce productdetailpage. I would like to order the columns different on mobile without getting white spaces. This is what it looks like currently:
The problem is on desktop when for example there is not content for box 3. There will be a huge white gap above box 5. So box 5 has to move under box 2. Like this:
I don't know if this is even possible through using framework Bootstrap 4, if not I'm looking forward to see how you would doing this without. Hopefully someone can help me out.
For the structure i use the following bootstrap grid:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="row">
<div class="col-lg-7">
1
</div>
<div class="col-lg-5">
<div>2</div>
<div>3</div>
</div>
</div>
<div class="row">
<div class="col-lg-7">
4
</div>
<div class="col-lg-5">
5
</div>
</div>
It is necessary to know what layout should be applied, e.g. though JavaScript. Then when we will know what layout should be used, we can apply our layout.
So we car create a div and divide this div into two parts. Then using flex-grow property, we can fill the remaining space:
html,body{height:100%;}
.bg-purple {
background: rgb(48,0,50);
}
.bg-gray {
background: rgb(74,74,74);
}
.bg-blue {
background: rgb(50,101,196);
}
.bg-red {
background: rgb(196,50,53);
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container-fluid h-100">
<div class="row justify-content-center h-100">
<div class="col-6 bg-red">
<div class="h-100 d-flex flex-column">
<div class="row justify-content-center bg-purple flex-grow-1">
<div class="text-white">
<div>1</div>
</div>
</div>
<div class="row justify-content-center bg-blue flex-grow-1">
<div class="text-white">4</div>
</div>
</div>
</div>
<div class="col-6 bg-gray">
<div class="h-100 d-flex flex-column">
<div class="row justify-content-center bg-info" style="height: 30px;">
<div class="text-white">
<div>Column with fixed height 2</div>
</div>
</div>
<div class="row justify-content-center bg-success flex-grow-1">
<div class="text-white">Fille the remaining space 5</div>
</div>
</div>
</div>
</div>
</div>
An example at jsfiddle can be seen here
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="container-fluid">
<!-- Control the column width, and how they should appear on different devices -->
<div class="row">
<div class="col-sm-6" style="background-color:yellow;">50%</div>
<div class="col-sm-6" style="background-color:orange;">50%</div>
</div>
<br>
<div class="row">
<div class="col-sm-4" style="background-color:yellow;">33.33%</div>
<div class="col-sm-4" style="background-color:orange;">33.33%</div>
<div class="col-sm-4" style="background-color:yellow;">33.33%</div>
</div>
<br>
<!-- Or let Bootstrap automatically handle the layout -->
</div>
</div>

How to align center + left/right

My example:
<div class="container">
<div class="d-flex justify-content-between">
<div class="col justify-content-center flex-column d-flex">
left
</div>
<div class="col justify-content-center flex-column d-flex right">
right
</div>
</div>
</div>
.container div {
height: 100px;
background-color: red;
}
a {
background-color: blue;
}
.right {
text-align: right;
}
Fiddle: https://jsfiddle.net/lawagabi/f7tp3x26/1/
How can I make text-align right in box with right without expanding it to the entire width?
Your .container div class is having an affect here. Wrap your anchor tag with a span with the right class to easily fix this.
<div class="container">
<div class="d-flex justify-content-between my-auto">
<div class="col justify-content-center flex-column d-flex">
left
</div>
<div class="col justify-content-center flex-column d-flex">
<span class="right">right</span>
</div>
</div>
</div>
Fiddle