CSS html 100 % width height layout - css

I am trying to build a layout that consumes all the space that is visible in browser. I set html, body height 100% as was suggested in different SO posts. Following is the markup that I am trying
<div>
<div class="header">
</div>
<div class="main">
<div class="container">
<div class="content"></div>
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
max-height: 100%;
}
.header {
height: 30px;
background-color: #000;
}
.main {
height: auto;
padding-right: 0px;
max-height: 100%;
width: 100%;
display: block;
clear: both;
background-color: #eee;
}
.container {
width: 90%;
overflow-y: scroll;
background-color: #ccc;
}
.content {
height: 2000px;
width: 80%;
background-color: #fff;
}
the content div height cause the whole body to grow and hence the browser's default scroll bars are shown. Though I have set the container div to scroll in order to display the content of content div, still the scroll bars for container div don't show. How can I fix this.
here is the jsfiddle

Edited:
By default the height of the div element depends on its content (unlike width which takes 100% width of the parent). That's why when you specify the height of inner element as a percentage it won't be accurate if your parent tag has no explicitly defined height (that means height has to be defined up to the very top of the DOM since height is not inheritable).
In your case you need to add height: 100%; or any other height to your .container , .main and the wrapper div
modified fiddle

Related

Why does computed height of body with height 100% not match its actual one?

This is a simple html page. I set html, body height 100%, but there is a quite long content.
Now I make the browser scale to a small size and scrollbar will show. I open Chrome Dev tool, the computed height of body seems the size of viewport, say 321px.
Normally, a body container of 321px computed height will end at the top of the page, but actually the body seems has the same height of the whole page, 1000px here.
That is my puzzle, why does the computed height not match the actual height?
html,body{
width:100%;
height:100%;
background: #ccc;
}
.content {
width: 20px;
height: 1000px;
background: #666;
}
<html>
<head></head>
<body>
<div class="content"> </div>
</body>
</html>
Here you are having an overflow, so the height of the body and the html are different from 1000px and equal to screen height because of the 100%.
The thing that make you think your body has 1000px is probably the background that cover your whole content but here you are facing a special behavior of the background called background propagation.
You may change the background of the html element and you will see the issue clearly:
html,
body {
height: 100%;
background: #ccc;
margin:0;
}
html {
background: red;
border:5px solid green;
}
.content {
width: 20px;
height: 1000px;
background: #666;
}
<div class="content"> </div>
As you may notice, the body height is not equal to the content height but limited to the screen height and your content is simply overflowing the body element. I also added a border to the html element to show that its height is also limited to screen size and to better highlight the background propagation behavior.
When you set height:100% to an element you basically telling it to take it's parent's height as it's own height.
Example :
* {
text-align: right;
}
#parent {
height: 100px;
background: red;
}
#kid {
height: 100%;
width: 200px;
background: lime;
}
#grandkid {
height: 1000px;
width: 100px;
background: orange;
}
<div id="parent">
<div id="kid">
<div id="grandkid">
</div>
</div>
</div>
If you expect the parent to take it's children's computed height, don't define a height for it.
Example :
#parent {
/* Parent without height takes all of it's children's heights*/
background: red;
}
.kids {
height: 1000px;
width: 40px;
background: lime;
margin-top: 10px;
}
<div id="parent">
<div class="kids"></div>
<div class="kids"></div>
</div>

Why is a max-width / height img not constrained by the parent percentage height / width in Firefox?

I have a set of absolutely positioned fluid divs within a container and want to display an image within each div that is vertically and horizontally centred within the container and fills up as much of the available space as possible. Due to using these images for other purposes they have to be img tags and not background images (otherwise with CSS3 this would be easy!)
I would have thought the following code should do just this but for some reason on Firefox the image displays in it's original dimensions and is not constrained by the parent dimensions. In Chrome the width seems to be correctly linked to the container however the img height is not constrained by the container height.
I could understand it if there was no width/height set on the parent but every element in this example has a percentage width/height set so i don't think this is the problem. FYI if you set a specific width:100% on the img then this constrains the width correctly (but can't be done as it means it's loses the correct aspect) however it still doesn't work for height even if you set the height to 100%,
You can see a jsfiddle at http://jsfiddle.net/deshg/xrzk084d/ and the code is below.
If anyone could point me in the right direction as to what i'm doing wrong that would be greatly appreciated!
body, html, #outer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
background-color: #ffcc00;
display: table;
position: absolute;
left: 20%;
top: 30%;
width: 60%;
height: 40%;
}
#containerinner {
display: table-cell;
width: 100%;
height: 100%;
vertical-align: middle;
}
#containerinner img {
max-width: 100%;
max-height: 100%;
margin: 0 auto;
display: block;
}
<div id="outer">
<div id="container">
<div id="containerinner">
<img src="https://dl.dropboxusercontent.com/s/wypn5e7n5bgeoic/landscape.png?dl=0" alt="">
</div>
</div>
</div>
Cheers,
Dave
The issue here is that set a vertical alignment of middle is impossible without specifying the height of the containing element. In your situation, you want the height to be relative to the viewport which creates additional difficulty.
However, if we use both the vh (viewport height) and vw (viewport width) units defined in CSS3 we can achieve what you're after. I have then assumed that you want your image to be center aligned and with a max width and height of 60% and 40% of the viewport respective. I have reduced the markup to the following (See JSFiddle):
#container {
position: fixed;
top: 30vh;
left: 20vw;
background-color: #ffcc00;
}
#inner {
display: table-cell;
vertical-align: middle;
text-align: center;
height: 40vh;
width: 60vw;
}
img {
display: block;
max-width: 60vw;
max-height: 40vh;
margin: 0 auto;
}
<div id="container">
<div id="inner">
<img src="https://dl.dropboxusercontent.com/s/wypn5e7n5bgeoic/landscape.png?dl=0">
</div>
</div>

How can a scrollable div and a fixed bottom div dynamically change height inside a wrapper?

I'm trying to stack 2 divs inside of a wrapper div. I need one div of a set height to stay at the bottom of the wrapper div, and I need the top div to scroll. I can't separate them because I want the wrapper to grow with content in the top div until it is too big for the screen and then start scrolling without hiding the bottom div.
Here is an example.
I can almost figure this out, however the bottom div overlaps the last bit of information in the content div. Is there a way to change the height of the top div such that it leaves room for the bottom div no matter it's height?
HTML
<div class="wrapper">
<div class="top">
<div class="content">
// Dynamically added information that
// grows the height of div.content
</div>
</div>
<div class="bottom">
// Input box or static button panel
</div>
</div>
SCSS
.wrapper {
max-height: 100vh;
position: relative;
overflow: hidden;
.top {
max-height: inherit;
overflow: hidden;
.content {
max-height: inherit;
overflow-y: scroll;
}
}
.bottom {
position: absolute;
bottom: 0;
}
}
You can add a padding-bottom:150px to the wrapper (150px is the height of the bottom div). Like here. This will give enough space for the bottom div.
It's not that hard. Just need to use the calc feature:
Fiddle
You can keep the wrapper dynamic by setting the value in the variable, and then forego your max-height: inherit rules.
Here's the relevant SCSS
$box_height: 100vh;
.wrapper {
height: $box_height;
max-height: $box_height;
position: relative;
overflow: hidden;
.top {
max-height: unquote("calc(" + $box_height + " - 150px)");
overflow: hidden;
.content {
max-height: unquote("calc(" + $box_height + " - 150px)");
overflow-y: scroll;
}
}
}
There is no way without adding padding or margin bottom to any of the div with content.
Here is code:
.wrapper {
max-height: 100vh;
position: relative;
overflow: auto;
.top {
padding-bottom:150px;
}
.bottom {
position: fixed;
bottom: 0;
left:0;
width:100%;
height:150px;
background-color:red;
}
}
you actually don't need the extra div ".content". The padding to div ".top" is the value equal to the height of the bottom fixed div. In case of dynamic height of bottom fixed div you need to change the padding value of top div using jQuery (no other alternative). But for the change in content dynamic, you don't need to add any jQuery.
Hope this helps.
I simplified it a bit and got what I think you're going for:
<div class="wrapper">
<div class="top">
// Dynamically added information that
// grows the height of div.content
</div>
<div class="bottom">
// Input box or static button panel
</div>
</div>
then for css:
body{
height: 100vh;
margin: 0;
}
.wrapper {
overflow: hidden;
width: 100%;
}
.content {
width: 100%;
max-height: calc(100vh - 150px);
overflow-y: scroll;
}
.bottom {
height:150px;
width:100%;
background: #f00;
}
check out the jsfiddle here

Expand div to fill rest of browser window and center content

I'm trying to achieve a particular layout for a website I'm working on, but I'm not sure how to about it. The layout will look like this:
The header has nothing special about it. The footer has position: fixed and bottom: 0px. The main body content needs to be centred vertically within the space from the bottom of the header down to the top of the footer. If the window height is adjusted, the body content should remain centred between these two points. Also note that the website will be responsive, but only from 960px up to about 1600px (so the minimum width it will ever be is 960px).
My only idea on how to achieve this is to have the div containing the body content somehow automatically expand to always be the full height from the bottom of the header down to the bottom of the browser window (and then add some padding at the bottom to account for the footer), then use display: table on this containing div, and use display: table-cell and vertical-align: middle on a child div.
Are there any other (preferably CSS-only) ways I could potentially do this? If not, how can I get the containing div for the body content expand to always be the full height from the bottom of the header down to the bottom of the browser window?
Here is one solution, for a header with a fixed height.
Your HTML needs to have the following pattern:
<div class="header">Header</div>
<div class="main-wrap">
<div class="container">
<div class="content">Content...</div>
</div>
</div>
<div class="footer">Footer</div>
and the CSS:
html, body {
height: 100%;
}
body {
margin: 0;
}
.header {
height: 50px;
background-color: beige;
}
.main-wrap {
position: absolute;
top: 50px;
bottom: 50px;
width: 100%;
background-color: silver;
overflow: auto;
}
.container {
display: table;
height: 100%;
width: 100%;
}
.content {
border: 1px solid blue;
display: table-cell;
height: 100%;
width: 100%;
vertical-align: middle;
}
.footer {
height: 50px;
width: 100%;
background-color: lightblue;
position: fixed;
bottom: 0;
}
See demo at: http://jsfiddle.net/audetwebdesign/aGTKs/
It is possible to adapt this to a header of flexible height.
The .main-wrap container defines the space between the header and footer.
The .container block uses display: table and inherits the height from .main-wrap.
Finally, .content uses display: table-cell, which allows you to use vertical-align: middle (default value) to center the content vertically.
You need to set the height of body and htmlto be 100% to capture the height of the view port.
You can hack it by doing {position: absolute; bottom: 0} !

Div won't stretch the full height of the page (yup, I've Googled plenty)

I'm trying to stretch the content of a div the height of the page. I've Googled the problem and so far nothing works. The whole thing is starting to give me a headache. Perhaps someone more experienced could take a look at my code? The full stylesheet is >400 lines, so I'm including what is (hopefully) relevant.
"Wrapper" takes up 100% of the page height, whereas "contentShadow" stretches only to the height of the text in the div "content".
Edit: as far as I can tell, every container has its height set to 100%, which whould make "contentShadow" 100% as well. Right...?
Edit 2: I'm starting to see the problem, but don't know how to solve it. While the following code will keep the footer down, it also means that since .wrapper doesn't have height:100%, "contentShadow" will not stretch. The question then is how I keep my footer down while changing this code:
.wrapper {
min-height: 100%;
height: auto !important;
margin: 0 auto -37px;
}
To this:
.wrapper {
height: 100%;
}
Basic structure of the page:
<div id="body">
<div id="headerWrapper"></div>
<div id="wrapper">
<div id="contentShadow">
<div id="#contentWrapper">
<div id="content">
<!-- contentshadow stretches the height of this content and no further, but SHOULD stretch the height of the entire page -->
</div>
</div>
</div>
<div id="push"></div>
</div>
<div id="footer"></div>
Css rules relevant to these divs:
html, body {
height: 100%;
}
#headerWrapper {
height: 314px;
width: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -37px;
}
#contentShadow {
min-height: 100%;
width: 994px;
background-image: url(../images/contentShadow.png);
background-repeat: repeat-y;
margin-right: auto;
margin-left: auto;
}
#contentWrapper {
min-height: 100%;
width: 940px;
margin-right: auto;
margin-left: auto;
padding-right: 16px;
padding-bottom: 16px;
padding-left: 16px;
padding-top: 17px;
background-color: #EDECEC;
overflow: hidden;
}
#content {
min-height: 100%;
}
.footer, .push, {
height: 37px;
}
.footer {
background: white;
clear: both;
height: 37px;
}
You have really wrong code:
.wrapper matched <div class="wrapper"> not <div id="wrapper">.
<div id="#contentWrapper"> is not correct, you should try <div id="contentWrapper">
height: auto; is the problem. The wrapper needs to be 100% height, not auto...
the height: 100% after height: auto !important doesn't make sens, because of the !important keyword.
Maybe it's the default margins and padding, have you tried this?
body {margin: 0px; padding: 0px; }
I had this issue for the better part of my life, but I just solved it for myself, so I'm sharing, just in case somebody else can benefit.
My HTML/BODY selector is set to height:100%.
My container div within the HTML/BODY selector is set to min-height:800px.
My CONTENT div inside of the CONTAINER div didn't have a height, and I had the issue of the div not stretching to the bottom of the page. When I inspected this div, I noticed that for some reason, it was stretching way below its container div, pushing it up and creating that annoying space at the bottom of the page. Once I placed a height on that inside DIV, the issue went away for me.
I hope this helps.
The contentShadow must have overflow: auto. Try this
body, html { height: 100%; margin: 0; padding: 0; }
#container { width: 100%; height: 100%; overflow: auto; display: block; }
<body>
<div id="container">
This should fill the page!
</div>
</body>

Resources