1

I thought a general rule is that, whenever a div foo has position: relative, then if none of the parent and ancestor has any non-static position (so need to have one of relative, absolute, or fixed), then, the div foo now will be position relative to the overall document.

But in the following page:

http://jsfiddle.net/4RcEn/6/

<div id="box1"></div>
<div id="box2">
    <div id="box3">some text inside some text</div>
</div>

<style>
  #box1 { width: 300px; height: 100px; background: #ffd; margin-left: 60px }
  #box2 { width: 300px; height: 100px; background: #fa0; margin-left: 60px }
  #box3 { width: 100px; height: 80px; background: #af0; position: 
          absolute; left: 20px;  }
</style>

box3 actually behave like this: the left is 20px and is relative to the document, but top is auto (by default), and is in fact relative to the container div. Only when top is set to 0, 0px, or some other value, then it is relative to the document. What rule is governing this?

P.S. with the rules in the spec, I don't see a rule that says: if the top or left is not specified, then the behavior is such and such. So this is a de facto standard that if it is not specified, then if there is no "containing block (which is defined as non-static positioned block), then it won't be relative to the "initial block"?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • possible duplicate of [Position absolute but relative to parent](http://stackoverflow.com/questions/10487292/position-absolute-but-relative-to-parent) – Curtis Feb 27 '13 at 12:02
  • What rule is governing this? [Newton's First Law](http://en.wikipedia.org/wiki/Newton%27s_laws_of_motion#Newton.27s_first_law) – Madara's Ghost Feb 27 '13 at 12:05
  • Regarding your edit, I edited my own answer to reference this: http://www.w3.org/TR/CSS21/visuren.html#comp-abspos. Here the spec loosely mentions how if no positioned elements are nearby the element should be positioned relative to its container. I guess this only applies when value is `auto`, but I don't believe it mentions that it should only apply then. If a value is specified, as you've mentioned, it seems to position itself to the document instead. – James Donnelly Feb 27 '13 at 12:22

3 Answers3

4

It is positioned relatively to the document (that's the reason why top: 0 moves it all the way to the top), but if you don't set top to any value (i.e. you leave it as auto), the box has no reason to shift anywhere from its static position (where it would normally sit if you hadn't set position: absolute).

See also this answer and sections 9.3 and 10 of the spec. Section 10, in particular, contains all the rules that govern static positioning, and is quite a comprehensive if not overly technical read.

The exact rule that says an element should remain in the static position in such a scenario is in section 10.6.4. In your scenario, you don't set top or bottom, but you do set height, so the second rule among the six that are listed applies:

2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'

So an absolutely-positioned element needs to remain in its normal static vertical position if top is not given something other than auto — it's not supposed to move itself arbitrarily.

Also, the containing block of an absolutely-positioned element is always either its nearest positioned ancestor if there is one, or the initial containing block.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
0

From the notes on the top attribute in the CSS 2.1 specification:

This property specifies how far an absolutely positioned box's top margin edge is offset below the top edge of the box's containing block. For relatively positioned boxes, the offset is with respect to the top edges of the box itself (i.e., the box is given a position in the normal flow, then offset from that position according to these properties).

To me this implies that if no top is specified then the box is positioned to the top of its "natural" container (its parent). When top is specified it's then offset to the closest ancestor with relative or absolute positioning (which I assume html or body have by default).

It then goes on to say:

...which cause the top of the outer box to be positioned with respect to its containing block. The containing block for a positioned box is established by the nearest positioned ancestor (or, if none exists, the initial containing block, as in our example).

James Donnelly
  • 126,410
  • 34
  • 208
  • 218
  • The positioning scheme is much more complicated, but it basically boils down to "containing block" having a different definition from what it seems to imply - http://www.w3.org/TR/CSS21/visuren.html#containing-block – BoltClock Feb 27 '13 at 12:10
  • I've edited my post. It does go on to mention how it's positioned to the nearest positioned ancestor or, if none exist, the initial containing block. I suppose the `auto` value here complies with this rule by positioning to its container, but then when a value is specified it positions itself in relation the body itself - I imagine this varies across different browsers. – James Donnelly Feb 27 '13 at 12:17
  • The initial containing block is usually where the viewport is and can be compared to the viewport, but in general it is the container for the root element `html` (whereas `html` and `body` each generate their own boxes). Also, this should not vary across browsers as the spec has an entire section dedicated to box calculations that browsers are expected to follow (section 10). I've edited my answer as well. – BoltClock Feb 27 '13 at 12:40
0

It is work div3 is calculating from body not from div2. Because you not specific "top" position of div than div3 get "top" from div2 and make your top point same as top point of div2. When you add atributte "top: 0px;" to dov3 then you see where is div3 and from which element affected div3 position.

Severe Torture
  • 319
  • 5
  • 26