CSS 中,為什麼絕對定位(absolute)的父級元素必須是相對定位(relative)?

搞清楚了,正確的應該是只要父級元素=設置了position值(absolute或者relative),那麼子元素的position都是以父級元素來定位的。


首先,我想告訴你的是,如果父級元素是絕對定位(absolute)或者沒有設置,裡面的絕對定位(absolute)自動以body定位。這句話是錯的。

正確的是:只要父級元素設了position並且不是static(默認既是static),那麼設定了absolute的子元素即以此為包含塊(最近的)。

絕對定位(Absolute positioning)元素定位的參照物是其包含塊,既相對於其包含塊進行定位,不一定是其父元素。

建議去詳細通讀一下定位體系和包含塊。


同意 @濤吳 提到的 CSS2.1 9.6節,但是其中 http://w3schools.com 的資料不能作為權威參考吧。

仔細查了一下,9.6 節中提到 「with respect to itscontaining block」 所以必然要看什麼叫做 「containing block」。

在 10.1 節 (http://www.w3.org/TR/CSS2/visudet.html#containing-block-details) 提到:

The position and size of an element"s box(es) are sometimes
calculated relative to a certain rectangle, called thecontaining
block
of the element.

在下面的詳細定義中,分情況說明了具有不同 position 屬性的元素如何確定 containing block,其中第 4 點是絕對定位元素的情況:

If the element has "position: absolute", the containing block is
established bythe nearest ancestor with a "position" of "absolute", "relative"
or "fixed"
, in the following way:

  1. 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. In CSS 2.1, if the inline
    element is split
    across multiple lines, the containing block is undefined.
  2. Otherwise, the containing block
    is formed by the padding edge of

    the ancestor.

If there is no such ancestor, the containing block is theinitial
containing block
.

從這裡可以看到,一個元素的 containing block 是由其最近的 position 為 absolute / relative / fixed 的祖先元素決定的。

如果沒有找到,則為 initial containing block。需要注意 initial containing block 並不是所謂的以 & 或是 & 定位的。試試設個 bottom: 0; 看看元素會不會跑到頁腳?

對這個 initial containing block 規範前文有描述:

The containing block in which the root element lives is a rectangle called the initial containing block. For continuous
media,it has the dimensions of the viewport and is anchored at the
canvas origin
; ...

這就是說,initial containing block 是以整個 canvas (渲染內容的空間, http://www.w3.org/TR/CSS2/intro.html#canvas) 的坐標原點(左上)為基準,以 viewport (也就是瀏覽器視窗內渲染 HTML 的空間)為大小的矩形。

所以平時說的 position:absolute 元素相對最近的 position 為 absolute / relative / fixed 的祖先元素,或在找不到時基於根元素定位,這後面一半是錯誤的。


CSS2 標準 9.6 節:

In the absolute positioning model, a box is explicitly offset with respect to its containing block. It is removed from the normal flow entirely (it has no impact on later siblings). An absolutely positioned box establishes a new containing block for normal flow children and absolutely (but not fixed) positioned descendants.

http://www.w3schools.com/css/css_positioning.asp:

An absolute position element is positioned relative to the first parent element that has a position other than static. If no such element is found, the containing block is &.

故此 absolute 元素的定位是上溯父級元素,找第一個不是 static 的元素,以其為 absolute 的基準。所以題目補充說明裡的說法是不準確的。實際上,

如果父級元素是絕對定位,則裡面的絕對定位自動以此父級元素定位;

如果父級元素全都沒有設置(static),則裡面的絕對定位以 body 定位。

驗證:

&

&&

&

顯示:

http://minus.com/ltH8O0GPovDU3


一圖勝千言,包含塊判定總流程圖如下:

圖片解釋及來源: w3help.org 的頁面


如果父級元素全都沒有設置(static),則裡面的絕對定位以 body 定位。

這個不準確。W3C的手冊是:若無非static祖先,以 初始包含塊 定位,在瀏覽器里,根元素的包含塊(HTML)為初始包含塊,只是一般情況下看上去像是body區域。


我不太喜歡用html的術語來描述css,描述出來的是不嚴謹的,反之用css的術語描述,就嚴謹多了。比如這個,用css來描述就是:絕對定位的盒子是相對於離它最近的一個已定位的盒子進行定位的。這其實是包含塊的知識點,標準描述如下:

If the element has "position: absolute", the containing block is established by the nearest ancestor with a "position" of "absolute", "relative" or "fixed", in the following way:

  1. 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. In CSS 2.1, if the inline element is split across multiple lines, the containing block is undefined.
  2. Otherwise, the containing block is formed by the padding edge of the ancestor.


如果absolute元素的top或bottom屬性未設定,即使父級元素及祖先都無position,也是相對最近的父級元素定位的


看了很多慕課網上的視頻都是說,絕對定位的上級都是相對定位,似乎成了一個固定模式了


css沒有規定絕對定位的東西必須有個相對定位的爹地吧。你誤解了..


若要定義某個元素absolute,首先找個參照祖先;所以這裡需要有一個祖先必須設置relative,如果沒有這個祖先元素,就會是initial containing block ,反正就是會影像後面的布局,能則么理解嗎 ?


感謝丁小倪的建議,給大家補充一下關於定位體系和包含塊的「較權威,中文」W3C文檔

KB009: CSS 定位體系概述

http://www.w3help.org/zh-cn/kb/008.html


推薦閱讀:

UI/UX與前端的分界,客戶(PM)與程序員的關係?
CSS 2.1 中為何規定行內塊元素的「overflow」為非「visible」時其基線是底部外邊界?
關於阿里巴巴的矢量圖標與傳統的雪碧圖有什麼優勢?
apache django 間交互的問題?

TAG:前端開發 | CSS | Web標準 |