How to exactly fill remaining vertical space with css [duplicate] - css

I need to fill the remaining vertical space of #wrapper under #first with #second div.
I need an only CSS solution.
#wrapper {
width: 300px;
height: 100%;
}
#first {
width: 300px;
height: 200px;
background-color: #F5DEB3;
}
#second {
width: 300px;
height: 100%;
background-color: #9ACD32;
}
<div id="wrapper">
<div id="first"></div>
<div id="second"></div>
</div>

You can use CSS Flexbox instead another display value, The Flexbox Layout (Flexible Box) module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic.
Example
/* CONTAINER */
#wrapper
{
width:300px;
height:300px;
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-ms-flex-direction: column;
-moz-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
}
/* SOME ITEM CHILD ELEMENTS */
#first
{
width:300px;
height: 200px;
background-color:#F5DEB3;
}
#second
{
width:300px;
background-color: #9ACD32;
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* NEW, */
}
jsfiddle Example
If you want to have full support for old browsers like IE9 or below, you will have to use a polyfills like flexy, this polyfill enable support for Flexbox model but only for 2012 spec of flexbox model.
Recently I found another polyfill to help you with Internet Explorer 8 & 9 or any older browser that not have support for flexbox model, I still have not tried it but I leave the link here
You can find a usefull and complete Guide to Flexbox model by Chris Coyer here

Using CSS Flexbox (MDN Web Docs).
html, body {
height: 100%;
}
.wrapper {
display: flex;
flex-direction: column;
width: 300px;
height: 100%;
}
.first {
height: 50px;
}
.second {
flex-grow: 1;
}
<div class="wrapper">
<div class="first" style="background:#b2efd8">First</div>
<div class="second" style="background:#80c7cd">Second</div>
</div>

You can do this with position:absolute; on the #second div like this :
FIDDLE
CSS :
#wrapper{
position:relative;
}
#second {
position:absolute;
top:200px;
bottom:0;
left:0;
width:300px;
background-color:#9ACD32;
}
EDIT : Alternative solution
Depending on your layout and the content you have in those divs, you could make it much more simple and with less markup like this :
FIDDLE
HTML :
<div id="wrapper">
<div id="first"></div>
</div>
CSS :
#wrapper {
height:100%;
width:300px;
background-color:#9ACD32;
}
#first {
background-color:#F5DEB3;
height: 200px;
}

If you can add an extra couple of divs so your html looks like this:
<div id="wrapper">
<div id="first" class="row">
<div class="cell"></div>
</div>
<div id="second" class="row">
<div class="cell"></div>
</div>
</div>
You can make use of the display:table properties:
#wrapper
{
width:300px;
height:100%;
display:table;
}
.row
{
display:table-row;
}
.cell
{
display:table-cell;
}
#first .cell
{
height:200px;
background-color:#F5DEB3;
}
#second .cell
{
background-color:#9ACD32;
}
Example

Have you tried changing the wrapper height to vh instead of %?
#wrapper {
width:300px;
height:100vh;
}
That worked great for me when I wanted to fill my page with a gradient background for instance...

If you don't want to have fix heights for your main-container (top, bottom, ....), you can simply use this css-file to get a flex-container which uses the remaining space incl. working!!! scrollbars
Fiddler
<!DOCTYPE html>
<html >
<head>
<title>Flex Container</title>
<link rel="stylesheet" href="http://demo.qooxdoo.org/5.0/framework/indigo-5.0.css">
<style>
.cont{
background-color: blue;
position: absolute;
height: 100%;
width: 100%;
}
.headerContainer {
background-color: green;
height: 100px;
width: 100%;
}
.mainContainer {
background-color: white;
width: 100%;
overflow: scroll
}
.footerContainer {
background-color: gray;
height: 100px;
width: 100%;
}
</style>
</head>
<body class="qx-flex-ready" style="height: 100%">
<div class="qx-vbox cont">
<div class="headerContainer">Cell 1: flex1</div>
<div class="mainContainer qx-flex3">
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
</div>
<div class="footerContainer" >Cell 3: flex1</div>
</div>
</body>
</html>

All you need is a bit of improved markup. Wrap the second within the first and it will render under.
<div id="wrapper">
<div id="first">
Here comes the first content
<div id="second">I will render below the first content</div>
</div>
</div>
Demo

You can just add the overflow:auto option:
#second
{
width:300px;
height:100%;
overflow: auto;
background-color:#9ACD32;
}

Related

CSS Stick Footer to Bottom

Here is my code to stick the footer to bottom of the page:
#footer {
background-color: #0F2157;
width: 100%;
bottom: 0px;
min-height: 35px;
padding-top: 5px;
}
When I'm doing it with height it works perfectly fine, but when I'm trying to set the minimum height it leaves a little space under the footer. Any guess how to fix that?
First of all, the height of body, html and container (see element with class 'container') has to have height: 100%;
In this solution I have used flex box. It is supported by all modern browsers and IE11.
It's necessary to add the following properties to container:
display: flex;
flex-direction: column; /*the flex items are placed in column, by default it is in row*/
To move footer to bottom, just add to flex item
margin-top: auto; /* it grabs all free space between flex items and put it before this flex item */
html, body {
height: 100%;
}
.container {
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
.header {
height: 20%;
background-color: yellow;
}
.content {
background-color: white;
}
.footer {
min-height: 20%;
background-color: blue;
margin-top: auto;
}
<div class="container">
<div class="header">Header</div>
<div class="content">It's content</div>
<div class="footer">Footer in bottom</div>
</div>
What about using Flexbox? It is supported by IE>=10.
To use that, you have to split your page at least in two separated elements: The "upper"-one (.content) with the whole content of your page and the footer.
The "upper"-one gets the value flex: 1, which is a shorthand for:
flex-grow: 1
flex-shrink: 1
flex-basis: auto
This means, that the "upper"-element could grow to the maximum, while the footer reserves only it's actually required space.
Code snippet
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
<!doctype html>
<html>
<head>
</head>
<body>
<div class="content"></div>
<footer class="footer">
Hey footer!
</footer>
</body>
</html>
You used min height 35 px. I think your content's height inside of footer is more than 35px. So check the margin or padding of all footer elements.
It will be better, if you can make a jsfiddle demo.
[SOLVED]
I found this to be working for my example:
#footer {
position: absolute;
bottom: 0;
width: 100%;
}

Flexbox not honouring container height when percentage

Simple scenario - I would have thought.
The idea is that app-bar is a fixed height - set at 56px. The content DIV beneath should fill the remaining space - the height of the container is around 320px, which is set using a percentage of the parent.
If I use height:100%, the flexbox doesn't kick in, however, if I use height:320px it does.
Any ideas? The height needs to be a percentage, as it's filling the responsive parent.
<header class="img-app-bar">
<div class="container">
<div class="app-bar"></div>
<div class="content"></div>
</div>
</header>
.img-app-bar {
.container {
display:flex;
flex-direction:column;
background-color:Red;
height:100%;
.app-bar {
flex:0;
}
.content {
flex:1;
background-color:Yellow;
}
}
}
If the parent element doesn't have a height css style, percentage height for the child it isn't going to work (unless you use the absolute positioning hack) - that's just the way css works
A work around for your situation is to do the following (the aforementioned absolute position hack):
.img-app-bar {
position: relative;
/* the following is just for giving height without using height */
padding-top: 300px;
background: red;
}
.container {
/*this seems to set a height without setting a height*/
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.flex {
display: flex;
flex-direction: column;
height: 100%;
}
.app-bar {
height: 56px;
background: green;
}
.content {
flex:1;
background: blue;
}
<header class="img-app-bar">
<div class="container">
<div class="flex">
<div class="app-bar"></div>
<div class="content"></div>
</div>
</div>
</header>
The problem is that .img-app-bar needs a height, too. Otherwise your .container takes 100% height of 0.
body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.img-app-bar {
width: 100%;
height: 100%;
}
.container {
display:flex;
flex-direction:column;
background-color:Red;
height:100%;
}
.app-bar {
height: 56px;
}
.content {
flex:1;
background-color:Yellow;
}
<header class="img-app-bar">
<div class="container">
<div class="app-bar"></div>
<div class="content"></div>
</div>
</header>

How to make div to expand vertically without using overflow or javascript or hardcoded values such as margins

This plunkr shows the issue.
http://plnkr.co/edit/Zr4ncVcNa53Sawbk42kK?p=preview
I'd like the blue divs to precisely cover up the red divs.
How do I do this?
The yellow divs cannot be hardcoded in terms of height because their content is variable.
I can't use overflow else the SVG will also overflow, cutting off my chart.
If restructuring the HTML is required (add, remove or moving elements), I can't do it at or above the container class (as I use an HTML partial system and this HTML is generated via nested partials).
I'd like it purely done in the container, variable and fill-vertically CSS classes.
HTML
<li class="fixed left">
<view-widget>
<view-gadget>
<div class="container">
<div class="variable">
Title
<br>
Subtitle
<br>
Something else
</div>
<div class="fill-vertically">
SVG Kendo Chart
</div>
</div>
</view-gadget>
</view-widget>
</li>
<li class="fixed right">
<view-widget>
<view-gadget>
<div class="container">
<div class="variable">
Title
</div>
<div class="fill-vertically">
SVG Kendo Chart
</div>
</div>
</view-gadget>
</view-widget>
</li>
CSS
.container {
background:green;
}
.variable {
background: yellow;
}
.fill-vertically {
background: blue;
color: white;
}
.fixed {
background: red;
list-style: none;
height: 150px;
width: 45%;
}
.left {
position: absolute;
left: 0;
}
.right {
position: absolute;
right: 0;
}
Using flexible boxes: Plunker
.container {
height: 100%; /* fill .fixed's height */
display: flex;
flex-direction: column;
}
.fill-vertically {
flex-grow: 1;
}
Compatibility: Chrome, Firefox 28+, IE11+.
Use the display:table trick in case you need to support older browsers: Plunker
.container {
display: table;
width: 100%;
height: 100%; /* fill .fixed's height */
}
.variable, .fill-vertically {
display: table-row;
}
.variable {
height: 1px; /*computed = as little height as possible to fit content*/
}
.fill-vertically {
height: 100%; /*computed = remaining available height*/
}
Compatible with IE8+ and all modern browsers.

Responsive CSS Approach

The figure below is an illustration of what Im trying to get. The 1st figure represents the longer width and the 2nd figure represents the shorter width.
All the red blocks stays at the right and left position and the yellow block should follow the width of the container.
1: http://i.stack.imgur.com/6bHTo.jpg
heres my current approach
/* the one with black border :) */
.container{
position: relative;
}
/* red blocks have auto heights depends on its content */
.red{
position: absolute;
top: 0;
width: 100px;
}
.red-left{
left:0;
}
.red-right{
right:0;
}
/* yellow block follow the width of the container but should leave spaces for the left and right */
.yellow{
margin: 0 110px;
}
Im almost satisfied with this approach however, I noticed that when the red blocks are higher than the container, the container doesnt auto follow the height of its contents. I understand that its impossible to auto height the container because the children are in position absolute. :)
Have you consider using CSS3 Flex Box? It would go like this:
HTML:
<div class="container">
<div class="red red-left">red-left<br>red-left<br>red-left<br>red-left<br>red-left</div>
<div class="yellow">yellow<br>yellow</div>
<div class="red red-right">red-right</div>
</div>
And Css:
.container{
display: -webkit-box;
-webkit-box-orient: horizontal;
display: -moz-box;
-moz-box-orient: horizontal;
display: box;
box-orient: horizontal;
}
.red{
background-color:red;
width:100px;
}
.yellow{
background-color:yellow;
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
}
​
​Check out this Fiddle:
http://jsfiddle.net/lucaslazaro/sjYNy/
EDIT:
To know more about Flex Box I recommend this quick tutorial: http://www.html5rocks.com/pt/tutorials/flexbox/quick/
Maybe that helps:
HTML
<div class="container">
<div class="red red-left">red-left<br>red-left<br>red-left</div>
<div class="yellow">yellow<br>yellow</div>
<div class="red red-right">red-right</div>
</div>
​
​
CSS
/* the one with black border :) */
.container{
position: relative;
}
/* red blocks have auto heights depends on its content */
.red{
position: absolute;
top: 0;
width: 100px;
background:red;
height:auto
}
.red-left{
left:0;
}
.red-right{
right:0;
}
/* yellow block follow the width of the container but should leave spaces for the left and right */
.yellow{
margin: 0 110px;
background:yellow
}
​
​
​​DEMO
My Own Demo to make it easier.
What we can see here is the content overlapsed the container.
Using:
div {
display: table;
width: 100%;
table-layout: fixed;
}
div > div {
display: table-cell;
}
Review full code:
http://jsfiddle.net/BF6La/

How to push a footer to the bottom of page when content is short or missing?

I have a page with an outer div that wraps a header, content and footer div. I want the footer div to hug the bottom of the browser, even when the content div is not tall enough to fill the viewable area (i.e. there's no scrolling).
Your issue can be easily fixed by using flexbox. Just wrap your .container and your .footer in a flex container with a min-height: 100vh, switch the direction to column so that they stack on top of each other, and justify the content with space between so that footer will move to the bottom.
.flex-wrapper {
display: flex;
min-height: 100vh;
flex-direction: column;
justify-content: space-between;
}
<div class="flex-wrapper">
<div class="container">The content</div>
<div class="footer">The Footer</div>
</div>
While this question is old, I want to improve slightly on the great answer by Luke Flournoy.
Luke's answer only works if you have two elements in the wrapper. It's very common to have at least 3: header, main content and footer. With these three elements, Luke's code will space them evenly vertically - most likely not what you want. With multiple elements, you can do this:
.flex-wrapper {
display: flex;
min-height: 100vh;
flex-direction: column;
justify-content: flex-start;
}
.footer {
margin-top: auto;
}
<div class="flex-wrapper">
<div class="header">The header</div>
<div class="content">The content</div>
<div class="footer">The footer</div>
</div>
What I wanted was to have the footer be at the bottom of browser view ONLY IF the content was not long enough to fill up the browser window (non-sticky).
I was able to achieve by using the CSS function calc(). Which is supported by all modern browsers. You could use like:
<div class="container">CONTENT</div>
<div class="footer">FOOTER</div>
the css:
.container
{
min-height: 70%;
min-height: -webkit-calc(100% - 186px);
min-height: -moz-calc(100% - 186px);
min-height: calc(100% - 186px);
}
Change 186 to the size of your footer.
Use a blank div with flex-grow:1 to fill unused spaced right before the footer.
<body style="min-height: 100vh; display: flex; flex-direction: column;">
Any content you want,
put it here. Can be wrapped,
nested, whatever.
<div style="flex-grow:1"></div>
<!-- Any content below this will always be at bottom. -->
<footer>Always way at the bottom</footer>
</body>
Extract the styles to css as needed. This works by setting <body> as display:flex;
Example : http://jsfiddle.net/AU6yD/
html, body { height: 100%; }
#wrapper { min-height: 100%; height: auto !important; height: 100%; margin: 0 auto -30px; }
#bottom, #push { height:30px;}
body { background:#333;}
#header { height:30px; background:#000; color:#fff; }
#footer { height:30px; background:#000; color:#fff; }
<div id="wrapper">
<div id="header">
Header
</div>
<div id="push"></div>
</div>
<div id="bottom">
<div id="footer">
Footer
</div>
</div>
I did what Jahmic up top did (won't let me comment yet) except I had to use VH instead of % since I couldn't just apply it to a container class.
#inner-body-wrapper
{
min-height: 70vh;
min-height: -webkit-calc(100vh - 186px);
min-height: -moz-calc(100vh - 186px);
min-height: calc(100vh - 186px);
}
You can do exactly what you want using Flexbox, as an example will be:
html, body {
height: 100%;
width: 100%;
}
.wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
}
.content {
flex-grow: 1;
}
as a note the footer must be outside the content element
html structure will be something like follow:
<html>
<body>
<div class="wrapper">
<header></header>
<div class="content">
<!-- Content -->
</div>
<footer></footer>
</div>
</body>
</html>
I Found this very simple way, just take the main container add min-height and make the footer sticky
body { /* the main container */
min-height: 100vh;
}
footer {
position: sticky;
top: 100%;
}
There are great answer above, i think the problem is that nowadays most people whant to do this with some framework like React, Next or Vue, these frameworks add another element to wrap all the html rendered by the framework like divs with an id #root #__next
so we have to aply the style to that element
To make it work responsively when the footer is taller on mobile devices compare to on desktop, you can't really know the footer height. One way to do it is to stretch the footer out to cover the entire screen.
html,
body {
height: 100%;
}
.container {
min-height: 80%;
background-color: #f3f3f3;
}
.footer {
background-color: #cccccc;
box-shadow: 0px 500px 0px 500px #cccccc;
}
<div class="container">Main content</div>
<div class="footer">Footer</div>
body{
position:relative;
min-height:100vh;
}
footor{
position:absolute;
bottom:0%;
width:100vw;
}
Best solution to have this done was a previous reply from #DR-MATTH, assuming that the body is the main container:
body {
min-height: 100vh;
}
footer {
position: sticky;
top: 100%;
}
I just wanted to add that I had to use this variation min-height: calc(100vh - "any margin top/bottom of any sibling element above the footer"); to make the footer really sticky at the bottom when the page have not enough content and avoiding unnecessary scrolling.
Something like this:
body {
min-height: calc(100vh - 60px);
}
footer {
position: sticky;
top: 100%;
}
I tried: http://jsfiddle.net/AU6yD/ as here it's the best option but I had problems when the content of the <div id="wrapper"> started to get too big see
evidence.png, what I did to solve this was refreshing the body size everytime I changed the content of that div like this:
var body = document.body,
html = document.documentElement;
body.style.height = 100 + "%";
setTimeout(function(){
var height = Math.max( body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight,
html.offsetHeight );
body.style.height = height + "px";
}, 500);
Try with this codepen.io/dendii/pen/LLPKJm media responsive
html, body {
color:#fff;
}
.wrapper{
box-sizing: border-box;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
margin: 0 auto;
min-height: 100vh;
}
.main{
width:100%;
overflow:hidden;
}
.main-inner {
box-sizing: border-box;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
article,aside{
float:left;
padding:20px 10px;
}
article{
width:70%;
background:darkred;
}
aside{
width:30%;
background:darkblue;
}
.top {
padding:20px 10px;
height:100%;
background:darkgreen;
}
.bottom,.text-mid {
padding:20px 10px;
height:100%;
background:darkorange;
}
.text-mid {
margin-top: auto;
background:darkgrey;
}
#media (max-width: 768px){
.main-inner{
display: block;
}
article,aside{
width:100%;
float:none;
display: block;
}
}
<div class="wrapper">
<header class="top">
<h1>Header</h1>
</header>
<div class="main"><div class="main-inner">
<article>
blank content
</article>
<aside>
class sidebar
</aside>
</div></div>
<div class="text-mid">
<div class="center">
Whatever you want to keep.
</div>
</div>
<footer class="bottom">
<div class="footer">
Footer
</div>
</footer>
</div>
Another alternative if you want a main-wrapper to adjust the screen EqualHeight
I've solved same problem with jquery
var windowHeiht = $(window).height();
var footerPosition = $("#asd-footer").position()['top'];
if (windowHeiht > footerPosition) {
$("#asd-footer").css("position", "absolute");
$("#asd-footer").css("bottom", "0");
$("#asd-footer").css("width", "100%");
}
Reworking the jQuery solution. I have it working with resizing the window. When the window is bigger than the page, the footer style's position is "absolute" fixed at the bottom the window. When the window is smaller than the page, the footer stays at the bottom of the page - scrolling off the bottom.
<style>
.FooterBottom {
width:100%;
bottom: 0;
position: absolute;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
FooterPosition();
$(window).resize(function () {
FooterPosition();
});
});
var originalFooterBottom = 0;
function FooterPosition() {
var windowHeight = $(window).height();
if (originalFooterBottom == 0) {
var footer = $("#Footer");
originalFooterBottom = footer.position()['top'] + footer.height();
}
if (windowHeight > originalFooterBottom) {
var footerElement = document.getElementById("Footer");
if (!footerElement.classList.contains('FooterBottom')) {
footerElement.classList.add('FooterBottom');
}
}
else {
var footerElement = document.getElementById("Footer");
if (footerElement.classList.contains('FooterBottom')) {
footerElement.classList.remove('FooterBottom');
}
}
}
</script>
I tried many style only solutions but none of them worked. This Javascript/Style solution works just fine for me, even with its odd mix of jQuery and GetElement.
Thanks to Asad for his post.
i had just changed the position to sticky and set top to 100%.Then i go to its parent block and set its min height is 100%
This solved my problem.
In my case the parent block was body so i changed the min height of body.
.footer {
position: sticky;
top: 100%;
text-align: center;
width: 100%;
height: 60px;
background-color: #1abc9c;}
body{
margin:0;
padding:0;
min-height:100vh;}
To push a footer to the bottom of the page when content is short using tailwind.
Add the following to a class
flex flex-col justify-between min-h-screen
<div className="flex flex-col justify-between min-h-screen">
<div>
... //your body here
</div>
<Footer/> // your footer here
</div>
In my website i have 3 seperation divs div-header,div-body,div-footer. i put
min-height for div-body using javascript(i used window.height()) . so when content is low then it will maintain minimum height.so that the footer always be in bottom.
I tried this and it works fine so far
position:absolute;
bottom:0;
width:100%;
or
position:absolute;
bottom:0;
left:0;
right:0;
Wrap your footer with a class as following:
<div class="footer">
<h1>footer content</h1>
Then add following css properties to the footer:
.footer{
position: fixed;
bottom: 0;
}
This is what I am doing for my page
<h6 style="position:absolute; bottom:0;">This is footer at bottom of page without scrollbars</h6>

Resources