I created a sample of the situation in JSFiddle
I updated JSFiddle Here: http://jsfiddle.net/x11joex11/r5spu85z/8/ (this shows in more detail how the sticky footer works so well, just height issue).
I want the table to take up the remaining height, for some reason the height: 100% is not working?
From my tests it appears to be related to min-height: 100%. I need that to make the sticky footer work.
So a solution for me is another way to do the sticky footer, or a way to still give 100% height to the elements within.
HTML
<div class="wrapper">
<div class="wrapper_content">
<!--Header-->
<div class="header">Header</div>
<div class="content table">
<div class="row">
<div class="l_cell">left</div>
<div class="r_cell">right</div>
</div>
</div>
<div class="push"></div>
</div>
</div>
<!--Footer-->
<div class="footer">Footer</div>
CSS
body, html {
margin: 0;
padding: 0;
height: 100%;
}
.wrapper {
min-height: 100%;
margin: 0 auto -50px;
background-color: black;
}
.container {
}
.table {
display: table;
height: 100%;
width: 100%;
background-color: yellow;
}
.row {
display: table-row;
}
.l_cell {
display: table-cell;
width: 265px;
background-color: orange;
}
.r_cell {
display: table-cell;
background-color: purple;
}
.header {
background-color: red;
width: 100%;
}
.footer {
height: 50px;
background-color: green;
}
.push {
height: 50px;
}
Here is one solution, http://jsfiddle.net/7t4RT/
This question has been asked many times before. I recommend viewing some of the answers already provided here at StackOverflow.
The reason that we're unable to use height: 100% in your example is because no height has defined. The CSS is wondering... well how high is 100%? There are many ways to get our elements to fill their containers in either HTML or CSS. Simply choose one you feel works better for you.
The following is one of many ways to solve this problem.
HTML:
<div class="fill-height">
<p>Filled</p>
</div>
<div class="cant-fill-height">
<p>Not Filled</p>
</div>
CSS:
body {
background-color: #ccc;
}
.fill-height {
background-color: #0ff;
width: 200px;
position: absolute;
top: 0;
bottom: 0;
}
.cant-fill-height {
background-color: #ff0;
width: 200px;
height: 100%;
margin-left: 200px;
}
I found an answer to my problem for now, but it requires the use of display:table which I recall causes other errors down the road, but it does appear to work right now to create the layout I had in mind.
http://jsfiddle.net/x11joex11/r5spu85z/10/
CSS
body,html{margin:0;padding:0;height:100%;}
.wrapper{}
.table{
height:100%;
width:100%;
display:table;
background-color:yellow;
}
.row{display:table-row;}
.cell{display:table-cell;}
.footer{background-color:green;height:50px;}
.header{background-color:red;height:30px;}
.left{background-color:purple;}
.right{background-color:orange;}
HTML
<div class="wrapper table">
<div class="header row">
Header<br/>
Header2
</div>
<div class="content table">
<div class="row">
<div class="cell left">leftt<br/>left2</div>
<div class="cell right">right<br/>right2</div>
</div>
</div>
<div class="footer row">
Footer
<br/>
Footer2
</div>
</div>
An answer not requiring the use of display:table or table tags is preferred.
Notice the sticky footer effect remains.
Related
I'm making a user-resizable GUI window with a header that gains height through new elements, a footer with static height, and a spacer in between that automatically takes up the rest of the height. I attempted using this answer, but the footer ended up vertically-centered. Picture:
If anyone knows why off the top of their head, it would be greatly appreciated. The element is being added to the page with javascript so the code is pretty messy. Thank you for your time.
What about the following:
<body>
<header class="header"></header>
<main class="spacer"></main>
<footer class="footer"></footer>
</body>
.
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
min-height: 100%;
}
.spacer {
flex: 1;
}
I still don't know what the issue was, but I made a solution using the css calc() function.
HTML:
<div id="myWindow">
<div id="header">
Header
</div>
<div id="footer">
<div id="subHeaderContainer">
<div id="subHeader">
Sub Header
</div>
</div>
<div id="subFooter">
Sub Footer
</div>
</div>
</div>
CSS:
#myWindow {
width: auto;
height: auto;
resize: both;
border: 2px solid black;
overflow:hidden;
}
#header {
height: 20px;
background-color: grey;
}
#footer {
width:100%;
height: calc(100% - 20px);
}
#subHeaderContainer {
width:100%;
height: calc(100% - 30px);
}
#subFooter {
width:100%;
height:30px;
}
I am just trying to create a basic website using Material Design Light that responds to the size of the screen and I am having trouble making the grid fill all of the available height. I have tried to look for solutions to this problem online but I cant find any that work.
Here is the source code for one the grids I will use:
<main class="mdl-layout__content">
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray;">size 4</div>
</div>
</main>
Here is a link to the full Html page: Example MDL Page
Here is an image of the problem: Page Example
I'm assuming that your page height is the view height, which you can only use w/ modern browsers. See view height
Basically what we're doing here is we already know how high our footer and header are going to be (in the fiddle i just set it to 50px each). Then we use the calc CSS property to set the view height (vh) to 100% - 100px (meaning the footer and header's height put together (50+50 = 100)
Check the fiddle
<div id="main-body">
<div class="header"></div>
<div class="content clearfix">
<div class="a">1</div>
<div class="a">2</div>
<div class="a">3</div>
<div class="a">4</div>
</div>
<div class="footer"></div>
</div>
* {
box-sizing: border-box; /* add for browser prefixes */
}
#main-body {
height: 100%;
overflow: hidden;
}
.header, .footer {
background-color: blue;
height: 50px;
}
.content .a {
height: calc(100vh - 100px);
background-color: red;
width: 25%;
float: left;
}
.clearfix:after {
content: "";
clear:both;
display:table;
}
Note that you'll also need the viewport meta tag in your <head> for this to work.
<meta name="viewport" content="width=device-width, initial-scale=1">
OP added the he would like the ability to center the text within these content divs
<div id="main-body">
<div class="header"></div>
<div class="content clearfix">
<div class="a"><p>1</p></div>
<div class="a"><p>2</p></div>
<div class="a"><p>3</p></div>
<div class="a"><p>4</p></div>
</div>
<div class="footer"></div>
</div>
#main-body {
height: 100%;
overflow: hidden;
}
.header, .footer {
background-color: blue;
height: 50px;
}
.content .a {
height: calc(100vh - 100px);
background-color: red;
width: 25%;
float: left;
position: relative;
}
.content .a p {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
}
.clearfix:after {
content: "";
clear:both;
display:table;
}
Th way I did it was to over-ride a couple of the mdl styles, notably to make main display as flex rather than inline-block. It would probably make sense to add an Id to restrict the impact of this override across the rest of your site
.mdl-layout__content {
display: flex;
flex-direction: column;
.mdl-grid {
width: 100%;
flex-grow: 2;
}
}
Try to fool around with the CSS height attribute. Like so:
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray; height:100%;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray; height:100%;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray; height:100%;">size 4</div>
More information here: http://www.w3schools.com/cssref/pr_dim_height.asp
I have a specific layout that is causing me HUGE headaches. Here is an image:
My goal is to have the "Side panel" ALWAYS equal the height of the container. The "Enrollment Application" section is at 100% height already.
Current Markup
<body>
<div id="container" class="pure-g">
<div class="pure-u-md-1-4 pure-u-1 panel" id="left-panel">
<div class="panel-row">
<div class="panel p">
<div class="inner-panel">
<div class="panel-logo">
"Logo here text"
</div>
</div>
</div>
</div>
<div class="panel-row">
<div class="panel p">
<div class="inner-panel">
<nav class="panel">
</nav>
</div>
</div>
</div>
</div>
<div id="right-panel" class="pure-u-md-3-4 pure-u-1 panel p">
<div class="inner-panel">
<header class="pure-g">
<div class="pure-u-md-1-4 pure-u-1 header-logo">
LOGO Would go here, of course.
</div>
<div class="pure-u-md-3-4 pure-u-1 header-title">
<h1>Consumers Energy</h1>
<h1><strong>CARE 3.0 Program</strong></h1>
<h1>Enrollment Application</h1>
</div>
</header>
<div id="content">
"Enrollment application text..."
</div>
</div>
</div>
</div>
</body>
Current CSS
.panel {
box-sizing: border-box;
height: 100%;
display: table-cell;
}
.panel.p {
padding: 3px;
}
.panel .panel-row {
display: table-row;
}
.panel .inner-panel {
border-radius: 5px;
padding: 10px;
width: 100%;
box-sizing: border-box;
background-color: red;
}
Here is an alternative fiddle to play with: http://jsfiddle.net/3c3tqo3e/ but I really don't want to use a table...
Q How can we stack two divs and make their heights = 100% of parent? The "Logo here.." section will be an auto height.
NOTE I would really prefer an answer that is responsive-friendly. I am using PureCSS for the sections. (This means that absolute positioning is not preferred) Also, strongly prefer just css/html. Thanks!
I have created a demo for you, but it will work on all modern browsers only. and you might have to read flexbox and its demos in details to make your work more meaningful in terms of performance and maintenance.
Also read on calc() here
HTML:
<main>
<aside>
<div class="logo">Logo</div>
<div class="aside-content">Other Content</div>
</aside>
<section>Section</section>
</main>
CSS:
html, body{ height: 100%; }
main{
height: 100%; background: teal; padding: 2em; box-sizing: border-box;
display: flex; flex-direction: row;
}
aside{
height: inherit; margin: 0 1em 0 0; width: 200px;
}
aside .logo{
background: #fff; height: 140px;
}
aside .aside-content{
background: #fff; height: calc(100% - 150px); margin: 10px 0 0 0;
}
main section{
height: inherit; background: #fff; flex-grow: 2;
}
Demo Fiddle: http://jsfiddle.net/vpqqyo9L/1/
Edit:
Here's one for IE9: http://jsfiddle.net/vpqqyo9L/3/
This is what I want to achieve:
Footer should stay at the bottom of the screen even if the content doesn't fill the viewport vertically.
Content columns have a border that should always be 100% content height. As the number and width of columns will change from page to page, background-image to fake column borders can’t be used.
There should be no scrollbars when all content is visible (Example 1).
Solution should be all HTML/CSS, no JS.
Minimum browser support should be IE9+ and latest desktop versions of Firefox, Chrome, Safari, Opera; with no quirks mode.
Width of the header/footer/content is always fixed (so header and footer don’t need to be placed inside content area). Height of header and footer is also fixed.
I’ve tried techniques from Fluid Width Equal Height Columns and this sticky footer example but haven’t been able to satisfy all the requirements at the same time. Any tips are appreciated.
Edit: So far the farthest I’ve got is by imitating tables which works correctly in webkit browsers but not in IE9 and Opera. See the fiddle here.
HTML:
<div class="table outer">
<div class="row header">
<div class="cell">header</div>
</div>
<div class="row content">
<div class="cell">
<div class="table inner">
<div class="row">
<div class="cell">content 1</div>
<div class="cell">content 2</div>
<div class="cell">content 3</div>
</div>
</div>
</div>
</div>
<div class="row footer">
<div class="cell">footer</div>
</div>
</div>
CSS:
html, body {
height: 100%;
}
.table {
display: table;
min-height: 100%;
height: 100%;
}
.table.outer {
width: 500px;
margin: 0 auto;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
}
.header, .footer {
height: 25px;
background-color: #999;
}
.content {
background-color: #eee;
}
.table.inner {
width: 100%;
min-height: 100%;
height: 100%;
}
.table.inner .cell {
width: 33%;
border-right: 1px dashed #c00;
}
While not a semantically desirable solution, the only way I could find to achieve all stated requirements is to go back to the 90s and use tables for layout.
See the fiddle here.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<table class="outer">
<tr>
<td class="header" colspan="3">header</td>
</tr>
<tr class="content">
<td>content1</td>
<td>content2</td>
<td>content3</td>
</tr>
<tr>
<td class="footer" colspan="3">footer</td>
</tr>
</table>
</body>
</html>
CSS:
html, body {
height: 100%; margin: 0;
}
.outer {
min-height: 100%;
height: 100%;
width: 500px;
margin: 0 auto;
}
.header, .footer {
height: 25px; background-color: #999;
}
.content td {
width: 33%;
background-color: #eee;
border-right: 1px dashed #c00;
vertical-align: top;
}
Try this :
#footer {
position:fixed;
left:0px;
bottom:0px;
height:30px;
width:100%;
}
/* IE 6 */
* html #footer {
position:absolute;
top:expression((0-(footer.offsetHeight)+(document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop))+'px');
}
In case anyone is interested, I figured out a solution that uses jQuery (instead of tables).
http://benpearson.com.au/web-development/3-column-fluid-layout-with-header-sticky-footer-and-100-percent-height-columns/
Is it possible to make the wrapper fill the window height (no scrolling) and the center div scrollable without messing around with pixels and javascript?
<div id="wrapper">
<h1>Header</h1>
<div id="center">
<div style="height:1000px">high content</div>
</div>
<div id="footer">Footer</div>
</div>
Basically I want the header to be visible at the top and the footer to be always visible at the bottom and have a scrollable content in the center which occupies the remaning height.
The header, footer and center divs' heights are all unknown (no set px or %, i.e. variable font-size or padding). Is it possible with pure CSS?
2014 UPDATE: The modern way to solve this layout problem is to use the flexbox CSS model. It's supported by all major browsers and IE11+.
2012: The correct way to do this with CSS alone is to use display: table and display: table-row. These are supported by all major browsers, starting with IE8. This is not using tables for display. You'll use divs:
html, body {
height: 100%;
margin: 0;
}
.wrapper {
display: table;
height: 100%;
width: 100%;
background: yellow; /* just to make sure nothing bleeds */
}
.header {
display: table-row;
background: gray;
}
.content {
display: table-row; /* height is dynamic, and will expand... */
height: 100%; /* ...as content is added (won't scroll) */
background: turquoise;
}
.footer {
display: table-row;
background: lightgray;
}
<div class="wrapper">
<div class="header">
<h1>Header</h1>
<p>Header of variable height</p>
</div>
<div class="content">
<h2>Content that expands in height dynamically to adjust for new content</h2>
Content height will initially be the remaining
height in its container (<code>.wrapper</code>).
<!-- p style="font-size: 4000%">Tall content</p -->
</div>
<div class="footer">
<h3>Sticky footer</h3>
<p>Footer of variable height</p>
</div>
</div>
That's it. The divs are wrapped as you'd expect.
A cross-browser solution derived from Dan Dascalescu answer:
http://jsfiddle.net/Uc9E2
html, body {
margin: 0;
padding: 0;
height: 100%;
}
.l-fit-height {
display: table;
height: 100%;
}
.l-fit-height-row {
display: table-row;
height: 1px;
}
.l-fit-height-row-content {
/* Firefox requires this */
display: table-cell;
}
.l-fit-height-row-expanded {
height: 100%;
display: table-row;
}
.l-fit-height-row-expanded > .l-fit-height-row-content {
height: 100%;
width: 100%;
}
#-moz-document url-prefix() {
.l-scroll {
/* Firefox requires this to do the absolute positioning correctly */
display: inline-block;
}
}
.l-scroll {
overflow-y: auto;
position: relative;
height: 1000px;
}
.l-scroll-content {
position: absolute;
top: 0;
bottom: 0;
height: 1000px;
min-height:100px;
}
<div class="l-fit-height">
<section class="l-fit-height-row">
<div class="l-fit-height-row-content">
<p>Header</p>
</div>
</section>
<section class="l-fit-height-row-expanded">
<div class="l-fit-height-row-content l-scroll">
<div class="l-scroll-content">
<p>Foo</p>
</div>
</div>
</section>
<section class="l-fit-height-row">
<div class="l-fit-height-row-content">
<p>Footer</p>
</div>
</section>
</div>
Using overflow:auto will let you do this.
demo
So what you are talking about is a sticky footer. I went and did some more research and here is what I have for you.
<div id="wrapper" style="height:100%">
<div id="header" style="float:none;"><h1>Header</h1></div>
<div style="overflow:scroll;float:none;height:auto;">high content</div>
<div id="footer" style="clear:both;position:fixed;bottom:0px;"><h1>Footer</h1></div>
</div>
This will give you a sticky footer. The key is position:fixed and bottom:0px;
Unfortunately this means it also hovers above any content in the scrollview. So far there seems to be only Javascript to figure this out but I will keep looking.