CSS relative vs absolute position - html

I'm trying to understand the difference between relative and absolute positions in CSS. I've read the explanations and definitions of both absolute and relative, yet I still find a particular example rather strange. Can someone explain why in the following example :
Here's the HTML file :
body {
display: block;
}
.d1 {
margin-top: 100px;
position: relative;
width: 100px;
height: 100px;
background: #815BFF;
}
.d2 {
position: absolute;
margin-left: 100px;
width: 100px;
height: 100px;
background: #815BFF;
}
.d3 {
position: absolute;
margin-top: 100px;
margin-left: 200px;
width: 100px;
height: 100px;
background: #815BFF;
}
<body>
<div class="d1">div 1</div>
<div class="d2">div 2</div>
<div class="d3">div 3</div>
</body>
I've posted the example on http://codepen.io/l7uci/pen/JWNrRj.
If I change the position of any div from absolute to relative, why does the div itself not change, but all the divs that come after it take it as a reference and change according to it ? I was expecting the other divs to still be placed relative to the body, as in Difference between relative and absolute .

If you use position:absolute but don't set top, left, bottom or right, the element takes the position it would have had in normal flow, even though it is not itself in normal flow, so doesn't affect the position of subsequent elements.
So if you change an element without top, left, bottom or right from absolute to relative it doesn't move, this is it still takes it's place in normal flow, but it is now in normal flow, so subsequent elements will move to take account of its size.

-An element with position: relative; is positioned relative to its normal position.
Setting the top, right, bottom, and left properties of a relatively-positioned element will cause it to be adjusted away from its normal position. Other content will not be adjusted to fit into any gap left by the element.
-An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed).
However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.

Related

Fixed element positioning relative to its parent

I have an element that gets position: fixed while dragging. This element is inside a modal that is a direct child of the body element.
On the image below, the modal is gray, the rest of the body is black, and the button is blue. When I add the following styles to the button:
position: fixed;
top: xxxpx;
left: -100px;
It positions the button relative to the modal, not the viewport. Is that even possible that an element with position: fixed be positioned relative to something but the viewport? It acts like an absolutely positioned element instead.
'normally' position fixed fixes relative to the viewport.
But there are exceptions. See MDN
The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none (see the CSS Transforms Spec), in which case that ancestor behaves as the containing block. (Note that there are browser inconsistencies with perspective and filter contributing to containing block formation.) Its final position is determined by the values of top, right, bottom, and left.
Here's a simple example:
body {}
.parent {
position: relative;
margin: 100px;
transform: scale(1);
width: 50vw;
height: 10vw;
background: black;
rfilter: blur(1);
}
.child {
position: fixed;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
background-color: blue;
}
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
Notice that the blue child element is placed at the top left of its parent. Its parent has a transform - and as it's scale(1) we might assume it doesn't do much. But it does create the parent as the containing block.
I think your problem is the transform on the parent.

setting html to position relative

I am curious how works position: relative in html tag. Can anyone explain? Is it positioned relative to document object or something like this?
<footer class="footer">
<div class="container">
<p class="text-muted">Place sticky footer content here.</p>
</div>
</footer>
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
This keyword lays out all elements as though the element were not positioned, and then adjust the element's position, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned).
An element with position: relative; is positioned relative to its normal position.
Setting the top, right, bottom, and left properties of a relatively-positioned element will cause it to be adjusted away from its normal position. Other content will not be adjusted to fit into any gap left by the element.
Source: https://www.w3schools.com/css/css_positioning.asp
Actually it won't make any sense if you use position relative with html tag.
position: relative;
positions the child with respect to its parent or to its neighboring elements.
You can try position: relative with body to position the body relative to the parent html.
Let me know if you require any further help

Making a relative div fixed to the top of the screen

I need to make #outer1 to be fixed at the top of screen, but I cannot do it without messing up the current positions. I cannot just make #outer1 fixed, as I need it to be relative, because the divs on the insides need to be absolute positioned. What should I do instead to make #outer1 to be fixed at the top of the screen?
div {
border: 1px solid black;
}
#outer1 {
height: 100px;
position: relative;
}
#outer2 {
height: 900px;
}
#left {
display: inline-block;
}
#right {
display: inline-block;
position: absolute;
right: 0;
}
<div id='outer1'>
<div id='left'>Left</div>
<div id='right'>Right</div>
</div>
<div id='outer2'></div>
I cannot just make #outer fixed, as I need it to be relative, because the divs on the insides need to be absolute positioned.
Simply because the most common arrangement for absolutely positioned children involves a relatively positioned parent, doesn't mean that's the only way.
The rule for absolutely positioned elements is that their containing block is the nearest positioned ancestor. #outer1 with position fixed is a positioned ancestor, so it qualifies. It's just that 99% of the time people use position: relative since that has minimal impact on the parent.
There's no problem using position: fixed as a containing block for absolutely positioned children.
From MDN:
A positioned element is an element whose computed position
property is either relative, absolute, fixed or sticky. (In other words, anything other than static)
A relatively positioned element is an element whose computed
position property is relative.
An absolutely positioned element is an element whose computed
position property is absolute or fixed.
A stickily positioned element is an element whose computed
position property is sticky.
The top, right, bottom, and left properties specify the
position of positioned elements.
The absolutely positioned element is positioned relative to nearest
positioned ancestor (non static). If a positioned ancestor doesn't
exist, the initial container is used.
source:
https://developer.mozilla.org/en-US/docs/Web/CSS/position
You can still have absolutely positioned child elements in a div with fixed position, it doesn't have to be specifically relative, it just can't be static, the default value for position
body {
margin: 0;
padding: 0;
}
div {
border: 1px solid black;
}
#outer1 {
height: 100px;
position: fixed;
width: 100%;
}
#outer2 {
height: 900px;
}
#left {
display: inline-block;
}
#right {
display: inline-block;
position: absolute;
right: 0;
}
<div id='outer1'>
<div id='left'>Left</div>
<div id='right'>Right</div>
</div>
<div id='outer2'></div>

How to set a div's position inside another div to bottom right corner?

In this example:
html
<div style="width:50%;overflow:hidden">
<div id="inboxHeader">
<div id="inboxCount"><p>Earth</p></div>
</div>
</div>
css
#inboxHeader{
background-color:yellow;
height :300px;
position: relative;
}
#inboxCount{
position: absolute;
bottom: 0;
float:right;
}
Earth is in the bottom left corner. So how can I shift it to the bottom right corner?
Set right:0 instead of float:right
http://jsfiddle.net/8np2f/4/
As it's an absolutely positioned element change float:right; for right: 0px;
If it was positioned relatively then you would need to float it to the right however absolute positioning removes the element from the flow of the DOM.
One caveat however, make sure the parent element has it's position set either to relative or absolute as required, or the child element could position itself against the highest in the DOM tree that has a position set.
float-ing has no effect on absolute-ly positioned elements. Set the right attribute instead.
So, change this:
#inboxCount{
position: absolute;
bottom: 0;
float:right;
}
To this:
#inboxCount{
position: absolute;
bottom: 0px;
right: 0px;
}
HTML
<div style="width:50%;overflow:hidden">
<div id="inboxHeader">
<div id="inboxCount">
<p>Earth</p>
</div>
</div>
</div>
CSS
#inboxHeader {
background-color:yellow;
height :300px;
position: relative;
}
#inboxCount {
position: absolute;
bottom: 0;
right: 0; /* No need for float:right with absolute positioning */
}
I've update your Demo
You must add the rule right: 0 in the id inboxCount.
Here's an example: http://zip.net/brmZth
Hope this helps
Just posting a descriptive answer so it might help someone.
position property can be used to tackle this problem
<div id="outer" style="width: 400px; height: 400px; border: 1px solid red; position: relative">
<div id="inner" style="width: 200px; height: 200px; border: 2px solid yellow; right:0;bottom:0;position:absolute;">
</div>
jsfiddle to check a DEMO
If we set relative positioning on 'outer' div, any elements within 'outer' div will be positioned relative to 'outer' div. Then if we set absolute positioning on 'inner' div, we can move it to the bottom right of 'outer' div using 'right' and 'bottom' properties.
Relative :
If you specify position:relative, then you can use top or bottom, and left or right to move the element relative to where it would normally occur in the document.
What it really means is "relative to itself". If you set position: relative; on an element but no other positioning attributes (top, left, bottom or right), it will no effect on it's positioning at all, it will be exactly as it would be if you left it as position: static; But if you DO give it some other positioning attribute, say, top: 10px;, it will shift it's position 10 pixels DOWN from where it would NORMALLY be.
Absolute : When you specify position:absolute, the element is removed from the document and placed exactly where you tell it to go. And a type of positioning that allows you to literally place any page element exactly where you want it.
Any element that is a child of the relatively positioned element can be absolutely positioned within that block.
References :
http://www.barelyfitz.com/screencast/html-training/css/positioning/
https://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/

How do I absolutely position a relatively positioned element?

Let's say I have a container, and that I want to put this one container into yet another container that's also full of other stuff. The CSS code might look something like this:
.parent-container {
width: 100%;
position: relative;
}
.child-container {
width: 600px;
position: absolute;
left: 25px;
bottom: 100px;
}
However, .child-container also includes absolutely positioned elements, which are position relatively to .parent-container because .child-container doesn't have position: relative. So my question is, how can I position .child-container's children relatively to itself, while still keeping it correctly positioned in .parent-container?
P. S. Wrapping .child-container in a position: absolute'd div and making .child-container position: relative should do the trick, but I was hoping for something more... semantic.
However, .child-container also includes absolutely positioned elements, which are position relatively to .parent-container because .child-container doesn't have position: relative.
Incorrect. Absolute positioning is with respect to the nearest ancestor that is positioned, not position: relative. Anything except position: static will make an element positioned. (position: relative won't move the container out of normal flow so it is used when you want to set a positioning context with no side effects).
Since the parent is position: absolute; they are positioned with respect to that already.
You don't need to change .child-container position to relative in order to set him has "relative" parent.
please review this link from MDN about position absolute.
"The absolutely positioned element is positioned relative to nearest positioned ancestor. If a positioned ancestor doesn't exist, the initial container is used."
*positioned ancestor is an element with either: relative, fixed or absolute position
Absolutely positioned elements should already be relative to their parent. Here's a demo which shows nested items within absolute positioning
HTML
<div class='parent-container'>
Parent
<div class='child-container'>
1st Child
<div class='grandchild-container'>
2nd Child
</div>
</div>
</div>
CSS (color added to illustrate differences)
.parent-container {
position: relative;
background: grey;
}
.child-container {
position: absolute;
background: red;
left: 20px;
}
.grandchild-container {
position: absolute;
background: yellow;
left: 20px;
}
jsFiddle
It will look like this
*Notice each position is relative to its parent.
For more info see:
Positioning - w3schools
Position - Mozilla Developer Network