CSS 定位與文件流

於明昊發表於2015-05-16

最近在工作中偶爾接觸到 CSS 佈局的問題,想著自己 CSS 實在太水,因此對這些問題總結一下,統一加深一下印象,以備不虞。

兩個問題

拖動元件的定位方式

之前在研究 avalon 拖動元件的時候,總是弄不清拖動的實現原理。後來發現是使用 relative 來進行定位。後來發現這個定位方式確實符合拖動的需求,它的主要效果是使元素偏離正常的位置,其他元素不會調整位置來彌補其偏離後留下來的空隙。其與 absolute 不同,其偏離對於父元素的定位方式沒有要求,且始終佔位,不脫離文件流。

脫離文件流

在幫人看專案的時候遇到了脫離文件流的情況,一時手足無措,只會去查詢 float,後來發現是由於定位是 position: absolute 引起的。也就是說,絕對定位是脫離文件流的。

繼續探討

文件流與脫離

發現 position: absolute 居然也可以脫離文件流之後,我不僅陷入了沉思:我居然這麼SB連這個都不知道什麼是文件流?還有什麼其他情況會導致脫離文件流呢?

文件流

所謂的文件流實際上是一種民間說法,正常稱謂應該指的是常規流(normal flow),個人感覺這兩者應該是“閥值”與“閾值”的關係。從直觀上理解正常流指的是元素按照其在 HTML 中的位置順序決定排布的過程,主要的形式是自上而下,一行接一行,每一行從左至右。

後來翻閱了一下 CSS2.1 規範,算是徹底搞明白了這個問題。CSS2.1 中,定位方案(Positioning Schemes)一共分三種:

  • 常規流,也就是俗稱的文件流,又包含三種型別:塊級元素的塊級格式、行內元素的行內格式以及兩種元素的相對定位方式。
  • 浮動(Float)
  • 絕對定位(Absolute Positioning):包含 absulotefix 兩種

由此我們就知道,所謂的不脫離文件流就只有三種情況:塊級、行內和相對定位。由此上面遇到的第一個問題也就得以證實:相對定位是不脫離文件流的

脫離文件流

其實脫離文件流的問題也迎刃而解,就只有兩種情況:浮動絕對定位。而這兩者的表現實際上非常相似,區別僅在於寬度缺失(詳見這裡)。

層疊順序

由於使用了相對定位和絕對定位的元素都會產生寬度缺失,因此會造成層疊的情況。層疊順序基本按照後者覆蓋前者的順序。但是如果要改變順序的話,就需要使用 z-index 屬性。

需要注意的是:z-index 只有在 position 值為 relativeabsolutefixed 的元素上有效。而其比較的規則遵循“拼爹原則”,即先比較具有 z-index 屬性的父輩元素,父輩元素 z-index 大的子輩元素都大。

但更需要注意的是:並非使用了 absolute 來進行定位就一定要設定 z-index,大量的 z-index 會使專案無法維護。

absolute 的使用注意點

上文已經說明了一點,即儘量依託後來居上的方式來設定 z-index,不要造成其濫用;同時還有一點是使用 absolute 也不是必須設定 TRBL。一般的教程都會說:使用 absolute 後,使用 TRBL 可以將元素定位到最近的非 static 的元素之內對應的偏移位置,卻都沒有說如果不使用 TRBL 會怎樣。實際上如果不使用 TRBL,absolute 會立即原地脫離文件流,即立刻在原來的位置浮動並不佔用寬度,效果與下拉框十分相似。如果配合 margin 就可以將其定位到某一個元素的下方進行浮動,從而實現下拉框的效果。


參考文件

相關文章