Three columns 100 percent height css layout - css

I am really stuck with the css for this layout. Here is my html code :
<body>
<div id="main">
<div id="left">
menu
</div>
<div id="middle">
</div>
<div id="right">
sidebar
</div>
</div>
</body>
I want three columns left, middle and right with the width of 25%, 60%, and 15% percent width of the parent and all expand to the 100 percent height of their parent (main).
in the mean time I want the main div to have a minimum height of the browser window and maximum height of its children.

You can do it easily using CSS tables:
html, body {
height: 100%;
}
body {
margin: 0;
}
.main {
display: table;
height: 100%;
width: 100%;
}
.left, .middle, .right {
display: table-cell;
background-color: lightgray;
}
.left {
width: 25%;
}
.middle {
background-color: beige;
}
.right {
width: 15%;
}
See demo at: http://jsfiddle.net/audetwebdesign/9L8wJ/
To fill the height of the view port, you first need to set height: 100% on the html and body elements.
Apply display: table to the parent container and set the height: 100%, and since this is a table, this value acts as a minimum value, so it will fill the vertical screen unless the content is very long, and in this case, the table height will automatically increase to contain the content.
Add widths to the left and right column, the middle will fill the remainder so no need to do the math.
Finally, apply display: table-cell to the three child elements.
You may want to add a wrapper around the content in each table cell is you want better control of the white space between columns, but it depends on you layout and design.

Related

Two column layout taking full screen but allowing one column to expand

I'm trying to create a somewhat complicated layout with two columns taking up the remaining height of their parent but where one of the two columns is able to exceed these bounds if its content requires it. (In my case, this is an image but I don't believe this matters).
Here's a picture of the desired result which I'm sure will explain much better what I'm looking after.
Note: Here the red border represents the screen bounds (100vw x 100vh).
Here's what I tried so far:
.container {
display: flex;
flex-direction: column;
height: 100vh;
}
.top {
background: orchid;
}
.columns {
flex: 1;
display: flex;
}
.columns>* {
flex: 1;
}
.left {
background: lightgreen;
/* Just make it larger than 100% */
height: calc(100% + 25px);
}
.right {
background: cornflowerblue;
}
<div class="container">
<div class="top">
Top Content
</div>
<div class="columns">
<div class="left">
Left Column
</div>
<div class="right">
Right Column
</div>
</div>
</div>
<div class="additional">
Additional Content
</div>
As you can see, the "additional content" section isn't pushed properly. This is because the left column is overflowing but isn't technically affecting its parent. I believe that if it did, then the right column wouldn't be sized properly. So this seems like two conflicting conditions and I'm not sure what to do.
Im not sure if this is the result you are looking for, but give it a try and let me know.
.container {
display: flex;
flex-direction: column;
height:max-content;
}
.top {
background: orchid;
}
.columns {
flex: 1;
display: flex;
}
.columns>* {
flex: 1;
}
.left {
background: lightgreen;
/* Just make it larger than 100% */
height: fit-content;
}
.right {
background: cornflowerblue;
max-height: 100vh;
}
First, the container is set to max-content, meaning that it will be as hight as the highes element inside it. Next, the right column is set to max-height:100vh, meaning that if your left column is not as high as 100vh, your container will be affected by that right column. As soon as left column exceeds 100vh mark of right column, the height:fit-content of left column makes its parent expand, leading to pushing the additional content properly while right column stays at 100vh.
In this case, if left column does not have enough content, it will get smaller then right column, if this is not desired behaviour, change the left-column height as you desire, but always us height properties that are affected by content (or min/max).

Fill parent by setting children height percentage

I have 2 columns. The first column is higher. The second column has 3 fieldsets. I'd like to fill the second column by setting children height percentage but it doesn't work. The second column height must equal the first column height. How to do it?
JSFiddle HERE
Update:
I tried to set parent height but the third fieldset went out of the secondColumn.
JSFiddle HERE
Here is one way of approaching this problem using CSS table cells.
For you HTML, add a wrapper div in the short (right most) column:
<div id="container">
<div id="firstColumn">
CONTENT<br>
CONTENT<br>
CONTENT<br>
CONTENT<br>
...
CONTENT<br>
</div>
<div id="secondColumn">
<div class="wrapper">
<fieldset id="first">
<legend>TEST1</legend>
Content
</fieldset>
<fieldset id="second">
<legend>TEST2</legend>
Content
</fieldset>
<fieldset id="third">
<legend>TEST3</legend>
Content
</fieldset>
</div>
</div>
</div>
For the CSS, try the following:
#container {
display: table;
height: 100%;
}
#firstColumn {
display: table-cell;
height: 100%;
background-color: yellow;
}
#secondColumn {
display: table-cell;
height: 100%;
background-color: gray;
}
.wrapper {
height: 100%;
outline: 2px dotted blue;
}
legend {
border: 1px dashed blue;
}
#first {
height: 15%;
}
#second {
height: 25%;
}
#third {
height: 45%;
}
Apply display: table to the parent #container, and display: table-cell to the child elements #firstColumn and #secondColumn. Set the height to 100% for the table and the table-cell elements.
For the .wrapper, set the height to 100% so that it fills up the height of the
column, and then adjust the heights of the fieldset elements.
Note that you need to allow some vertical space for the legend (I assumed 5%) so that
15% + 25% + 45% + 3x5% = 100%, this should be close to what you need.
See demo at: http://jsfiddle.net/audetwebdesign/qs25d/
Note: You may want to set a min-height to the parent (table) container to make sure
that the three fields sets have enough room, otherwise you may not get the vertical
height proportions as you expected for the fieldsets.

Set div to use remaining height using CSS with unknown height of other divs

I'm trying to implement solution similar to provided here:
https://stackoverflow.com/a/12242226
The problem with it (for me) is that it does not allow to restrict height of inner div.
So I've updated solution as follows:
<style type='text/css'>
html, body {
height: 400px;
width: 100%;
margin: 0;
}
.wrapper {
display: table;
height: 400px;
width: 100%;
background: yellow;
}
.component {
display: table-row;
background: gray;
}
.content {
display: table-cell; /* height is dynamic, and will expand... */
height: 100%; /* ...as content is added (won't scroll) */
background: turquoise;
}
.contentRel {
height: 100%;
background: blue;
position: relative;
}
.contentRemaining {
background: red;
position: absolute;
top:30px;
bottom:0;
left: 0;
right: 0;
overflow: auto;
}
</style>
<body>
<div class="wrapper">
<div class="component">
<h1>Component</h1>
<p>of variable height</p>
</div>
<div class="content">
<div class='contentRel'>
<div>100% Component Header</div>
<div class='contentRemaining'>
<div style='height:1000px'>
100% Component Content
</div>
</div>
</div>
</div>
<div class="component">
<h3>Other</h3>
<p>componet of variable height</p>
</div>
</div>
</body>
http://jsfiddle.net/UrcV7/
It works as I need in FF (height of contentRel div is set to 320px - height of wrapper div minus sum of heights of component divs), but doesn't work in IE: height of (contentRel div is set to 400px - same as height of wrapper div).
Does anybody know how to fix it?
Here is my problem description (maybe it is another solution for it):
I have an outer div with height set to some px values (wrapper div in example).
In that div I have several other divs which can be hidden dynamically by some JS code.
All divs except of 1 has some height. though it is unknown to me (component divs in example).
I want that one remaining div (content div in example) to:
a. Use all remaining height of wrapper div
b. Have a header of some predefined height (100% Component Header part in example above)
c. Have a child div with height "100% of content div" - "height of header" (100% Component Content in example above)
d. To not to be taller than "height of wrapper div minus sum of heights of component divs" (scrollbars are ok)

100% height child div in auto height parent

I have been looking all around the internet for the last couple of hours to find an answer for my question. I read the Floats 101 article on alistapart as well as a ton of similar questions on stackoverflow. I think it's finally time I asked the question as to prevent my head from exploding.
What I have trying to do :
A container with a fixed width contains a 100% width div which has two children. The div expands vertically to the content inside it. The two children form columns within the parent div so are therefore floated to place them side by side. The left column expands to the height of the parent div and has a background color. The right column doesn't have a background color and determines the height of the parent div.
It is really hard to explain so I tried to create an example:
http://jsfiddle.net/bituser/LzNuN/1/
I would really appreciate your help. Thanks
Don't float the right column at all, just give it a large enough margin to accommodate the left column. Floated elements are removed from the normal document flow and contribute nothing to the height of their parent; so, if you float both the right and left columns, your red #box element ends up with no height and you don't see it; if you stop floating the right column, then it really will determine the height of #box. If you don't float #right_column at all then it will expand to use all of the available width in #box.
Something like this:
<div id="container">
<div id="box">
<div id="left_column">
<p>details stuff yada yada yada</p>
</div>
<div id="right_column">
<p>other stuff yada yada yada test test test test test stuff stuff content content content content content stuff stuff example stuff test stuff content content stuff content example</p>
</div>
</div>
</div>
CSS:
#container {
width: 400px;
}
#box {
background-color: red;
}
#left_column {
width: 200px;
background-color: blue;
float: left;
}
#right_column{
margin: 0 0 0 200px;
background-color: green;
}
Updated fiddle: http://jsfiddle.net/ambiguous/eDTdQ/
Alternatively, you could add a width: 200px to #right_column and let it keep floating, then add overflow: hidden to #box so that #box expands to contain its floated children:
#box {
background-color: red;
overflow: hidden;
}
#right_column{
background-color: green;
float: left;
width: 200px;
}
Live version of this approach: http://jsfiddle.net/ambiguous/eDTdQ/2/
If you want the right column to auto-stretch and you want both columns to be full-height, then you can absolutely position the left column instead of floating it:
#box {
background-color: red;
position: relative;
}
#left_column {
width: 200px;
background-color: blue;
position: absolute;
top: 0;
left: 0;
bottom: 0;
}
Live: http://jsfiddle.net/ambiguous/3Cxe3/
look at this: http://jsfiddle.net/LzNuN/3/
you need to add the margin to the total width - the margin-left of the right column is not margin left from the parent it is margin left from the left column so if you total is 400px and your left column is 200px and your right column is also 200px there is no room for margin

CSS div positioning

I have div that contains 2 divs in it. One of the child divs has static height 2em, and I want the other one to vertically fill the rest of the space of the parent div. How do I do this?
Edit: I need the parent div to fill the screen.
This depends on exactly what you want to achieve. Getting a fixed top and variable bottom where the container is only as large as it needs to be for the two children.
Assuming:
<div id="parent">
<div id="top"></div>
<div id="bottom"></div>
</div>
use:
#top { height: 2em; }
and the bottom div will be as large as it needs to be. You can make the bottom fixed height and achieve the same thing.
But I suspect what you want to do is have the outer div fixed height (say 100%). That gets much harder. The problem is that there is no way in CSS of saying "height of 100% minus 2em" without using an (ill-advised) CSS expression.
One approach is to overlay the top with the bottom.
#outer { position: relative; }
#top { position: absolute; height: 2em; top: 0; left: 0; width: 100%; }
#bottm { height: 100%; padding-top: 2em; }
The top div actually overlays the bottom. This is fine so long as you don't want a border.
You can use Faux Columns if you're using an image for the background or just move the background color back to #parent to give the appearance of filling the screen with the #bottom div. It would fill the page by giving it a 100% height (as long as html and body also get height: 100%).
Example:
<head>
<title>TITLE</title>
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0; }
#parent { height: 100%; background: #f08; }
#top { height: 2em; background: #80f; }
</style>
</head>
<body>
<div id="parent">
<div id="top">TOP DIV</div>
<div id="bottom">THE REST</div>
</div>
Since CSS is just about styling, giving the appearance of 100% height is the same as having 100% height. Right?

Resources