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.
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
Position absolute but relative to parent
#father {
position: relative;
}
#son1 {
position: absolute;
top: 0;
}
#son2 {
position: absolute;
bottom: 0;
}
This works because position: absolute
means something like "use top
, right
, bottom
, left
to position yourself in relation to the nearest ancestor who has position: absolute
or position: relative
."
So we make #father
have position: relative
, and the children have position: absolute
, then use top
and bottom
to position the children.
Fixed position relative to parent container
The problem here is with the -webkit-transform
.
Chrome cannot render
position:fixed
on elements under a transformation.
Read here
You can try removing the transform
from .absolute
div and set a margin-left
to the .fixed
div after calculating it's parents width. in your case it's 40px
.
Example:
.absolute{
height:60px;
width: 60px;
position: absolute;
top:0;
right:0;
background: #ccc;
/* -webkit-transform: translateZ(0); */
}
.fixed{
height:20px;
width: 20px;
background: red;
position: fixed;
margin-left: 40px;
}
JSFiddle DEMO
Element with position fixed is not sticking to parent element that has its position set to relative
position:fixed
is not relative to parent element, even if it has a position:relative
set. It's relative to the viewport. Here is what MDN says about it:
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
, orfilter
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 oftop
,right
,bottom
, andleft
.
You would wanna use position:absolute
instead if you want to position relative to parent element.
css fixed child element positions relative to parent element not to the viewport, why?
FWIW, when I ran into this, the problem turned out to be a parent div
with -webkit-transform: translate3d(0, 0, 0)
in its CSS. Apparently, this is a known source of potential mayhem in child elements with position: fixed
.
For what I was trying to do (turning fixed
on and off as a way of sticking a key nav element to the top of the page as it scrolled by), the solution was to append
it to the page body
element when it was time to hold it in place and sticking it back in its wrapper div
when it wasn't. No idea if any of this would have helped the OP, but if you're chasing this bug yourself, worth looking into.
Related Topics
How to Add Stylesheets to Jsdom
Does @Font-Face Work in Email Templates
Min/Max Width/Height with Multiple Values
Word-Wrap CSS Property Not Affecting a Table Cell
How to Change Inline Text Height, Not Just the Line-Height
CSS Multiple Class/Id Selectors
Applying Transition on Flexbox Justify-Content Property
Input Background Colour Destroys Styling
CSS Position Absolute with Respect to a Parent Element Acting as Relative
CSS Linear Gradient Transparency Misbehaving Only in Safari
CSS Selector: First Paragraph's First Letter Inside a Div
Can CSS3 Translatez() Be Used Instead of Z-Index
Progressive Jpg Background Image Trouble in Firefox