css定位規則

之前寫前端總會發現自己css定位代碼得不到預期效果,有時候甚至要費上好幾個小時來解決一個小問題,但最后還是不清楚原理。于是決定要系統地學下定位。翻了四五天w3c的規范,發現定位規則實際上是非常復雜的,有些效果要觸發所需的充分條件都有十幾條,涉及n個概念,w3school教程里面的定位規則并不完全準確(那個網站部分內容讓我覺得寫的人并不精通定位規則)。同時也發現之前以為等價的幾個概念實際上是獨立的。以上兩點便是之前一直覺得定位規則詭異的原因。

但是,全面地把這些規則學通很難,也完全沒有必要。師兄們是靠經驗寫前端,久而久之自己會形成一套固定的定位寫法,簡單又可靠。因此,我只想嘗試整理出一套系統而又精的定位知識,并且把自己做定位的套路記錄下來。


元素生成框

首先應該明確幾個概念和它們的關系。這些概念包括:元素element(inline 或者 block),框 box(inline 或者 block),框模型box model,塊級框block-level box,內聯級框inline-level box, ?container box,包含塊containing block , 塊級格式化上下文 block formatting contexts,內聯格式化上下文 inline formatting contexts 。里面有很多概念長得很像,但是有些是完全不同的!而且它們各自有獨立的作用。我之前覺得定位規則詭異的主要原因就是簡單把父級box和containing box簡單看成是同一個概念。其實還有不少看似很像但是不一樣的概念,像block box ,inline box ,這里略。(注意核對英文單詞來確認是否為同一個概念)

下面來簡單理一下這些概念之間的關系。在這之前,應當先理解element在文檔樹中的父子關系和框模型box model,這里略。

首先,可以粗略地認為,html文檔中的 每一個元素element 會對應生成 一個在瀏覽器中真實可見的 框box,其模型為框模型box model。內聯元素inline element 生成內聯級框inline-level box,塊級元素block element 生成 塊級框block-level box。由于html文檔中的元素間具有家族關系,因此元素生成的框也有家族關系。框之間的家族關系表現在父框包含子框。

w3c關于這點的原文為:Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme.Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context.


元素的家族關系?

(圖片出自http://www.ddcat.net/blog/?p=216)


格式化上下文決定定位規則

那這些一個包著一個的框具體應該怎么定位呢?考慮定位不能離開三個概念:包含塊containing block?,?塊級格式化上下文 block formatting contexts,內聯格式化上下文 inline formatting contexts?。

Formatting contexts 是個不同于框的概念,準確來說是框產生formatting contexts。什么條件下框才會生成formatting context ,會生成哪種 formatting context,等下有講。

考慮一個框會怎么定位,就要先考慮它在哪個formatting context中 ?還有 ?它和哪些框存在于同一個formatting context中。對于block formatting context(BFC).假設A框是B,D框的父框,B框是C框的父框,A促發條件生成了一個BFC。那么,B,C,D都同在A產生的BFC里面。但若B又促發條件,產生了新的BFC,那么 B,D在A產生的BFC里面,而C只在B產生的BFC中。(這個問題最切身的影響是外邊距折疊和浮動,兩個框產生外邊距折疊有一個必要條件是,兩個框處于同一個BFC中。)而對于inline formatting context(IFC),一個IFC里面所有內聯級元素都處于該IFC中(不考慮嵌套)。而產生IFC的塊級框會存在于一個BFC中。塊級框只存在于BFC中,內聯級框只存在于IFC中。

以下是生成formatting context的促發條件:

Block formatting contexts:浮動框,絕對定位框,inline-block 的內聯級框 ,overflow屬性不為visible的框都會生成一個新的block formatting context。

W3C原文:Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

Inline formatting contexts:block-level box 和 inline-block 的inline-level box 也是 container box(還是要注意不要把這和其他相似的概念混淆),container box 若只含內聯級框,就生成inline formatting context,否則,只要含一個塊級框,就不會生成新的formatting context,并且自動生成無名塊級框把所有內聯元素包起來。

W3C原文:Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.

稍微總結一下:文檔樹中的每個element對應生成一個框。某些框促發條件生成formatting context。最后每個框都會在某個formatting context中。而生成規則使得BFC中全為塊級框,IFC中全為內聯級框。

有了formatting context,才能談定位規則,因為定位規則實際上是由formatting context決定的。BFC對BFC中的框有一套定位規則,IFC對IFC中的框有另一套定位規則。簡單來說,BFC中的每一個框各占一行(也就是我以前理解的塊級框要換行),IFC中會嘗試用一個行框盡可能多地把多個框包起來,放在一行里面顯示(也就是我以前理解的內聯級框會在同一行上顯示)。詳細:http://www.w3help.org/zh-cn/kb/010/


以包含塊為基準算出定位結果

好了,以上規則規定了哪些框會在同一個上下文(formatting context)中,這影響了元素定位效果。但是要明確規定框究竟在哪個位置,靠上下文這個無形無具體位置的概念是不夠的。

因此我們需要 包含塊containing block 這個有固定區域有固定位置的概念來作為框定位的基準。首先應該明確,包含塊不是框,更加不能簡單理解為父級框(上個學期因為這個問題好多時間都嘩嘩流掉5555555555)。準確來說,包含塊是網頁上的區域。每個框都有它的 包含塊containing block ,框的包含塊的區域和位置總是比該框早確定下來,然后該框就可以 以包含塊為基準,按照所在formatting context 對框規定的定位規則,明確得出框的位置了。

那框的包含塊是怎么確定的,為什么框的包含塊總是先與框確定下來?直接看下面兩個圖。(其實兩張圖講的是一個內容)



圖片來自http://www.w3help.org/zh-cn/kb/010/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,814評論 1 92
  • 先前在學習CSS float時,有同學提到了BFC這個詞,作為求知好問的好學生,哪里不懂查哪里,那么今天就來研究一...
    這名字真不對閱讀 6,577評論 3 19
  • 什么是BFC BFC全稱是Block Formatting Context,即塊格式化上下文。它是CSS2.1規范...
    陌客百里閱讀 536評論 3 4
  • 轉載自(http://web.jobbole.com/83274/) BFC BFC全稱是Block Format...
    居客俠閱讀 2,162評論 0 20
  • 1.解決margin疊加問題 三P每個p之間的距離為50px,發生了外邊距疊加。 要解決這個疊加問題即讓每個P之間...
    歲月幫兇ds閱讀 516評論 1 0