What is the logic behind { height: 100%; position: absolute; } getting browser height? - css

Okay, so there's three ways to get browser window height (NOT full web page height, that is the difference).
Vertical height unit, explained wonderfully here.
jQuery
Using { height: 100%; position: absolute; } on an element. (jsfiddle)
I do not understand the logic behind #3 on my list.
height: 100% and absolute positioning. height: 100% fills up the parent. Positioning absolute also is relative to the parent, so shouldn't it take the full height of the page. How does the viewport come into play?
I know that fixed is relative to the viewport, but I thought that was the difference from absolute. The height: 100% div does have a parent, its the body, it should be relative to that.
Can someone please explain?

An absolutely positioned element is placed in relation to the first parent that is also positioned. The body element has no positioning applied to it in your example. Therefore, the div has no reference since absolutely positioned elements are taken out of the normal flow.
If you assign positioning to the body, typically position:relative;, you will find what you are looking for.
W3C CSS2.1 explanation

Related

Strange container div behaviour

I'm asking this for learning purposes; there aren't any negative aspects on this behaviour, but I just wonder if this could have any negative consequences in the future.
So I have a container div: content_wrap, which has two other div's: side_bar and main_content. The container div is 980px width, and is used to center its contents using margin-left and margin-right.
It's doing this correctly, however, when I was debugging the page (in Firefox), I noticed that the browser renders the div as being 0x0px and renders the parent div off-screen. However, it does position the child divs correctly. See this JSFiddle for an example: http://jsfiddle.net/7fsXp/7/
I Googled this and most of the answers have something to do with floats and are solved by using clear:both, but I don't use any floats. I did notice that if I change the main_content div from position:absolute; to position:relative;, the content_wrap is displayed correctly. Or I can fix it by setting a height for content_wrap.
I don't actually need to be able to see the content_wrap, so there isn't really a problem, as it is doing its job in means of centering the child divs. I just wondered if it would be a bad practice to leave it like this? Is it a bad thing, or does it matter?
Try adding other elements to this HTML and enjoy the horror :D
There are actually many things in your code, that I wouldn't do. First of all, when an element is with position: absolute or position: fixed its layout is "ignored" by other elements or in other words cannot "push" any element and that is why your container is having 0 height. It's like they are ethereal (best explanation ever, I know).
You should check this article on positioning -- http://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/
The fact that they are in the place you expect them to be is that there are actually no other elements in the HTML and the absolute element is positioned relatively to the body and so is the fixed one (but that's what elements with position: fixed always do). Looks what happens when I add some other content to the parent div -- http://jsfiddle.net/7fsXp/13/
So long story short - you shouldn't form your layout with absolute or fixed elements if you can do it without them.
position: fixed and position: absolute take the elements out of the flow, so using either of these positions on all child divs will collapse the parent div entirely.
If you have content below a collapsed div, it will flow up and over/under that content like this.
You don't need to position the main_content div absolutely, but you'll need to change a few things to top align the sidebar and main_content.
DEMO
Since sidebar is fixed, it's using the document, not the container div as a reference for top, while main_content would use the body (unless you add position: relative to the container). Getting rid of the body's default padding/margin will fix the small alignment difference.
body {
padding: 0;
margin: 0;
}
#main_content {
//remove position: absolute;
margin-top:70px; //top: 70px won't work unless you specify position
}
It depends on what you are willing to do, but because the default position for div is position: static; changing the position: relative; will avoid the collapse of parent div.

div with `position:fixed`, but stil have same behaviour as with `position:relative`

When working with position:fixed; this is the expected result one would get:
What I actually want to achive is:
as in this result when working with two position: relative; elements
Don't get me wrong, I know how position: fixed or position: absolute works and should behave, how I haven't come around how to get both properties for the same div...
One approach wich works, but isn't a satisfying solution is that I put a position: relative -div below my fixed element, not allowing the second element moving below the fixed element because it is already taken by the extra div.
So I have tried to get this second relative div working with :after or :before pseudo-elements. This doesn't quite seem to work
div:after, div:before { position: relative; }
it somehow get's mixed up because the element itself is
div { position: fixed }
and turning fixed and relative around obviously also doesn't work because fixed will be bound to the relative - element.
Any ideas?
And if somebody is wondering why I need to use fixed and don't just go with relative : it's for scrolling reasons.
why not use a margin left on the relative div?
http://jsfiddle.net/q3nQr/1/
html
<div id="fixed"></div>
<div id="relative"></div>
css
#fixed { position: fixed; width: 60px; height:100px; background: red; }
#relative { position: relative; width: 300px;height:1000px; background: green; margin-left:65px; }
UPDATE
Take a look at the w3 spec for static positioning (just read the first two paragraphs).
http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning
Absolutely positioned elements are removed entirely from the document
flow. That means they have no effect at all on their parent element or
on the elements that occur after them in the source code. An
absolutely positioned element will therefore overlap other content
unless you take action to prevent it. Sometimes, of course, this
overlap is exactly what you desire, but you should be aware of it, to
make sure you are getting the layout you want!
Fixed positioning is really just a specialized form of absolute
positioning; elements with fixed positioning are fixed relative to the
viewport/browser window rather than the containing element; even if
the page is scrolled, they stay in exactly the same position inside
the browser window.
This means that elements with fixed or absolute positions do not associate with any other elements in the document, this means they cannot effect the width of another element. If the width of the static element is not known, I think you will need manipulate the DOM with javascript; something as simple as (jquery, not tested):
var staticwidth = $("#static").width();
$("#relative").css('margin-left', staticwidth + 'px');

CSS Relative and Absolute Positioned Elements Stretch the Container

Can you help me with my dilemma? I have a container (BODY in this case) that has position:relative set. Inside it I have two div's. One relative and one absolute positioned (in this order).
The problem is that whenever I set some margin-top to the relative positioned element, the container's height (body in this case) stretches vertically.
For example, even though I have set height: 100% to the container, its size when viewed is 100% + the margin-top of the relative positioned child element.
Here's a fiddle:
http://jsfiddle.net/xJ75R/7/
First of all, you should not give a relative position to the body, since body takes up the whole page.
Anyway, be specific when applying the relative position to another element, so if you have a class of "lists" then use
.lists { position: relative; top: something; left: something }
or margin, or whichever rule.
If you are just having problems with the body tag after giving some margin to ANOTHER element (though I do not see how this would happen), then give the body a margin of 0, like:
body { margin: 0; }
and if that doesn't work then use !important like
body { margin: 0 !important; }
On a side note, use firebug addon for firefox to make your CSS life easier and see what's happening on the fly.

position relative elements after absolute elements

I have a site with absolute positioned elements on it, for example the top Navigation of the site:
#topNav
{
position: absolute;
top: 100px;
left: 50%;
height: 40px;
width: 1000px;
margin-left: -500px;
}
Now I created a sticky footer like on the following site:
http://ryanfait.com/resources/footer-stick-to-bottom-of-page/
Now, the problem is that the footer will "overlap" the topNav,
because the topNav is positioned absolute, which means it's "outside of the normal float of elements". The relative position will not "notice" that there is the topNav before.
Before I start creating additional "pusher divs" for each absolute positioned element I would better ask if there are better practices than "pusher divs" or should I even not use position absolute on my elements?
EDIT:
JsFiddle here: http://jsfiddle.net/dkxUX/15/
When you scale down your browserwindow you'll find #footer overlapping all elements before it.
You could just apply a 140px top margin/padding to the body or other container element which would make the topNav's height and offset accounted for.
Better yet, don't set position to absolute in this case - it appears to me that all you're doing is horizontally centering a 1000px wide div.
/*top-margin of 100px + center the element*/
#topNav {width:1000px; height:40px; margin:100px auto 0;}
Update: I see your jsfiddle now. You could account for all absolutely positioned elements when setting the margin/padding as suggested in the first paragraph You are using absolutely positioned elements when normal document flow could be relied on.
a little bit too late to give an answer but it may help someone in the future, I came up with that problem not too long ago so here was my shot at it, using jquery since I couldn't came up with a CSS solution that wasn't removing the DOCTYPE tag (which isn't something you should do, anyways).
So here it is.
$("#CONTAINERDIV").prepend("<div id='relativefix' style='position:relative;margin-top:"+($("#YOUR_ABSOLUTE_DIV").offset().top+$("#YOUR_ABSOLUTE_DIV").outerHeight()+30)+"px'></div>");
$(window).resize(function(){
$("#relativefix").css("margin-top",($("#YOUR_ABSOLUTE_DIV").offset().top+$("#YOUR_ABSOLUTE_DIV").outerHeight()+30)+"px");
});
So yeah, that's all there is to it, you just dynamically add another div at the start of the container hard-placed under the absolute div, that will force all subsequent relative divs to me placed after it, it is like a clear fix for someone who ran out of ideas.

Does padding of relatively positioned element affect (0,0) of absolutely positioned child element?

This is a CSS issue that doesn't make sense to me..
Right now I have something like this:
.container {
height: 500px;
width: 500px;
position: relative;
padding: 10px;
}
.child {
top:0px;
left:0px;
position:absolute;
width: 100px;
height: 100px;
}
The child right now disregards padding of parent. This seems counter-intuitive to me. Am I missing a quick fix (I can't add padding/margin to child)? Did I mess up the DOCTYPE?
Thanks!
Matt Mueller
Since you have specified position absolute for the child element this behavior is the correct one. The child will be positioned absolutely with the left and top value.
In the absolute positioning model, a
box is explicitly offset with respect
to its containing block. It is removed
from the normal flow entirely (it has
no impact on later siblings). An
absolutely positioned box establishes
a new containing block for normal flow
children and absolutely (but not
fixed) positioned descendants.
However, the contents of an absolutely
positioned element do not flow around
any other boxes. They may obscure the
contents of another box (or be
obscured themselves), depending on the
stack levels of the overlapping boxes.
Visual Formatting model - Absolute positioning

Resources