3 rows layout, with total min-height: 100% - css

I would like to achieve a 3 rows layout that behaves like this:
Content is displayed in the middle row. With no content, it just has the fixed height header on top of the screen and the fixed hight footer at the bottom. The middle row is empty and fills up the remaining height of the window.
With increasing content, the middle row gets larger. When it reaches the max size, the total layout size increases, so that the user now has to scroll to see the lower content and the footer.
I kind of managed to do that with tables:
http://jsfiddle.net/v73c4L7n/8/ (lot of content)
http://jsfiddle.net/v73c4L7n/9/ (little content)
HTML
<table class="main">
<tr><td>HEADER</td></tr>
<tr class="middle">
<td>
<div class="area">
<p>Content</p>
<p>Content</p>
</div>
</td>
</tr>
<tr><td>FOOTER</td></tr>
</table>
CSS
body, html {
height: 100%;
padding:0;
margin:0;
}
.area {
position: relative;
width: 300px;
background-color: green;
margin: 0px auto;
min-height: 100%;
height: 100%;
}
.main {
height: 100%;
width: 100%;
}
.main tr:first-child, .main tr:last-child {
height: 50px;
}
The problem is, that it doesn't seem to work in IE9 or IE10. I think, the problem is the height:100% of .area inside a table cell, that has no explicit height.
So I wondered if there is a better approach to this kind of layout.

have you given a try to set .middle height to 100% too ?
this way, the .middle <tr> will take as much place wich remains, others <tr> will expand according to their content.
http://jsfiddle.net/v73c4L7n/10/ (works in latest browsers .
updated CSS:
body, html {
height: 100%;
padding:0;
margin:0;
}
.area {
width: 300px;
background-color: green;
margin: 0px auto;
min-height: 100%;
height: 100%;
padding:1px
}
.main {
table-layout: fixed;
border-collapse: collapse;
background-color: red;
height: 100%;
width: 100%;
}
.main .middle > td {
background-color: yellow;
width: 100%;
}
.main tr:first-child, .main tr:last-child {
height: 50px;
}
.main tr:first-child > td {
width: 100%;
background-color: rgba(0,0,255,0.5);
}
.main tr:last-child > td {
width: 100%;
background-color: rgba(0,0,255,0.5);
}
.middle {
height:100%;
}
It worlks too with display:table and regular tag elements such as header, main and footer. http://jsfiddle.net/v73c4L7n/13/
Display:flex; makes things even easier : http://jsfiddle.net/v73c4L7n/14/
display:table is understood since IE8, flex since IE10 :(

Use divs not tables if you can. I would use the calc(expression) to get 100% height minus the sum of the footer and header. Look here in the fiddle. If you delete some of the paragraphs in the content div you will see it moves the footer to the bottom of the page even if theres no content.
JSFiddle
HTML
<div id="wrapper">
<div id="header">
HEADER
</div>
<div id="content">
<p>content</p><p>content</p><p>content</p><p>content</p><p>content</p>
<p>content</p><p>content</p><p>content</p><p>content</p><p>content</p>
<p>content</p><p>content</p><p>content</p><p>content</p><p>content</p>
<p>content</p><p>content</p><p>content</p><p>content</p><p>content</p>
<p>content</p><p>content</p><p>content</p><p>content</p><p>content</p>
</div>
<div id="footer">
FOOTER
</div>
CSS
html, body {
background-color:yellow;
height:100%;
}
* {
margin:0;
padding:0;
}
#wrapper {
height:100%;
margin: 0 auto;
}
#header{
height: 50px;
width: 100%;
background-color:purple;
}
#content {
background-color:green;
min-height: -moz-calc(100% - 100px); /* Firefox */
min-height: -webkit-calc(100% - 100px); /* Chrome, Safari */
min-height: calc(100% - 100px); /* IE9+ and future browsers */
width:300px;
margin:0 auto;
}
#footer {
height: 50px;
width:100%;
background-color:purple;
}

Related

Why assigning 100% of viewport width among elements breaks the look?

I am trying to design a two column theme with CSS3 viewport. My css and html looks like -
*{
padding:0;
margin:0;
}
#one{
width: 20vw;
height: 100vh;
float: left;
}
#two{
width: 80vw;
height: 100vh;
float: left;
}
<div id="one">one</div>
<div id="two">two</div>
However, with this the divs are displayed one after another. But if I remove height:100vh, they are displayed side-by-side as was expected. Can anyone tell me where am I going wrong?
*{
padding:0;
margin:0;
}
#one{
width: 20vw;
height:100vh;
float: left;
}
#two{
width: 80vw;
height:100vh;
float: left;
}
<div id="one">one</div>
<div id="two">two</div>
When you set the height of the elements to 100% of the viewport height, this causes a vertical scrollbar to appear. The vertical scrollbar makes the viewport narrower, which causes your elements to wrap. One way to solve this is to set overflow-y: hidden on the body element, which prevents the scroll bar from appearing:
* {
padding:0;
margin:0;
}
body {
overflow-y: hidden;
}
#one {
width: 20vw;
height:100vh;
float: left;
}
#two {
width: 80vw;
height:100vh;
float: left;
}
<div id="one">one</div>
<div id="two">two</div>
A better solution (in my opinion) is to create a wrapper around your divs to prevent them from wrapping:
* {
padding:0;
margin:0;
}
#wrapper {
width: 100vw;
}
#one {
width: 20vw;
height:100vh;
float: left;
}
#two {
width: 80vw;
height:100vh;
float: left;
}
<div id="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>
You need to add box-sizing: border-box;
*{
box-sizing: border-box;
padding:0;
margin:0
}
:root,body{width: 100vw; height: 100vh}
Hier is a good reading about it by paul
*{
box-sizing: border-box;
padding:0;
margin:0
}
:root,body{width: 100vw; height: 100vh}
#one,#two{
float: left;
height: 100vh
}
#one{
width: 20vw;
background: red
}
#two{
width: 80vw;
background: green
}
<div id="one">one</div>
<div id="two">two</div>
It's because (stupidly) browsers ignore the scrollbar for viewport units. That means that your two divs are making up all available screenspace but the scrollbar needs its space too. So div#two will break into a new line.
There are issues filed for this on Mozilla, for example
https://bugzilla.mozilla.org/show_bug.cgi?id=811403
height: 100vh;
this sets the height to 100vh, meaning it sets it as heigh as the viewport is.
using 20vw and 80vw equals 100vw meaning it would be logical to place on below the other, because the vw is 100%.
*{
padding:0;
margin:0;
}
#one{
width: 20vw;
height: 100vh;
float: left;
}
#two{
width:79vw;
height: 100vh;
float: left;
}
try using this

How to set two floated divs to be the 100% height of the page

There are two floated divs of different height inside a wrapper div. I need both of them to be 100% of height of the body i.e. of the same height. Also used clearfix. But height:100% doesnt seem to work. How to do this?
Demo
Html:
<div class="wrapper">
<div class="primary">
<img src="http://demo1.opentaps.org/images/products/small/gis_computer_glen_rolla.png" />
</div>
<div class="secondary">
<img src="http://demo1.opentaps.org/images/products/small/gis_computer_glen_rolla.png" />
</div>
<div class="clearfix">
</div>
</div>
CSS:
body {
min-height: 100vh;
background-color: green;
margin: 0;
}
.wrapper{
background-color: blue;
height: 100%;
}
.primary{
float: left;
width: 80%;
height: 100%;
background-color: yellow;
}
.primary img{
height: 100px;
width: 100px;
}
.secondary{
float: right;
width: 20%;
background-color: red;
height: 100%;
}
.secondary img{
height: 500px;
width: 100px;
}
.clearfix{
clear: both;
}
All you need to do is add a height of 100% to the html and body tags like so:
html, body {
height: 100%;
}
Demo:
http://jsbin.com/EsOfABAL/1/
if you want to use vh units (seen in your code), it does makes it easier, no need to worry about 'heritage' and see your columns being stopped at 100% height of the window.
if you mix the method of faux-column and clear fix , you need to set only once min-height:100vh; on the floatting element.
Your yellow background has to be drawn in the wrapper and the red one in the non-floatting element wich is stretch with the clearfix method.
body {
margin: 0;
}
.wrapper{
background-color: yellow;
overflow:hidden;
}
.primary{
float: left;
width: 80%;
min-height:100vh;
}
.wrapper .primary img{
height: 100px;
/* width:1000px; */
width: 100px;
}
.secondary .overflow{
margin-left:80%;
background-color: red;
}
.overflow:after {
content:'';
height:0;
display:block;
clear:both;
}
.secondary img{
height: 500px;
/*height:100px;*/
width: 100px;
}
uncomment height value for image to check behavior and drawing of your page, scrolling or not .
http://codepen.io/anon/pen/chHtK
Hope this helps you to understand the use of vh (or vw) units , for the faux-column and clearfix methods, it's just a reminder of old methods :)
Enjoy
The html element also needs to be 100% - try this:
html { height: 100%; }
body {
height: 100%;
background-color: green;
margin: 0;
}

align 3 divs inline

i am trying to align 3 divs inline with each other
i have
#header {
width:100%;
height:160px;
}
as the main container so the container fits the width of the page (100%)
then
.header-left {
width:33%;
display:inline-block;
}
.logo {
width:409px; /* width of the logo */
margin:10px auto 0 auto;
display:inline-block;
}
.header-right {
width:33%;
display:inline-block;
}
for the 3 divs in the container.
I need the .logo div in the centre of the page and in between the other 2 divs, so then the 2 other divs either side of the logo div.
the logo div needs to be 409px as thats the width of the logo.
for some reason it is just all displaying to the left and i cannot work out why
One solution is possible if you arrange the header HTML as follows:
<header class="ex1">
<div class="header-left">the left stuff </div>
<div class="header-right">the right stuff</div>
<div class="logo"><img src="http://placehold.it/409x138" ></div>
</header>
and apply the following CSS:
header {
border: 1px solid blue;
width: 100%;
min-width: 800px;
height: 160px;
overflow: auto;
}
.ex1 .header-left {
display:inline-block;
width: 33%;
max-width: 190px;
background-color: gray;
float: left;
}
.ex1 .logo {
width: 409px; /* width of the logo */
margin:10px auto 0 auto;
border: 1px solid red;
}
.ex1 .logo img {
display: block;
}
.ex1 .header-right {
display:inline-block;
width: 33%;
max-width: 190px;
background-color: gray;
float: right;
}
Basically, you float the left header element to the left, the right element to the right,
and keep the logo element centered in the normal box flow.
Set the min-width to allow for a fixed with logo/banner image.
Fiddle reference: http://jsfiddle.net/audetwebdesign/Esst8/
In this context, what happen if 409px is more than 34% of total width ? it breaks.
Think about rewriting your html, it won't work this way.
Restructure and use Float
To get what you want, the best thing to do is restructure your HTML and make sure you set a min-width on the body. Something like this (as seen in this fiddle):
HTML
<div id="header">
<div class="header-left">LEFT</div>
<div class="header-right">RIGHT</div>
<div class="logo"><img src="images/logo" width="409" height="138" /></div>
</div>
Essential CSS
body {
min-width: 600px; /* some minimum greater than 409px */
}
.header-left {
float: left;
width: 50%;
margin-right: -204.5px;
border-right: 204.5px solid transprent;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.logo {
width:409px; /* width of the logo */
margin:10px auto 0 auto;
position: relative;
z-index: 1;
}
.header-right {
float: right;
width: 50%;
margin-left: -204.5px;
border-left: 204.5px solid transparent;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
Update: to keep it functioning "on-center," you have to account for the larger of the two side pieces in your min-width setting. So if you are putting some fixed width element on each side, then you need to calculate your min-width based on the larger of those two side elements by this formula:
((Larger side piece px) x 2) + 409px Logo = Minimum width
Don't forget to account for borders, etc. as needed in sizing that.
Use display: inline instead of display: inline-block for your div
Demo: http://jsfiddle.net/R65fA/1/
I just read #Milche Patern answer and notice that you use both percentage and fixed width for your child element. It's really bad idea. You better rewrite to make it standard.
#header{ width:100%}
.header-left {
width:33%;
float:left;
}
.logo {
width:34%; /* width of the logo */
margin:10px 0px 0px;
float:left; height:138px;
}
.header-right {
width:33%;
float:left;
}
.clr{ clear:both;}
HTML:
<div id="header">
<div class="header-left">LEFT</div>
<div class="header-right">RIGHT</div>
<div class="logo"><img src="images/logo" width="409" height="138" /></div>
<div class="clr"></div>
</div>

How to make margins collapse evenly?

I want my margins to collapse fully before the body starts to become narrower like how it is on http://www.skysports.com/, and only when the margins have fully collapsed then the body can become narrower. I've been playing around with px, em, and % in my css for ages and haven't been able to make it work. Here is what i have so far.
html { background-image:url(images/webBackground.jpg);
background-size:100% 100%;
background-repeat:no-repeat;
background-attachment:fixed;
height:100%; width:100%;
}
body { background:black;
height:100%; width:75%;
margin:0 12.5% 0 12.5%;
}
#container { width: 100%; height: 100%; }
Here's a jsfiddle exmaple of what I think you're asking for.
HTML
<div id="wrapper">
<div id="main-content">
<div class="push"></div>
</div>
</div>
CSS
body, html {
margin: 0px;
padding: 0px;
}
#wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
width: 500px; /* specific resolution width */
margin: 0px auto 0px;
}
#main-content {
background-color: red;
}
#main-content .push {
height: 500px;
}
Sorry I didnt fully understand your question. Assuming that you need your image center aligned whatever width of the screen.
body
{background: url(images/webBackground.jpg) no-repeat fixed center 0 black;}

Aligning two divs side-by-side [duplicate]

This question already has answers here:
Align <div> elements side by side
(4 answers)
Closed 4 years ago.
I have a small problem. I am trying to align two divs side by side using CSS, however, I would like the center div to be positioned horizontally central in the page, I achieved this by using:
#page-wrap { margin 0 auto; }
That's worked fine. The second div I would like positioned to the left side of the central page wrap but I can't manage to do this using floats although I'm sure it is possible.
I would like to push the red div up alongside the white div.
Here is my current CSS concerning these two divs, sidebar being the red div and page-wrap being the white div:
#sidebar {
width: 200px;
height: 400px;
background: red;
float: left;
}
#page-wrap {
margin: 0 auto;
width: 600px;
background: #ffffff;
height: 400px;
}
If you wrapped your divs, like this:
<div id="main">
<div id="sidebar"></div>
<div id="page-wrap"></div>
</div>
You could use this styling:
#main {
width: 800px;
margin: 0 auto;
}
#sidebar {
width: 200px;
height: 400px;
background: red;
float: left;
}
#page-wrap {
width: 600px;
background: #ffffff;
height: 400px;
margin-left: 200px;
}
This is a slightly different look though, so I'm not sure it's what you're after. This would center all 800px as a unit, not the 600px centered with the 200px on the left side. The basic approach is your sidebar floats left, but inside the main div, and the #page-wrap has the width of your sidebar as it's left margin to move that far over.
Update based on comments: For this off-centered look, you can do this:
<div id="page-wrap">
<div id="sidebar"></div>
</div>
With this styling:
#sidebar {
position: absolute;
left: -200px;
width: 200px;
height: 400px;
background: red;
}
#page-wrap {
position: relative;
width: 600px;
background: #ffffff;
height: 400px;
margin: 0 auto;
}
I don't understand why Nick is using margin-left: 200px; instead off floating the other div to the left or right, I've just tweaked his markup, you can use float for both elements instead of using margin-left.
Demo
#main {
margin: auto;
width: 400px;
}
#sidebar {
width: 100px;
min-height: 400px;
background: red;
float: left;
}
#page-wrap {
width: 300px;
background: #0f0;
min-height: 400px;
float: left;
}
.clear:after {
clear: both;
display: table;
content: "";
}
Also, I've used .clear:after which am calling on the parent element, just to self clear the parent.
This Can be Done by Style Property.
<!DOCTYPE html>
<html>
<head>
<style>
#main {
display: flex;
}
#main div {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 40px;
}
</style>
</head>
<body>
<div id="main">
<div style="background-color:coral;">Red DIV</div>
<div style="background-color:lightblue;" id="myBlueDiv">Blue DIV</div>
</div>
</body>
</html>
Its Result will be :
Enjoy...
Please Note: This works in Higher version of CSS (>3.0).
The HTML code is for three div align side by side and can be used for two also by some changes
<div id="wrapper">
<div id="first">first</div>
<div id="second">second</div>
<div id="third">third</div>
</div>
The CSS will be
#wrapper {
display:table;
width:100%;
}
#row {
display:table-row;
}
#first {
display:table-cell;
background-color:red;
width:33%;
}
#second {
display:table-cell;
background-color:blue;
width:33%;
}
#third {
display:table-cell;
background-color:#bada55;
width:34%;
}
This code will workup towards responsive layout as it will resize the
<div>
according to device width.
Even one can silent anyone
<div>
as
<!--<div id="third">third</div> -->
and can use rest two for two
<div>
side by side.
It's also possible to to do this without the wrapper - div#main. You can center the #page-wrap using the margin: 0 auto; method and then use the left:-n; method to position the #sidebar and adding the width of #page-wrap.
body { background: black; }
#sidebar {
position: absolute;
left: 50%;
width: 200px;
height: 400px;
background: red;
margin-left: -230px;
}
#page-wrap {
width: 60px;
background: #fff;
height: 400px;
margin: 0 auto;
}
However, the sidebar would disappear beyond the browser viewport if the window was smaller than the content.
Nick's second answer is best though, because it's also more maintainable as you don't have to adjust #sidebar if you want to resize #page-wrap.
The easiest method would be to wrap them both in a container div and apply margin: 0 auto; to the container. This will center both the #page-wrap and the #sidebar divs on the page. However, if you want that off-center look, you could then shift the container 200px to the left, to account for the width of the #sidebar div.

Resources