Why is an element with position: fixed moving with a non-positioned sibling?
With position: fixed
, your header
element is removed from the document flow.
The first in-flow element is main
, which has margin-top: 90px
in your code.
The parent of this element is body
, which normally has a default margin: 8px
(see HTML default style sheet).
Due to CSS margin collapsing, the body
element's margin-top: 8px
is collapsed with the main
element's margin-top: 90px
.
As a result, both elements, now having the same margin, shift down 90px.
html { background-color: green; height: 100%; }
body { background-color: pink; height: 100%;}
header { position: fixed; border: 1px solid red;}
main { margin-top: 90px; background-color:yellow;}
<header>Project Header</header> <main class="container" id="layout-mainContent"> <div class="row" id="first-row">somecontent</div></main>
position fixed div in absolute positioned div works - but why?
An element with position: fixed
is indeed positioned relative to the viewport (or browser). However, because it is an absolutely positioned element, it is "positioned relative to the initial containing block established by the viewport".
This is laid out in the position
documentation:
An absolutely positioned element is an element whose computed
position
value isabsolute
orfixed
. Thetop
,right
,bottom
, andleft
properties specify offsets from the edges of the element's containing block. (The containing block is the ancestor relative to which the element is positioned.) If the element has margins, they are added to the offset.
That is to say, when you specify margin-top
and margin-left
, these values are relative to the parent. And because the element is positioned relative to the parent, the default top
and left
are inherited from the parent. In your example, the .fixed
element has a top
value of 100px
because it inherits the top
value of 100px
from .sidebar
(the parent). When you set top: 0
on .fixed
, you are overriding this value (going from top: 108px
to top: 0
):
Because of this, the element appears to be taken 'out of flow'. However, it is still always positioned relative to the viewport; it just had an initial offset (which it inherited from its parent).
Fixed position but relative to container
Short answer: no. (It is now possible with CSS transform. See the edit below)
Long answer: The problem with using "fixed" positioning is that it takes the element out of flow. thus it can't be re-positioned relative to its parent because it's as if it didn't have one. If, however, the container is of a fixed, known width, you can use something like:
#fixedContainer {
position: fixed;
width: 600px;
height: 200px;
left: 50%;
top: 0%;
margin-left: -300px; /*half the width*/
}
http://jsfiddle.net/HFjU6/1/
Edit (03/2015):
This is outdated information. It is now possible to center content of an dynamic size (horizontally and vertically) with the help of the magic of CSS3 transform. The same principle applies, but instead of using margin to offset your container, you can use translateX(-50%)
. This doesn't work with the above margin trick because you don't know how much to offset it unless the width is fixed and you can't use relative values (like 50%
) because it will be relative to the parent and not the element it's applied to. transform
behaves differently. Its values are relative to the element they are applied to. Thus, 50%
for transform
means half the width of the element, while 50%
for margin is half of the parent's width. This is an IE9+ solution
Using similar code to the above example, I recreated the same scenario using completely dynamic width and height:
.fixedContainer {
background-color:#ddd;
position: fixed;
padding: 2em;
left: 50%;
top: 0%;
transform: translateX(-50%);
}
If you want it to be centered, you can do that too:
.fixedContainer {
background-color:#ddd;
position: fixed;
padding: 2em;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
Demos:
jsFiddle: Centered horizontally only
jsFiddle: Centered both horizontally and vertically
Original credit goes to user aaronk6 for pointing it out to me in this answer
Topmost 'fixed' position div moving with non position div
Change the CSS of the your .bottom element to:
.bottom {
position:relative;
top:128px; #64+64
}
Why absolute positioned element looks at its sibling element?
position:absolute; looks for the nearest element with position:relative/absolute, and makes his position, based on that element.
In your case, as you have position:relative in the image, the "Irene" text will be placed at the top left corner of the image.
For "Irene" to be at the top left of the document, you either apply position:fixed, wich is based on the browser window, or remove all the position:absolute/relative that are above the "Irene" element.
Why is an absolutely positioned element placed by its sibling instead of at the top corner of the page?
I always thought that absolute positioned elements are out of the flow.
Yes, they are removed from normal flow.
I don't understand why absolute positioned element appeared after child_static div.
Just because absolute positioning removes elements from normal flow, it doesn't mean it does alter the position of the elements as well.
In other words, absolutely positioned elements would be at the same place as they are not positioned absolutely unless their top
, left
, ... offsets are set.
So what happens is that they would overlap next sibling elements, because they are not part of document flow anymore.
For instance have a look at the following example where the gold <div>
element is covered by absolute
ly positioned element.
.parent { position: relative;}
.child_static { height: 20px; background: blue;}
.child_absolute { position: absolute; height: 20px; width: 100%; background: green;}
.child_static ~ .child_static { background: gold;}
<div class='parent'> <div class='child_static'>Green</div> <div class='child_absolute'>Blue</div> <div class='child_static'>Gold</div></div>
Can I position an element fixed relative to parent?
Let me provide answers to both possible questions. Note that your existing title (and original post) ask a question different than what you seek in your edit and subsequent comment.
To position an element "fixed" relative to a parent element, you want position:absolute
on the child element, and any position mode other than the default or static on your parent element.
For example:
#parentDiv { position:relative; }
#childDiv { position:absolute; left:50px; top:20px; }
This will position childDiv
element 50 pixels left and 20 pixels down relative to parentDiv's position.
To position an element "fixed" relative to the window, you want position:fixed
, and can use top:
, left:
, right:
, and bottom:
to position as you see fit.
For example:
#yourDiv { position:fixed; bottom:40px; right:40px; }
This will position yourDiv
fixed relative to the web browser window, 40 pixels from the bottom edge and 40 pixels from the right edge.
Adding p to one div, is moving other div
It's because you're not positioning the element anywhere vertically, because you're not setting any of its top
or bottom
offsets, thus placing it where it would be positioned if it were part of the document flow. This means it will align itself with the first element in the document flow, according to its margin.
That first element in document flow happens to be <p>
.
The proper fix for your problem is setting top:0;
on the fixed
element. For a more detailed explanation please read the accepted answer of the question yours duplicates.
Other possible (improper, IMHO) "fixes" are adjusting the first element in document flow to start from the top of the document, by overriding the default margins of <p>
to 0
, or setting it's display property to inline-block
(or any other inline
type of display).
Related Topics
How to Embed a Google Drive Folder in a Website
Using Text-Align Center in Colgroup
Can a Span Be Closed Using <Span />
Chrome Rendering Issue. Fixed Position Anchor with Ul in Body
Disabling Safari Autofill on Usernames and Passwords
Is It Alright to Use Multiple H1 Tags on the Same Page, But Style Them Differently
What Is the Default Button Type
CSS Speech Bubble with Box Shadow
Html5 Phone Number Validation with Pattern
Fit Website Background Image to Screen Size
Make <Body> Fill Entire Screen
Get Rid of Space Underneath Inline-Block Image
How to Give a CSS Class Priority Over an Id
Bug with Firefox - Disabled Attribute of Input Not Resetting When Refreshing
Can Comments Appear Before the Doctype Declaration
How to Apply a Color to a Svg Text Element
Set Width of Dropdown Element in HTML Select Dropdown Options