CSS Positioning is not working as expected - html

Here is my code
CSS
h2
{
position: absolute;
left: 100px;
top: 150px;
}
h1
{
position: fixed;
top: 300px;
}
HTML
<h1>
Heading for Fixed Position
<h2>
This is a heading with an absolute position</h2>
</h1>
I'm new to CSS so was experimenting with positioning. I read some where
An absolute position element is positioned relative to the first parent element that has a position other than static. If no such element is found, the containing block is <html>:
If that is right then This is a heading with an absolute position message must be below the Heading for Fixed Position since h1 is the parent object and h2 being a absolute object must be positioned relative to h1. Please correct if I'm wrong.
Here is the JSFiddle link:
http://jsfiddle.net/KXmgG/

I would like to explain you how positioning actually works, there are 4 types
Static (Default)
Relative
Absolute
Fixed
Static position is nothing but a normal flow of the document where elements render on after the another (Excluding floats)
Relative position is something special, which turns out to be a great power when used with position absolute. When you want to use top, left, bottom and right instead of margins, you need to assign position: relative; to that element, after doing so, top, left, right and bottom properties will work.
When you use position: absolute; it gets out of the document flow, so if you have an element called div width class a. Now if you assign position: absolute; to class a, it will get out of the document flow, so when you use top: 0; it will fly away to the top of the document. So in order to restrict it, we wrap a container with position: relative; so that when you use position: absolute;, it will be absolute to that particular element and not the entire document.
Demo 1
Demo 2
Position fixed is entirely different, it is also out of the document flow as same as position: absolute; but the difference is that fixed positioned element cannnot be relative to any element, it has no contact whatsoever with any element, it is always calculated from the top, left, right and bottom of the window and not the element, also a fixed position element will flow as the user scrolls the document.
Demo
Coming to your answer, you are using fixed position and absolute position, both are out of the document flow, so they have no relation what so ever...
You are using top: 300px; for fixed position and top:: 150px; for absolute positioned element, so the fixed element will render below the absolute element, but when you try to scroll, your fixed element will scroll along where as position: absolute; element won't.
Edit as you commented
Go to w3c Validator and validate your document here

"An absolute position element is positioned relative to the first parent element that has a position other than static. If no such element is found, the containing block is :"
Yes but you dont have position:relative declared.
If you want you're parent transform you're html by this :
<div class="parent">
<h1 class="child">blabla</h1>
<h2 class="child">blabla</h2>
</div> <!-- end parent -->
<div class="relative">
<h1>
Heading for Fixed Position</h1>
<h2>
This is a heading with an absolute position</h2>
</div>
CSS :
.relative{
position:relative;
}
JSFIDDLE with
position relative / fixed / absolute /]
http://jsfiddle.net/KXmgG/1/

Related

CSS absolute position orients on sibling rather than parent

I am a little confused about absolute positioning right now. I have always thought that if I position an element absolutely it would be positioned relative to it's parent element (in contrast to relative to it's usual position like relative positioning). During homework I now came across this situation and I'm confused:
<body>
<div> <!-- This is colored red in my example -->
...
</div>
<div style="position: absolute;"> <!-- This is colored green in my example -->
...
</div>
</body>
What I would expect:
What I got:
Of course when I set an actual position with left/right/top/bottom I get what I would expect from an absolutely positioned element. So is position: absolute just set to take the exact position it would be at without position: absolute when not specified otherwise?
To clarify:
"I have always thought that if I position an element absolutely it would
be positioned relative to it's parent element"
Nope. If an element has position: absolute;, it is positioned relative to the nearest parent in the DOM chain that has position: relative; or position: absolute; specified on it. If no parents have it (ie. they are all position: static, which is the default), then it is positioned relative to the document (page).
When using position: absolute, always:
Be aware of what parent you want it positioned relative to, and make sure that parent has position: relative; on it.
Specify one or more of the top/right/bottom/left attributes on the absolutely positioned object.
You are confused with the difference between position and display.
Position will change which element your element will be positioned relative to. In your case, your child div is now positioned to the body element. That's why it's on top.
Also you need to be aware that div is displayed as block, which means it will take all the width. If you want to align 2 divs left and right, the modern way is to use flexbox. The old way is float left/right.
I have made an article to explain CSS position in details:
https://www.youtube.com/watch?v=nGN5CohGVTI

Why does a relative positioned element appear above a floated element?

I have two elements: one with relative positioning that defines most of my header, and a smaller one that I'd like to "float" on top of it.
<div id=floater style="float:right">
Floater!
</div>
<div id=header style="width: 100%; position: relative; background-color: lightgreen">
This is the header
</div>
As shown in this fiddle, the floated component is invisible. But if you remove the position: relative, the floated element pops right up. Futzing with the z-index hasn't yielded anything of interest.
The header component isn't "mine"; it's inherited through React-Bootstrap. I could override, but right now I'm mostly looking to understand the interaction of float and relative positioning.
Elements without a position property set will default to "position:static" which ignores all positioning properties such as z-index. By setting relative positioning to the header element you have introduced the z-index positioning property to that element bringing it in front of the floater element which does not have a z-index property.
Since z-index will be ignored with a static floater element you will have to give that element a position property (absolute, relative or fixed) so it can have z-index as well.
For your example "position: relative;" would work. Once you have set the position property on the floater element you would need to add a z-index value to it that's higher then the header element. Which in this case z-index:1 would be a higher value since z-index is set to default.
Example:
<div id=floater style="float:right; position: relative; z-index: 1;">
Floater!
</div>
<div id=header style="width: 100%; position: relative; background-color: lightgreen">
This is the header
</div>
When elements are positioned, they can overlap other elements. If two positioned elements overlap without a z-index specified, the element positioned last in the HTML code will be shown on top.
This is a function of the painting order
In-flow, non-positioned, block-level elements are painted in step 4
Floated items are painted at step 5. So the floated element is painted "on top" of the static div and you see it displayed.
But positioned descendants with 'z-index: auto' or 'z-index: 0' are painted in step 8. So adding position:relative to the div means that it is now painted "on top" of the floated element, hiding it.

Why do absolute elements stack up on each other instead of stacking one after the other?

How can get both #row1 and #row2 in the following code to be visible, one after the other vertically, as if there wasn't any absolute/relative positioning involved (though without removing the positioning properties)? I.e. having the two .row <div> to appear as "normal" block elements.
body { position:relative; min-height: 2em; width: 100%; }
.container {position:absolute;}
.row {position:relative;}
.col1, .col2 {position: absolute;}
<body>
<div class="container">
<div id="row1" class="row">
<div class="col1">Hello</div>
<div class="col2">World</div>
</div>
<div id="row2" class="row">
<div class="col1">Salut</div>
<div class="col2">le monde</div>
</div>
</div>
</body>
(Sample also available as a fiddle.)
I need the elements to have the positioning provided in the CSS rules, for reasons excluded here.
The content is programmatically dynamic; I don't know the elements' heights beforehand, so a solution can't be based on specifying an absolute length (e.g. 'px') anywhere.
Well you have some weird wishes here so let me explain you what those positions really mean in CSS and how they work, using position: relative; is just like using static position, the difference is making an element position: relative;, you will be able to use top, right, bottom and left properties, though the element will move, but physically it will be in the document flow..
Coming to position: absolute;, when you make any element position: absolute;, it gets out of the document flow, hence, it has nothing to do with any other element, so in your example
you have .col1, .col2 {position: absolute;} which are positioned absolute and since both are out of the document flow, they will overlap... Because they are already nested under position: absolute; parent i.e .container and since no width is assigned, it will take the minimal width and hence, your elements overlap, if you cannot change your CSS(which according to me doesn't make any sense why you can't change) still if you want, than you can do is this..
Demo (Without removing any of your position property) And this is really dirty
For the s characters, it will be at the top as your container element is out of the flow, and hence, no height will be considered in the document flow, unless and until you wrap that s in some element, and bring it down with, margin padding or CSS Positioning.
CSS Positions Explained
As I commented, here are few examples of how CSS Positioning actually works, to start with, there are 4 values for position property i.e static which is the default one, relative, absolute and fixed, so starting with static, nothing to learn much here, elements just stackup one below the other unless they are floated or made display: inline-block. With static positioning, top, right, bottom and left won't work.
Demo
Coming to position: relative; I've already explained you in general, it's nothing but same as static, it stacks up on other element, it is in the document flow, but you can tweak the elements position using top, right, bottom and left, physically, the element stays in the flow, only position of the element is changed.
Demo 2
Now comes absolute which generally many fails to understand, when making an element absolute it gets out of the document flow, and hence it stays independent, it has nothing to do with other elements positioning unless it's overlapped by other position: absolute element which can be fixed using z-index to change the stack level. The main thing to remember here is to have a position: relative; container so that your absolute positioned element is relative to that relative positioned element, else your element will fly out in the wild.
It's worth noting that position: absolute; element when positioned absolute; inside an absolute positioned parent element, than it is relative to that element and not relative to the grand parent element which may be positioned relative
Demo 3 (Without position: relative; container)
Demo 4 (With position: relative; container)
Last is position fixed, this is same as absolute but it flows along when you scroll, it's out of the document flow, but it scrolls, also, position: fixed; element cannot be relative to any container element having any type of position, not even relative, position fixed element is always relative to the viewport, so designers use position: absolute; when they want to have a fixed position behavior but relative to parent and tweak the top property onScroll.
Demo 5
What you want, is not possible without modifying the CSS position property. However, what you can do without touching the existing CSS, is overriding it with a more specific selector
.row .col1, .row .col2 {
position: relative;
}
See JSFiddle
when position:relative is used, the page layout will occur normally before being offset by top, left values, however position:absolute will ignore the document flow. The relative ones will work with no changes but absolute must be changed
.col1, .col2 {display:inline-block;}
http://jsfiddle.net/C4bQN/
EDIT: Depending on your circumstances, maybe you can wrap your table in an absolute positioned div then use normal document flow within the table?
<div class="absolute-wrap">
<div class="row">
<div class="col"> </div>
</div>
</div>

I want to fully grasp the concept of a 'position: relative' containing div

Please bear with me... and excuse my (probably) incorrect terminology:
In the following code I don't grasp why you set the containing (parent) div to 'position:relative' in order for the divs inside to be positioned in relation to the parent div (using 'position:absolute). I thought in order for this to happen the children divs would be set 'relative' to the parent. Am I to understand that essentially the parent div is saying to the other divs inside "hey, you can all be positioned 'relative' to me now!" I sort of expected it to work the other way around.
E.g. I expected the text would have been positioned "relative" to the containing div. Can someone explain why it works the way it does here? Thanks.
<div id="backgroundImage">
<h2 class="titleBox">I AM A TITLE</h2>
<p class="textBox">I am a description box</p>
</div>
#backgroundImage {
position: relative;
height: 225px;
width: 300px;
background-image: url (#);
}
.titleBox {
position: absolute;
top: 15px;
left: 0;
}
.textBox {
position: absolute;
bottom: 10px;
left: 0;
}
The documentation explains this very well, but I'll summarize.
An element with position:relative is first laid out just like any static element ... shifted according to the top, bottom, left and right properties
The position: relative box can be adjusted relative to its parent (even if its parent is static).
For position: absolute,
the containing block is the nearest positioned ancestor. By “positioned” I mean an element whose position property is set to relative, absolute or fixed
That is, the top, bottom, etc. properties on a position: absolute element are relative to the nearest containing element of a position other than static (including relative).
That is to say that position: absolute elements can still be positioned relatively.
You position the child elements absolutely, i.e you are specifying x/y co-ordinates for them (using left and top properties).
By default these will be positioned absolutely to the document, but by setting a parent container as position:relative, they will be positioned relative to that div, in an absolute manner.
If you set your element as position 'absolute' it will be out of the DOM.So you can set where ever you want unless or until your absoluted element parent or parents of parent... does not having any position relative.why we use position relative actually is if u want to style the the element irrespectively with other elements inside container, u can set position relative to the parent(means container). If #backgroundImage does not have position relative , your child elements will go initial position of your screen but if u want some where in the middle of ur page u have to styled the "backgroundImage" element as position :relative .. then the child element wil fly inside your "backgroundImage" container.

How to put a static div on top of an absolute position div?

I am building a small web application.
I have two divs. One is absolute and the other is static.
I am trying to position my static div on top of my absolute one, so that it remains the top most item.
Very simple Code Sample:
http://jsbin.com/efuxe3/edit
How can this be done?
Edit:
I have been using z-index. It seems to have no effect.
z-index doesn't apply to static elements.
According to this page:
This property specifies the stack
level of a box whose position value is
one of absolute, fixed, or relative.
If you make your div relative instead, you can use z-index to determine the order.
position: relative positions the element relative to its default (static) position, so if you don't specify a top, bottom, left or right then there'll be no difference between static and relative other than that relative allows you to use z-index to move your element up the stack.
Edit: based on your code sample, here's a working demo.
Edit 2: based on Nathan D. Ryan's suggestion in the comments below, you could also apply a negative z-index to your absolutely-positioned div. This would move it behind everything else on the page that didn't have a lower z-index defined.
Rather than placing the statically positioned element over the absolutely positioned element, you can place the absolutely positioned element behind the statically positioned element. You can do this by setting the z-index of the absolutely positioned element to a negative value. However, as #Town mentioned, this will also place the absolutely positioned element behind everything else in the normal flow.
You can apply a negative z-index to the other elements placing them behind the static div. This can be applied directly to the other elements or you can use
*:not(connectedObjects){
z-index:-1000000000000000000000000000;
}
But this does not work in internet explorer
You could have a second absolutely positioned div to contain your statically positioned elements:
<div id="container">
<div class="underlay">
I want this to appear under my static items.
</div>
<div class="item_container">
<div class="item">blah</div>
<div class="item">yada</div>
<div class="item">foo</div>
<div class="item">bar</div>
</div>
</div>
And your css is
.underlay {
position: absolute;
z-index: 0;
}
.item_container {
position:absolute;
z-index:10;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.item {
position: static;
}
if by top you mean z-Index, you can set the style of that div with a higher z-index
div.divClassName {
z-Index:100;
}
edit:
you can change the z-index of your div, with absolute positioning to a negative, but then you will have to do so for every other element.
Unless you really have a really good reason to using positioning to static you can change it
to relative, and the z-index will have an effect.io have tried it in your code sample and it works fine;
Work with z-index attribute. The z-index of the object which should be at front must be higher than the other ones.