CSS進階09-定位體系差異分析

weixin_33890499發表於2018-03-02

(注1:如果有問題歡迎留言探討,一起學習!轉載請註明出處,喜歡可以點個贊哦!)
(注2:更多內容請檢視我的目錄。)

1. display,position,float 之間的關係

這三個屬性均會影響盒的生成及佈局,它們的互動如下:

  1. 如果 display 值為 none ,那麼 position 和 float 不生效。這種情況下,元素不生成盒。

  2. 否則,如果 position 值為 absolute 或 fixed ,盒為絕對定位absolutely positioned, float 的計算值為 none , display 的設定如下表。盒的位置由 top 、 right 、 bottom 和 left 屬性以及盒的包含塊決定。

  3. 否則,如果 float 值不為 none ,盒浮動並且 display 的設定如下表。

  4. 否則,如果元素為根元素, display 設定如下表,除了其在CSS2.2中未定義 list-item 的指定值是否變為計算值 block 或 list-item 。

  5. 否則, dislay 屬性值使用指定值。

4761597-5bc7e7d96ee93678.png

2. 標準流 normal flow,浮動 floats 和絕對定位 absolute positioning 的比較

為了說明標準流,相對定位,浮動和絕對定位之間的區別,我們提供了一系列基於以下HTML的示例:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Comparison of positioning schemes</TITLE>
  </HEAD>
  <BODY>
    <P>Beginning of body contents.
      <SPAN id="outer"> Start of outer contents.
      <SPAN id="inner"> Inner contents.</SPAN>
      End of outer contents.</SPAN>
      End of body contents.
    </P>
  </BODY>
</HTML>

該文件中假設有如下規則:

        body {
            display: block;
            font-size: 12px;
            line-height: 200%;
            width: 400px;
            height: 400px
        }

        p {
            display: block
        }

        span {
            display: inline
        }

在每個示例中,外部和內部元素生成的框的最終位置有所不同。在每個插圖中,插圖左邊的數字表示標準流位置中的雙倍行距(為了清晰)。
注:下述圖表僅供參考,並不按比例顯示。它們旨在突出CSS 2.2中各種定位方案之間的差異,而不是作為給定示例的參考渲染。

2.1 標準流 normal flow

考慮以下對outer和inner的CSS宣告,這些宣告不會改變盒的標準流:

#outer { color: red }
#inner { color: blue }

P元素包含所有行內內容: 匿名行內文字anonymous inline text
和兩個SPAN元素。因此,所有的內容將被放置在一個IFC中,處於由P元素建立的包含塊內,產生類似如下內容:

4761597-4795c9c85043b8ff.png

2.2 相對定位 relative positioning

為了檢視相對定位的效果,我們指定:

#outer { position: relative; top: -12px; color: red }
#inner { position: relative; top: 12px; color: blue }

文字正常流向outer元素。然後, outer的文字將流入其標準流內位置並在第一行末尾被分割。然後,包含文字(分佈於三行)的這些行盒會整體位移“-12px”(向上移動)。
作為outer子元素inner的內容,會在標準流中緊接"of outer contents"單詞(在1.5行)流入。然而,inner內容本身相對於outer內容偏移'12px'(向下),回到它們在第2行的原始位置。
請注意,跟在outer元素之後的內容不受outer相對定位的影響。


4761597-5cff87552bd39d86.png

另外要注意,outer偏移量若為'-24px',outer文字會和body文字產生重疊。
現在考慮通過如下規則將inner元素的文字浮動到右邊:

#outer { color: red }
#inner { float: right; width: 130px; color: blue }

inner盒脫離標準流向右浮動到right margins(盒的寬度已經顯示指定),文字正常流向inner盒。inner盒左側的行盒均被縮短,文件中剩餘的文字會流入它們。

4761597-eda2822afacf9975.png

為了展示'clear'屬性的效果,我們在示例中新增了一個兄弟元素:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>Comparison of positioning schemes II</TITLE>
  </HEAD>
  <BODY>
    <P>Beginning of body contents.
      <SPAN id=outer> Start of outer contents.
      <SPAN id=inner> Inner contents.</SPAN>
      <SPAN id=sibling> Sibling contents.</SPAN>
      End of outer contents.</SPAN>
      End of body contents.
    </P>
  </BODY>
</HTML>

帶有如下規則:

#inner { float: right; width: 130px; color: blue }
#sibling { color: red }

導致inner盒像之前一樣向右浮動,並且文件中的剩餘文字流入空出的空間:


4761597-e313174e08228e5a.png

但是,如果兄弟元素的clear屬性設定為'right'(即,生成的兄弟盒不會接受處於 其右側還緊鄰一個浮動盒 的位置),那麼兄弟內容會在float之下開始流動:

#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }
4761597-315242d0e721bc73.png

2.3 絕對定位 absolute positioning

最後,我們考慮絕對定位的影響。考慮以下用於outer和 inner的CSS宣告:

#outer { 
    position: absolute; 
    top: 200px; 
    left: 200px; 
    width: 200px; 
    color: red;
}
#inner { color: blue }

這會導致outer盒的top相對於其包含塊containing block定位。定位盒的包含塊由最近的定位祖先positioned ancestor(或者,如果不存在,使用初始包含塊,正如本例中所示)。outer盒的top side在其包含塊的top之下200px,left side在其包含塊的left之右200px。outer的子盒相對於其父級以標準方式流動。


4761597-3f29d9903ab2b61b.png

下面的示例顯示一個絕對定位盒是一個相對定位盒的孩子。儘管父親outer盒實際上並沒有偏移,但將其“position”屬性設定為“relative”表示該盒可以用作定位後代的包含塊。由於outer盒是一個行內盒,被分割到多行,第一個行內盒的top edge 和 left edge(由下圖中的粗虛線表示)作為“top”和“left”偏移的參考。

#outer { 
  position: relative; 
  color: red 
}
#inner { 
  position: absolute; 
  top: 200px; left: -100px; 
  height: 130px; width: 130px; 
  color: blue;
}

結果如下所示:


4761597-3ebaa8c58056e075.png

如果不對outer盒進行定位:

#outer { color: red }
#inner {
  position: absolute; 
  top: 200px; left: -100px; 
  height: 130px; width: 130px; 
  color: blue;
}

inner的包含塊將是初始包含塊initial containing block(見示例)。下圖顯示了此種情況下inner盒的位置。

4761597-37df55337e788d7d.png

如下例所示,可以使用相對定位和絕對定位來實現更改條。

<P style="position: relative; margin-right: 10px; left: 10px;">
I used two red hyphens to serve as a change bar. They
will "float" to the left of the line containing THIS
<SPAN style="position: absolute; top: auto; left: -1em; color: red;">--</SPAN>
word.</P>

可能會有如下結果:


4761597-72bede95507ce15b.png

首先,該段落(其包含塊邊在圖中顯示)正常流動。然後它從包含塊的left margin向右偏移了'10px'(因此,為該偏移量預留了'10px'的margin)。作為變化條的兩個連字元脫離標準流並位於當前行(由於'top:auto'),從其包含塊(由P在其最終位置建立)的左邊緣開始右移'-1em'。結果是變化條似乎“浮動”到當前行的左側。

參考

https://www.w3.org/TR/CSS22/visuren.html#visual-model-intro
https://www.w3.org/TR/CSS2/visuren.html
CSS規範 > 9 視覺格式化模型 Visual Formatting Model

相關文章