Nested 100% heights - html

I'm working on a mobile site that has a structure that looks something like this:
body
---->Mobile container div (height 100%)
-------->Full page div (height 100%)
------------>Vertically centered div (height 200px)
My problem is that the full page div level comes out as 0px. Here's the relevant CSS:
html, body
{
height: 100%;
margin: 0;
}
.mobile
{
min-height: 100%;
}
.full-page
{
height: 100%;
position: relative;
}
.center
{
height: 200px;
top: 50%;
margin-top: -100px;
position: absolute;
}
The mobile container is filling the window height, but the full page (100% of the height of the mobile container) is being rendered at 0px height, which ruins the vertical centering.
Why is this happening?
JSFiddle
The red div is the mobile container
The yellow div is the full page div (it's not visible because it's 0px tall)
The green div is the vertically centered div

This is happening because of the following rule:
.mobile {
min-height: 100%;
}
Here's why.
CSS specs tell us the following about percentage height:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to auto. A percentage height on the root element is relative to the initial containing block.
This applies to your .fullpage container. You can see that the parent container of .fullpage, which is .mobile, does not have a height set explicitly, but rather via the min-height property:
The min-height property is used to set the minimum height of a given element. It prevents the used value of the height property from becoming smaller than the value specified for min-height.
You would think that the child container, .fullpage would take the min-height property into consideration when determining its height, but it does not. Browsers will not set the child element’s height (specified in percent) based on its parent’s computed height if only min-height is used.
To correct this, you could add height: 100% to:
.mobile {
min-height: 100%;
}

Related

Divs inside container div disappearing when min-height applied [duplicate]

I am trying to set a <div> to a certain percentage height in CSS, but it just remains the same size as the content inside it. When I remove the HTML 5 <!DOCTYTPE html> however, it works, the <div> taking up the whole page as desired. I want the page to validate, so what should I do?
I have this CSS on the <div>, which has an ID of page:
#page {
padding: 10px;
background-color: white;
height: 90% !important;
}
I am trying to set a div to a certain percentage height in CSS
Percentage of what?
To set a percentage height, its parent element(*) must have an explicit height. This is fairly self-evident, in that if you leave height as auto, the block will take the height of its content... but if the content itself has a height expressed in terms of percentage of the parent you've made yourself a little Catch 22. The browser gives up and just uses the content height.
So the parent of the div must have an explicit height property. Whilst that height can also be a percentage if you want, that just moves the problem up to the next level.
If you want to make the div height a percentage of the viewport height, every ancestor of the div, including <html> and <body>, have to have height: 100%, so there is a chain of explicit percentage heights down to the div.
(*: or, if the div is positioned, the ‘containing block’, which is the nearest ancestor to also be positioned.)
Alternatively, all modern browsers and IE>=9 support new CSS units relative to viewport height (vh) and viewport width (vw):
div {
height:100vh;
}
See here for more info.
You need to set the height on the <html> and <body> elements as well; otherwise, they will only be large enough to fit the content. For example:
<!DOCTYPE html>
<title>Example of 100% width and height</title>
<style>
html, body { height: 100%; margin: 0; }
div { height: 100%; width: 100%; background: red; }
</style>
<div></div>
bobince's answer will let you know in which cases "height: XX%;" will or won't work.
If you want to create an element with a set ratio (height: % of it's own width), use the aspect-ratio property. Make sure height is not explicitly set on the element for it to work. https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
.square {
width: 100%;
height: unset;
aspect-ratio: 1 / 1;
}
Historically, the best way to do this was to set the height using padding-bottom. Example for square:
<div class="square-container">
<div class="square-content">
<!-- put your content in here -->
</div>
</div>
.square-container { /* any display: block; element */
position: relative;
height: 0;
padding-bottom: 100%; /* of parent width */
}
.square-content {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
The square container will just be made of padding, and the content will expand to fill the container. Long article from 2009 on this subject: http://alistapart.com/article/creating-intrinsic-ratios-for-video
In order to use percentage(%), you must define the % of its parent element. If you use body{height: 100%} it will not work because its parent have no percentage in height. In that case in order to work that body height you must add this in html{height:100%}
In other cases to get rid of that defining parent percentage you can use
body{height:100vh}
vh stands for viewport height
You can use 100vw / 100vh. CSS3 gives us viewport-relative units. 100vw means 100% of the viewport width. 100vh; 100% of the height.
<div style="display:flex; justify-content: space-between;background-color: lightyellow; width:100%; height:85vh">
<div style="width:70%; height: 100%; border: 2px dashed red"></div>
<div style="width:30%; height: 100%; border: 2px dashed red"></div>
</div>
Sometimes, you may want to conditionally set the height of a div, such as when the entire content is less than the height of the screen. Setting all parent elements to 100% will cut off content when it is longer than the screen size.
So, the way to get around this is to set the min-height:
Continue to let the parent elements automatically adjust their height
Then in your main div, subtract the pixel sizes of the header and footer div from 100vh (viewport units). In css, something like:
min-height: calc(100vh - 246px);
100vh is full length of the screen, minus the surrounding divs.
By setting min-height and not height, content longer than screen will continue to flow, instead of getting cut off.
With new CSS sizing properties you can get away with not setting exact height on parent. The new block-size and inline-size properties can be used like this:
<!DOCTYPE html>
<style>
#parent {
border: 1px dotted gray;
height: auto; /* auto values */
width: auto;
}
#wrapper {
background-color: violet;
writing-mode: vertical-lr;
block-size: 30%;
inline-size: 70%;
}
#child {
background-color: wheat;
writing-mode: horizontal-tb;
width: 30%; /* set to 100% if you don't want to expose wrapper */
height: 70%; /* none of the parent has exact height set */
}
</style>
<body>
<div id=parent>
<div id=wrapper>
<div id=child>Lorem ipsum dollar...</div>
Resize the browser window in full page mode. I think the values are relative to viewport height and width.
For more info refer: https://www.w3.org/TR/css-sizing-3/
Almost all browsers support it: https://caniuse.com/?search=inline-size

Why isn't a containers height inherited, when it is sized with min-height?

I'm trying to make a container fill the entire page (or the viewport, whichever is larger), but ran into some trouble. I'm using the recommendations from this post: https://stackoverflow.com/a/17555766, to set the <html> and <body> to 100% height.
But I've noticed that the .Content div only fills the viewport when the <body> height is set with height: 100%, but not with min-height: 100%. Why is that? Why doesn't .Content pick up the height of the <body> when it's set with min-height? Is there a fix for this (without absolute positioning or fixed heights)?
html
<html>
<body>
<div class="Content">Content</div>
</body>
</html>
css
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
/* does not work for .Content: */
min-height: 100%;
/* does work for .Content: */
/* height: 100%; */
background: blue;
}
.Content {
background: red;
min-height: 100%;
}
codepen: http://codepen.io/anon/pen/mJEMVX
P.s.: when the <body> height is set with height: 100%, both min-height: 100% and height: 100% work as expected for .Content.
Percentage heights refer to the computed height property of the parent element. See the spec. When setting only min-height: 100% on the body element as per my answer to the linked question, the height property is left untouched at its default value of auto. The min-height property does not affect the computed value of the height property.
Because of this, min-height: 100% on your element does not have a parent height to refer to, and so it won't work. Once you set height: 100% on the body element, your element is able to refer to this height for its own percentage height calculation.
How to fix this depends on what sort of layout you're trying to achieve. The only purpose of setting min-height: 100% on the body element is to allow it to expand when the content height exceeds that of the viewport resulting in a scrollbar. If your content will only ever be exactly the height of the viewport, or you don't want body to generate scrollbars, it's as simple as replacing min-height: 100% with height: 100% on body.

Overflowing the viewport

Can anyone explain me on how the below fiddle is overflowing the viewport.
.row > .sidebar-fixed{
position: absolute;
top: 60px;
width: 220px;
height: 100%;
overflow-y:scroll;
}
.row > .sidebar-fixed.left{
left:0;
}
.row > .sidebar-fixed.right{
right:0;
}
.fixed-fixed {
margin: 0 240px;
}
http://www.bootply.com/X0Bie7aRN0
When specifying or hardcoding some top value, why should the height not be 100% and bottom be 0
.row > .sidebar-fixed{
position: absolute;
top: 60px;
width: 220px;
height: 100%; // should replaced by bottom: 0;
overflow-y:scroll;
}
What is so surprising? height: 100% means setting an element height to 100% of its parent IF the parent height is specified too. Then, you set its position to 60px from top, but it doesn't change an element height at all. So it's quite natural that its bottom edge is 60px below a viewport.
As for bottom: 0, when you specify top property - element's top edge is placed at a specified height relative to the top edge of its parent with position: relative|absolute. When you specify bottom property, element's bottom edge is placed at a specified height of its parent with position: absolute|relative. Specifying both these properties at once lead to stretching the element. This is actually quite a common way of specifying an element height.
Height's percentage values are relative to the element's containing block.
Provided your absolutely positioned element does not have any positioned ancestor (with position different than static), its containing block will be the initial containing block, in that case 100% height computes to the height of the viewport.
When you have defined a height property, without a bottom property, the top property will simply offset the element's position, but will not alter its defined height.
bottom:0 aligns the element's margin-box's bottom edge with the containing block's padding-box's bottom edge. (ref, demo)
And to demonstrate the initial containing block, heights and positioning behavior, see this demo.

Why body height is not 100% while using min-height property with 100% value

I have a page at
http://uberhealth.co/register.php
I have set the property to set the min-height to 100% but still as you can see the footer is not at bottom and thus the height is not getting set to 100%. how can i fix this?
Update
I have already given there
html, body{
height:100%;
}
and a container class for body
.cbody-full { min-height:100%; }
Though you've set a min-height (percentage) value for the <html> element, it doesn't have a explicit height value. Hence, the min-height property is not working for the <body> element properly.
From the MDN:
min-height
The percentage is calculated with respect to the height of the
generated box's containing block. If the height of the containing
block is not specified explicitly (i.e., it depends on content
height), and this element is not absolutely positioned, the percentage
value is treated as 0.
You could set a height of 100% for the <html> element, and min-height: 100%; for the <body>.
html { height: 100%; }
body { min-height: 100%; }
Update #1
Here's my attempt to fix your layout issue.
First note that you have to specify the height of the parent element, if want to use min-height for the child element.
You have multiple wrappers inside each other, changed all the min-height: 100% declarations to height: 100% (including the html, body, ...); and use min-height: 100% for the .cbody-full > container element.
Then, you may face the vertical scrollbar. That's because the computed height of the header and the footer is added to 100% of the height of the screen (In fact the .cbody-full > container element has the height of 100%).
You could fix that, by adding a negative top/bottom margin to the .cbody-full > container element:
.cbody-full > container {
min-height: 100%;
margin-bottom: -50px;
margin-top: -55px;
}
But, this cause the container goes over the header and/or the footer. In order to fix that, you could set a top/bottom padding to the container and use box-sizing: border-box to calculate the width and height of the box including the paddings and borders:
.cbody-full > container {
min-height: 100%;
margin-bottom: -50px;
box-sizing: border-box;
padding-bottom: 50px;
margin-top: -55px;
padding-top: 55px;
}
Just one more thing, you probably need to set z-index property for the header and footer elements, as follows:
#navbar, /* The header (navigation in this case) */
.footer {
position: relative;
z-index: 100;
}
Update #2
If you consider using Ryan fait's sticky footer, note that the footer shouldn't be inside of the .cbody-full element, it should be beside that. That's why it doesn't stay at the bottom of the page.
Hence, you could change your markup as follows:
<body>
<nav id="navbar"></nav>
<div class="cbody-full"></div>
<div class="footer"></div>
</body>
Then, follow the above approach for height and min-height properties, as well as position and z-index for the navigation and footer. Finally use the following for the .cbody-full element:
.cbody-full {
min-height: 100%;
margin-bottom: -50px;
box-sizing: border-box;
padding-bottom: 50px;
margin-top: -55px;
padding-top: 55px;
}
even if you dont put min-height:100% its always at 100%. The height is always relative to the content always given that the height is not staticcaly defined

CSS Height working but min-height doesn't work

I am having a strange rather weird problem. The problem is a small one that is I want to set min-height to 100% that is the content of the page should span whole screen of he user and if possible the page should extend down if content exceeds 100%. A simple way would be to set min-height:100% and to set height:auto that is exactly what I want but regardless of how many times I try it the problem remains there.
I am using height auto and min-height:100% on all the elements but it doesn't work. If I remove min-height to include only height:100% then it works like a charm but then when the content is larger it overflows whole footer.
Please help me here is css:
html, body, container, row, col-lg-3, col-lg-9 {
min-height: 100%;
height: auto !important;
height: 100%;
}
.container {
max-width: 1170px;
min-height: 100%;
height: auto !important;
height: 100%;
}
.col-lg-3 {
min-height:100%;
height:100%;
}
.col-lg-9 {
min-height: 100%;
height: 100%;
}
Here is the page showing the problem :
http://contestlancer.com/ai/GP/
Yes this is a pain but that's how it works. Height can be inherited from positioned parents but not when these have a min-height property.
Children of elements that have a min-height set to 100% cannot inherit their parent's height via percentage...
https://stackoverflow.com/a/8468131/1491212
CSS2.1 specs :
The percentage is calculated with respect to the height of the
generated box's containing block. If the height of the containing
block is not specified explicitly (i.e., it depends on content
height), and this element is not absolutely positioned, the value
computes to 'auto'.
Use position: relative; height: 100% on containers to work around the problem, and add min-height: 100%; to the deepest child.