Tricky box layout with sticky footer and flexible heights - html

I am working on a layout that is placed into a wrapper with a fixed height and contains three inner containers.
The first container (header) should be placed on top within the wrapper and is flexible in it's height.
The second container (content) is flexible in it's height as well and need to overflow if the available space is not sufficient (overflow-y: auto).
The third container (footer) also has an unknown height and needs to be placed at the bottom of the wrapper at any time.
<div id="wrapper">
<div id="header">
<span>
some unknown content that is placed at the top of the wrapper
</span>
</div>
<div id="content">
<span>
some more unknown content and within here we want
to enable vertical scrolling if necessary
</span>
</div>
<div id="footer">
<span>
again unknown content that should be placed at the bottom of
the wrapper at any time
</span>
</div>
</div>
The options I have ruled out so far:
absolute positioning of the footer within the relative positioned wrapper: doesn't work in this case since we don't know the footer's height
flexbox model: not possible since I need to support IE8+
table: the content row doesn't overflow, the complete table would overflow and the footer would be positioned outside of the wrapper
table with the content td element's position set to relative and including a div element with position set to absolute (containing the actual content): seems to fix the overflow issue in most browsers, but e.g. in IE9 the content div (with height set to 100%) results in a height of 0
Is there any other option without using Javascript that might work here?

It took a while but I believe this is it, I adapted it from my answer to another question. The .inner div must have height:100% but anything inside it should be able to be modified however you want.
http://jsfiddle.net/Z4K7J/2/
.left {
border:1px solid orange;
width:200px;
height:300px;
display:table;
}
.top {
display:table-row;
}
.middle {
display:table-row;
height:100%;
}
.middle .inner {
background-color:red;
height:100%;
overflow-y:auto;
}
.bottom {
display:table-row;
}

Related

How to create two divs where one of them will be fixed and other will be scrollable

I have one div which will hold my main contents and will be scrollable; and there is another div(footer) at the bottom exactly below the content div which will be fixed; the catch here is, no matter what the size of the browser window is, the main content div should not hide behind the footer div and it should resize its height based on the height of the browser.
So basically, i want both of them to be fixed at their positions and main div should always be scrollable.
So far whatever i have tried had made my scrollable div hide its content behind the footer.
I hope my question is not confusing.
Flex layout will really help you here:
HTML:
<div id="content">content</div>
<div id="footer">footer</div>
CSS:
body {
display:flex;
flex-direction:column
}
#content {
flex:1;
overflow:auto;
}
#footer {
height:50px; /* Whatever fixed height you desire */
}
Example:
http://jsfiddle.net/0qhevkbn/

Two Stacked divs and controlling heights

I am trying to stack two divs A and B.
Div A - will be scrollable but its height needs to be determined by the div underneath it, Div B so if the content in Div B changes, and it's height changes the height of Div A also changes.
Div B - needs to be aligned to the bottom of page on top of a absolute positioned footer. Its content needs to be aligned to the bottom.
I've tried using position relative and float by wrapping these divs in a wrapper, but the whole thing breaks when I try to keep the Div B aligned or positioned absolutely above the footer.
I've got a feeling this needs to go back to basics, any help would be greatly appreciated
thanks
Here's a basic example. I think I have correctly understood your requirement. This example has them appear to be stacked but in the HTML they are not actually stacked, they are nested. I wasn't sure if you could allow that in your solution but fingers crossed.
Example: http://jsfiddle.net/jyR2A/1/
CSS:
#divA {overflow-y:scroll;position:absolute;height:100%;top:-100%;background:green;width:100%;}
#divB {position:absolute;bottom:0;background:blue;width:100%;color:white;}
HTML:
<div id="divB">
<!-- Div A is nested so we can use divB's height -->
<div id="divA">
</div>
<!-- Div B content -->
<div id="divBinnerContent">
Line 1 <br />
Line 2 <br />
..Keep adding more lines to test how it works <br />
</div>
</div>
How it works:
divB is the parent element defining the height of divA. So if we set divB position relative or absolute and place divA inside then we can set divA's height to 100% to give it the height of parent element divB.
Now to position divA we make sure it has position:absolute and set top:-100% which will move it up the same distance as the height of its container divB. Position absolute not only allows us to position it correctly but it also removes it from affecting the height of its parent, divB.
And the content for divB I have made a nice container for it but it is not neccessary. Simply put it anywhere inside divB (but not inside divA) and it will be OK.
You can use the content to define the height,as I have, or use an absolute height set in CSS.
Hope this is what you were after.
Le-roy
I managed to achieve this with help from this question and fiddle.
Stack div elements in css vertically (with dynamic height)
http://jsfiddle.net/nCrEc/334/
Essentially the answer was giving my Div A a height without using the height parameter but instead using absolute positioning on top and bottom. Which meant changes to Div B changed the location of the Div A's bottom (oo er) which pushed the middle div up whenever another populates the bottom area.
<div class="con">
<div class="top"></div>
<div class="middle"></div>
<div class="bottom"></div>
</div>
then using this CSS
.con {
width:200px;
top:50px;
bottom:0;
left:0;
position:absolute;
background:#ff0;
}
.top {
width:200px;
height:20px;
position:absolute;
top:0;
left:0;
background:#f60;
}
.bottom {
width:200px;
height:50px;
position:absolute;
bottom:0;
left:0;
background:#f60;
}
.middle {
overflow-y:auto;
min-height:1px;
position:absolute;
bottom:50px;
top:20px;
left:0;
background:#06f;
}

Is there a way to specify as width of a contained div the full width of the scrollable area of the parent?

I found that if I put an overflow-auto div that contains other divs the width of those sub-divs is just the width of the visible part of the parent and not the width of the scrollable area.
You can see an example at http://jsfiddle.net/UdgCE/
Is there a way to specify as width the full width of the scrollable area instead?
I am not sure if this is ideal and it probably doesn't quite answer or match what you are intending to do.
However it appears as though the containers inside of the scrollable container exhibit similar behavior comparable to how a container would stretch a window. For example if you had a div with height:100%; and width:100%; it would stretch the view port and nothing more.
With that in mind, after messing around for a while, the only pure CSS solution I have found is to set specific "matching" pixel values to your inner / outer containers.
An example here ... http://jsfiddle.net/krishollenbeck/UdgCE/27/
HTML
<html>
<body>
<div style="overflow:auto" id="container">
<div id="inner-wrap">
<div style="white-space:pre" id="content">
This is a the text of the first div and it's veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery long
</div>
</div>
<div style="background-color:#FFFF00" id="yellow">
</div>
</div>
</body>
</html>
CSS
#yellow {
width:2000px;
}
#container {
border:1px solid red;
width:400px;
}
#content {
width:2000px;
border:1px solid #333;
}
#inner-wrap {
width:2000px;
}
​
This hardly seems ideal but it seems to work. I am guessing you will most likely have to use javaScript to measure the width of the scrollable container and then match the inner divs to that dimension.
Adding a "clearfix" to the wrapper div fixed it for me.
This makes the wrapping div expand to the width of the text. Not just overflowing.
http://jsfiddle.net/7a67j/

why positioned div is not expanding?

I have a div with position:absolute, left:0, right:0; widht:100%. This is fine with my code.
But when i have added another div, which it has width:2000px; my first div width is not expanding. Can you please suggest me.
This is my example. http://jsfiddle.net/vYhv4/
Thanks
The position:absolute property positions the element relative to its ancestor element, in your case that is the body of the document, which is not the width of your .displayElement class. One thing you can do to fix this is to contain both your .displayElement class and your absolutely positioned div, .box, inside of a container that is clearfixed that acts as the ancestor of your .box div, positioned relative.
Like so:
HTML
<div class="element-container">
<div class="box">test</div>
<div class="displayElement">
flash slider comes here
</div>
</div>
CSS
.element-container:before, .element-container:after {
content:"";
display:table;
}
.element-container:after {
clear:both;
}
.element-container {
zoom:1; /* ie hasLayout fix */
position:relative;
display:inline-block;
}
Demo
The first div will only expand to the width of the viewable area, it will not expand past that until you specify a width that is greater.
I assume this is because .box is aligning itself to the body. However, the body is 100% wide and isn't growing when .displayElement becomes wider than the viewport.
Is there any reason why you can't set the .box width to 2000px as well?
It is possible your parent container has a width set that is smaller than your 2000px element. I think as you have your div absolutely positioned with left and right being 0 your width will be the width of your parent container. width:100% wont expand your container to the width of child containers but to the parent.

CSS about two column layout

I have never thought that writing a simple two column layout is so complicated using css....haha
What I want to do is the following:
When the height of the content div exceed the height of screen size, scroll bar exist only in the content div. The users can only scroll the content div but the sidebar keeps static
The two columns should have the same height
My layout is:
<---------------container------------------->
<-------------------header------------------>
<-----sidebar-------><---------content--->
<------------------footer------------------->
<---End of container------------------------->
Here is my css file:
http://137.189.145.40/c2dm/css/main.css
#WorldContainer
{
width: 1000px;
margin: auto;
overflow: hidden;
}
.ContentColumn
{
float: left;
width: 500px;
overflow: auto;
}
<div id="WorldContainer">
<div class="ContentColumn">
Content goes here!
</div>
<div class="ContentColumn">
Content goes here!
</div>
</div>
That will give you a page where the main div cannot scroll but the two div columns can. They will be side by side. You question wasn't exactly clear so hopefully this is what you were after.
EDIT: In response to you showing the example site.
Your problem is really simple.
All of your divs have a height rule of height: 100%;
When you use percentage height, you are making it a percent of the container it is within, i.e Its parent container. It is NOT a percentage height of the entire window.
Every container is specifying a percentage height so the result is a height of 0.
Give your outermost div a fixed height and the problem will be resolved.
Additional Edit:
If you are concerned with making sure the outermost div always stretches to the bottom of the window then this is a css solution using absolute positioning:
#OutermostDiv
{
position: absolute;
top: 0;
bottom: 0;
}
Using this approach still causes a calculated height even though the outer div doesn't have a hard coded height. This will allow you to use percentage heights on your inner divs and maintain a outer div that stretches from top to the bottom of the visible window.
You'd have to set your container element to overflow:hidden;, and your content div to overflow:scroll; (and possibly do overflow-x:hidden; to hide the horizontal scrollbar). The problem with this is that if your sidebar & content are going to be the same height, then you would have to have TWO scrollbars - one for content, and one for sidebar.
You could probably solve this by using another container element around just sidebar & content, and setting the overflow: scrollbar; overflox-x:hidden; on it instead of sidebar/content.
You can also use display:table and display:table-cell to create columns if you're facing difficulties with float. Here's the CSS:
#container
{
width:960px;
margin:0;
padding:0;
display:table;
}
#sidebar
{
width:300px;
display:table-cell;
}
#content
{
width:660px;
display:table-cell;
}
and the HTML is:
<div id="container">
<div id="sidebar">
<!-- Sidebar Content Here -->
</div>
<div id="content">
<!-- Content Here -->
</div>
</div>
Hope this solves your problem. But display:table doesn't work in some old browsers.