Why Does an Absolute Position Element Wrap Based on Its Parent's Right Bound

Why does an absolute position element wrap based on its parent's right bound?

Doesn't position: absolute remove an element from the flow?

This has nothing to do with the flow. The width of an element always respects its containing block. If the element is absolutely positioned, then its dimensions can be constrained by top, right, bottom and left, but as long as its width is auto then it must still be constrained to the width of its containing block (making it no different from in-flow block boxes in that respect), which in your case is its absolutely-positioned parent. There isn't really any other element whose constraints the absolutely-positioned element could size itself with respect to without compromising the flow of its text.

For the specifics of how this width is calculated, refer to the spec.

css - parent's position is absolute and child's position is relative and vice versa

Read more about absolute, relative, and fixed position and how they differ here, but I'll try to answer your question about relationships specifically.

position: absolute will position that element to its nearest parent with a position other than static. Static is the default for everything.

position: relative is a little weird because it really affects that element's children, not its own position. It's just saying to its child elements, "position yourself relative to me if you have position: absolute." A position of fixed or absolute does the same thing (meaning its positioned children will position themselves relative to its boundaries), but these styles also affect their own position on the page. An element with position: relative won't look any different, but its children might.

So consider a situation like this:

<div class="parent">
<div class="child">
<div class="grandchild"></div>
</div>
</div>

If grandchild has position: absolute, it will position itself relative to the browser window because there is no parent with a position other than the default of static.

If parent also has position of relative, absolute, or fixed, grandchild will position itself relative to the boundaries of parent.

However, if child also has a position of relative, absolute, or fixed, the grandchild will position itself relative to child's boundaries, because it is the nearest parent with a position other than static.

In summary, relative affects an element's children, while absolute and fixed affect the element itself as well as its children.

And remember that position: fixed bypasses all relative and absolute parents and always positions itself relative to the browser window.

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.

CSS position absolute and full width problem

You could set both left and right property to 0. This will make the div stretch to the document width, but requires that no parent element is positioned (which is not the case, seeing as #header is position: relative;)

#site_nav_global_primary {    
position: absolute;
top: 0;
left: 0;
right: 0;
}

Demo at: http://jsfiddle.net/xWnq2/, where I removed position:relative; from #header

Absolute positioned element inside relative positioned element gets clipped

EDIT:
I've edited the snippet to show a way to wrap the text in the td element in case this is what you were trying to accomplish.


If you can't edit the HTML of the child div directly, you can change its attributes with JavaScript. The style attribute's left property having a value of -100px is what's causing your pain.

If you negate the default style attribute entirely, your CSS will be allowed to take over the styling, and the div will be at your mercy.

Try something like:

const childDiv = document.getElementsByClassName("child")[0];childDiv.style = "";
.parent {  position: relative;  border: 2px solid black;  width: 300px;  height: 300px;  overflow: visible;}
.child { position: absolute; border: 2px solid black; overflow: visible; top: 100px;}
.child td{ width: 100px; white-space: normal;}
<div style="width:300px;height:300px;border:2px solid black;">  <div class="parent" style="position:relative;left:200px;width:300px;height:300px;border:2px solid black;overflow:hidden;">    Relative Parent    <div class="child" style="position:absolute;left:-100px;border:2px solid black;">      <table>        <tbody>          <tr>            <td>              Absolute positioned div element            </td>          </tr>        </tbody>      </table>    </div>  </div></div>

Absolute positioning ignoring padding of parent

First, let's see why this is happening.

The reason is that, surprisingly, when a box has position: absolute its containing box is the parent's padding box (that is, the box around its padding). This is surprising because usually (that is, when using static or relative positioning) the containing box is the parent's content box.

Here is the relevant part of the CSS specification:

In the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element.... Otherwise, the containing block is formed by the padding edge of the ancestor.

The simplest approach—as suggested in Winter's answer—is to use padding: inherit on the absolutely positioned div. It only works, though, if you don't want the absolutely positioned div to have any additional padding of its own. I think the most general-purpose solutions (in that both elements can have their own independent padding) are:

  1. Add an extra relatively positioned div (with no padding) around the absolutely positioned div. That new div will respect the padding of its parent, and the absolutely positioned div will then fill it.

    The downside, of course, is that you're messing with the HTML simply for presentational purposes.

  2. Repeat the padding (or add to it) on the absolutely positioned element.

    The downside here is that you have to repeat the values in your CSS, which is brittle if you're writing the CSS directly. However, if you're using a pre-processing tool like SASS or LESS you can avoid that problem by using a variable. This is the method I personally use.

Can position:absolute elements somehow poke out of overflow:hidden containers?

No, you would have to set the height / width to the contents instead of the .wrap element itself. A solution would be an inner div next to .thing.

Why would margin not be contained by parent element?

This is how CSS works according to W3C:

In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding, or border areas, or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.

More specific to your case of the top div:

If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it. In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.

  • If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as the parent's.
  • Otherwise, either the element's parent is not taking part in the margin collapsing, or only the parent's bottom margin is involved. The position of the element's top border edge is the same as it would have been if the element had a non-zero bottom border.

The best thing I can do is point you to on "Collapsing Margins" on sitepoint (by Tommy Olsson and Paul O’Brien). They do a very detailed explanation with examples showing you exactly the behaviors you demoed in the question example code.

position absolute within position relative not working correctly

Position absolute means : absolute coordinates to its parent, without consideration of wrapping, going off the black background or whatever. As absolute positioning pulls the elements out of the HTML flow : your black box behaves like it has no content.

In your case, the to big inputs are 20px to the bottom of the black box, that's what you told it to do.

You have to stylise the black box (make it bigger, fill with some content), and you will see the two inputs staying 20px to the bottom.



Related Topics



Leave a reply



Submit