Absolute: Ignores flow completely.
Relative: Is within context of normal flow, but can be moved around too.
This displays a green box within a red box as expected.
<html>
<head>
<title>Lets see what occurs</title>
<style>
#box_1 {
position: absolute;
top: 100px;
left: 100px;
right: 0px;
bottom: 0px;
background:red;
}
#box_2 {
position: absolute;
top: 100px;
bottom: 100px;
left: 40px;
right: 0px;
background:green;
}
</style>
</head>
<body>
<div id="box_1"><div id="box_2"></div></div>
</body>
</html>
How come this fails to do the same?
<html>
<head>
<title>Lets see what occurs</title>
<style>
#box_1 {
position: absolute;
top: 100px;
left: 100px;
right: 0px;
bottom: 0px;
background:red;
}
#box_2 {
position: relative;
top: 100px;
bottom: 100px;
left: 40px;
right: 0px;
background:green;
}
</style>
</head>
<body>
<div id="box_1"><div id="box_2"></div></div>
</body>
</html>
Relative position:
Even if the content of the relatively positioned element is moved, the reserved space for the element is still preserved in the normal flow.
Absolute position:
With absolute positioning, an element can be placed anywhere on a page. The heading below is placed 100px from the left of the page and 150px from the top of the page.
absolute positioning is referenced to the parent/ancestor that has absolute or relative positioning. relative positioning is referenced to himself, that's it, to its supposed place in the page flow. So when you position an absolute div inside another absolute div, the left/top/etc. references are about the parent's borders; when you position the child div like relative, it takes reference about his own borders, in the place it was supposed to be.
Here you can read a good article about it: http://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/
The problem is not using relative positioning inside an absolutely positioned div, it's that you're setting values for every edge (top, right, bottom and left), and your elements have no defined widths. When you set values for every edge, it will attempt to position your element to each of those values which will produce unexpected results.
The following:
#box_1 {
position: absolute;
top: 100px;
bottom: 0;
left: 50px;
right: 0;
}
Should be more like:
#box_1 {
position: absolute;
top: 100px;
left: 50px;
}
Look at this fiddle to see the positioning working as expected when I remove two unnecessary position values and add width/height: http://jsfiddle.net/S4fvs/9/
Sometimes you want to take up the entire window, so setting top: 0, right: 0, bottom: 0 and left: 0 will cause a block level element to fill all available space. That's useful for creating a new context on top of your normal content, say for a modal that might get long and scroll without scrolling the page behind it.
Related
I had to place some text in the middle of its parent element . I have achieved it with the following code :
#div1 {
position: relative;
margin: 0;
padding: 0;
}
#div2 {
width: 100%;
position: relative;
height: 3.21em;
margin: 0;
background-color: red;
}
#p1 {
display: block;
right: 48%;
top: 3.21em;
position: absolute;
background-color: green;
margin: 0
}
<div id="div1">
<div id="div2">
</div>
<p id="p1">
Hello From Web
</p>
</div>
But my question is if I use position: relative for the paragraph , the same thing doesnt work i.e.,place the text in the middle doesnt work,
#p1 {
display: block;
right: 48%;
top:3. 21em;
position: relative;
background-color: green;
margin: 0;
}
I just wanted to know whats happening behind the scenes with relative positioning .
I am aware of the basic difference between the two from many tutorials which goes like this "
position absolute means something like use top right bottom left to position itself in relation the nearest ancestor which has position as either absolute or relative.
Position relative means position the element in relation to its immeditate parent."
Going by the above definition, the parent is div1 for p in both relative and absolute positioning cases .
Then what else is it that I am missing in my understanding that is giving me the different results?
I just wanted to know whats happening behind the scenes with relative positioning
The description highlighted "from many tutorial" is incorrect, especially for position relative.
According to the specification, relative position means:
Once a box has been laid out according to the normal flow or floated, it may be offset relative to this position. This is called relative positioning.
In short, relative position means "relative" to itself, not to its parent.
Then what else is it that I am missing in my understanding that is giving me the different results?
I think this question has already been answered from above explanation. If #p1 is defined as position: relative;, its right & top are all related to its origin place (when its position is not defined). That's why you will see a blank area above it (like margin-top, which is caused by top: 3.21em), and a left offset.
You could fix this by using the transform property. The problem is that the width of the element isn't calculated when using position absolute. Browsers place the outer left or outer right at 50% of the relative parent. In your example the #p1 selector outer right is placed at 48% percent, if you would change this to 50%, the right side will be placed exactly at 50% of the parent element.
To rectify the width of the element you could use this:
#p1 {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
#div1 {
position: relative;
margin: 0;
padding: 0;
}
#div2 {
width: 100%;
position: relative;
height: 3.21em;
margin: 0;
background-color: red;
}
#p1 {
display: block;
left: 50% ;
transform: translateX(-50%);
top: 3.21em;
position: absolute;
background-color: green;
margin: 0
}
<div id="div1">
<div id="div2">
</div>
<p id="p1">
Hello From Web
</p>
</div>
The translate property uses the element width to transfrom itself. Hope this helps.
I understand the principle of left: and right: positioning if you want to position an element inside it's parent and then add the appropriate values to position the element where necessary. I saw a site today where a lot of the elements had the left and right properties both set to 0.
Example:
div {
width: 200px;
height: 200px;
position: fixed;
top: 0;
left: 0;
right: 0;
}
This was the case on a number of fixed and relative positioned <div>s. Surely you can't fix a <div> so it's positioned both left and right to zero? Could someone explain if this is valid CSS, and if so, please explain what it achieves.
Many thanks,
Emily
Yes, this is valid CSS. Basically, code like this will center absolute divs. Just remember to also add this code: margin: auto;. Here's a working example:
div {
position: absolute;
margin: auto;
right: 0;
left: 0;
height: 100px;
width: 100px;
background: red;
}
<div></div>
I have a parent-child div relationship with the child intended as a horizontal scrollbar attached to the bottom edge of the parent.
The parent is a vertically growable/shrinkable container for rectangular strips that are added/deleted by the user interactively.
How do I force the scrollbar to adhere to the parent's bottom edge?
Here is my current css situation:
.parent-div {
position: absolute;
left: 0;
top:80px;
right: 0;
}
.horizontal-scrollbar-div {
position: absolute;
top: 0;
left: 0;
bottom:-50px;
height:50px;
width: 100%;
z-index: 500;
}
This is not working correctly. At runtime strips get added the scrollbar remains at the top edge of the parent (initially there are no horizontal strips so the parent has 0 height).
What are the css changes I need to make here?
Thanks,
Doug
Marc's answer is right, but in order for it to work you need to add "position: relative;" on the ".parent-div". Otherwise the ".horizontal-scrollbar-div" would position itself according to the body element instead of ".parent-div".
Here is how I would do it. You can change the height of parent and the scrollbar will always stay at bottom of the parent-div.
.parent-div {
position: relative;
height:200px;
background-color:#aaa;
}
.horizontal-scrollbar-div {
position: absolute;
bottom: 0;
height:50px;
width: 100%;
background-color:yellow;
}
<div class="parent-div">
<div class="horizontal-scrollbar-div"></div>
</div>
I would try the following:
.horizontal-scrollbar-div {
position: absolute;
left: 0;
bottom: 0;
height:50px;
width: 100%;
z-index: 500;
}
You want the bottom edge of .horizontal-scrollbar-div to be pinned to the bottom edge
of the parent container.
Note: You may not need the z-index property.
Also: You may need a minimum height to .parent-div.
Given an absolutely positioned element with a certain size and overflow:auto and a child element that is also absolutely positioned, anchored to the bottom left corner of the parent element and exceeding it in size, like this:
#container {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
overflow: auto;
}
#content {
position: absolute;
bottom: 0;
left: 0;
width: 50%;
height: 200%;
}
Why does no vertical scrollbar appear on the parent element?
When I change the positioning of the child element to top instead of bottom, the scrollbar appears. It seems like the scrollbar is only visible if the content overflows on the bottom edge of the parent element. Why is this the case?
Here is the link to a JSFiddle that demonstrates the issue: http://jsfiddle.net/qGsd3/14/
I was hoping for a more interesting answer, but it seems to be: "Because the spec says so."
EDIT: I just realized that isn't the right section... But luckily I found the correct one so the answer stands.
http://www.w3.org/TR/2007/WD-css3-box-20070809/#abs-non-replaced-width
At the bottom there are the rules that dictate when height is calculated and how and it states only when there is overflow on the bottom does it extend the height. There is more reading there about how this affects overflow, so just poke around.
Absolute elements don't take up any space, that's why. Absolute positioning isn't needed for your content, change it to static, I can't understand what you are trying to accomplish there...
In my experience, nesting an absolute position inside another absolute position has given me nothing but headaches. Also, for heights, percentages can be hit or miss depending on the browser. Take a look here to see what I did on the 'bad' class to display the overflow.
#container {
position: relative;
width: 100px;
height: 100px;
overflow: auto;
background: green;
text-align: right;
top: 100px;
}
.left {
left: 100px;
}
.right {
left: 300px;
}
#content {
position: absolute;
width: 50%;
height: 100px;
background: red;
}
.good {
top: 0;
left: 0;
}
.bad {
bottom: -20px;
left: 0;
}
http://jsfiddle.net/qGsd3/39/
I have an HTML div positioned at a certain point (position: absolute; top: ...; left: ...). How do I make the div span from that point over to the edge of the page, and scale as the window is resized? I.e. - the same behavior as for width: 100%, but with the top left corner of the div at a specific, arbitrary point.
If the element is absolutely positioned, you can assign it's top, left, bottom and right properties:
<html>
<head>
<style>
#foo{
position: absolute;
top: 10px;
left: 10px;
bottom: 0;
right: 0;
background-color: red;
border: 5px solid blue;
}
</style>
</head>
<body>
<div id="foo"></div>
</body>
</html>
if i understand the question correctly, this should work
div {
position: absolute;
left: 100px; << "left top corner of the div at a specific, arbitrary point."
top: 0;
bottom: 0;
right: 0;
background-color: #666;
}