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.
Related
In css the position properties seem simple but in reality, there‘s tons of weird edge cases that seemingly come out of nowhere when building a layout.
One thing that I always skimmed over was when I would see height: auto or width: auto. In trying to understand this better, I came across the below code and I am hoping someone can try to explain why this happens.
The reason I am confused is if position: absolute is used, since height and width are both auto on the parent, the parent becomes 50px x 50px.
This doesn't happen though when the parent is relatively positioned. When the parent has position: relative, height: auto works but width: auto does not cause the parent to take on the width of it‘s child as I would expect. Instead with position: relative, the element stretches the length of the whole line.
body {
margin: 0;
padding: 0;
}
.a {
/*
why is width auto not respected, but height auto takes the
height of the child??
if position was absolute then the height and width
both take on the dimensions of the child
*/
position: relative;
background: #ff9999;
top: 10px;
height: auto;
width: auto;
}
.b {
position: relative;
background: blue;
top: 10px;
height: 50px;
width: 50px;
}
<div class="a">
<div class="b"></div>
</div>
It's not only related to position but also to the display of the element. You can find how the width of each element is calculated here https://www.w3.org/TR/CSS22/visudet.html#Computing_widths_and_margins
You will see a lot of categories. When your element is position: relative we don't care about position but we see other criteria like the fact it's a block level element and it follows the rule:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
And when it's position: absolute we consider different rules and somewhere you can read:
.. then the width is shrink-to-fit
I won't detail each case but you can read the first link to understand all the cases of width calculation. They are a lot but a quick reading will give you a clear idea on how the width and height of the elements is calculated.
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%;
}
All the examples I've seen say to do the below code, but this does not work (see jsfiddle below).
html { height: 100%; min-height: 100%; }
body { height: 100%; min-height: 100%; }
.stretchable { position: absolute; width: 100px; height: 100%; min-height: 100%; }
Showing it not working: http://jsfiddle.net/yVDXQ/481/
How do I use CSS only to force a div to be the height of the document body, not the window?
Look closer... your body element is not the full height of the content. Remove the height: 100% and instead add position: relative to the body element. Here is a fork of the fiddle:
http://jsfiddle.net/7j8vrnr8/
Remember that absolute positioned elements have their height/width based on the first relative positioned element as you move up the hierarchy.
position: relative
First of all, you need to remove height:100% for body – otherwise the body will only be as high as the viewport (with the rest of the content overflowing it).
And then, since your .stretchable element is positioned absolutely, you simply remove any height and min-height from that completely (so that effectively height:auto is in place) – and position it from the top and bottom, so that those two values determine its height. (position:relative added for body, so that this element gets taken as point of reference for the absolute positioning).
http://jsfiddle.net/yVDXQ/484/
I'm trying to make an absolute positioned element to take 100% height of body, where body is set to take 100% of content, that might exceed window height. But, I cannot seem to nail it.
CSS:
html
{
height: 100%;
}
body
{
min-height: 100%;
}
#push
{
padding-top: <to exceed window height>;
}
#absolute
{
position: absolute;
left: 0px;
top: 0px;
width: 100%; /* to take full width of body */
height: 100%; /* to take full height of body */
}
HTML (assuming that this is all the content within <body>):
<div id="push"></div>
<div id="absolution"></div>
Fiddle: http://jsfiddle.net/psycketom/DbV4R/
I have tried to make #absolute first child of body, last child (assuming that DOM hasn't yet calculated height at the start of body). Also, tried removing it's height property in exchange of top: 0; bottom: 0; - no luck.
Well, I assume it's because of absolute takes element out of document's flow, but, isn't there a way around it?
My actual example is where I want to have an absolute positioned background attachment element that holds numerous absolutely positioned elements. The element is going to have overflow: hidden to not make any scrollbars.
What options do I have here, except javascript and defined height?
Update:
If you inspect fiddle, you'll notice that #absolution takes 536px in height, where body takes 600.
I want, #absolution, to also take 600px - full height of body.
Make the body position relative? Remove native margin/padding for body to get rid of all the red (http://jsfiddle.net/DbV4R/6/)
http://jsfiddle.net/DbV4R/5
body {
position: relative;
}
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