CSS規範 > 9 視覺格式化模型 Visual Formatting Model

視覺格式化模型 Visual Formatting Model

URL:http://www.w3.org/TR/CSS2/visuren.htmlcss

Translator: HaoyCn html

Date: 14th of Aug, 2015算法

本文並未所有翻譯,譯者在原文基礎上稍有添加圖示。如瞭解所有信息,請參看規範原版。我的水平有限,歡迎指正。app

9.1 視覺格式化模型介紹

本章和下章用於描述視覺格式化模型:用戶代理 User Agent 如何在視覺媒體 Visual Media 下處理文檔樹 Document Tree 框架

視覺格式化模型中,文檔樹中的每個元素根據盒模型 Box Model 產生零個或多個盒。這些盒的佈局由如下內容控制:ide

  1. 盒的尺寸和類型佈局

  2. 定位體系 Positioning Scheme (常規流,浮動和絕對定位)字體

  3. 文檔樹中元素之間的關係動畫

  4. 外部信息(如:視口大小,圖片的固有尺寸等)this

本章及下章定義的屬性適用於連續媒體和頁面媒體 Paged Media 。然而,外邊距屬性的意義在頁面媒體中有所不一樣(詳情見頁面模型)。

視覺格式化模型沒有指定格式化的全部方面(如,沒有指定字符間距算法)。本規範沒有覆蓋到的格式化問題上,符合規範的用戶代理也可能表現不一。

9.1.1 視口 The Viewport

在連續媒體 Continuous Media 上工做的用戶代理通常會向用戶提供一個視口(屏幕上的一個窗口或其它可視區域)來幫助用戶訪問文檔。用戶代理能夠在調整視口大小的同時改變文檔的佈局(見初始包含塊 Initial Containing Block )。

若是視口小於渲染文檔的畫布區域,用戶代理應提供一個滾動機制。每一個畫布最多有一個視口,但用戶代理能夠把文檔渲染到多個畫布上(即爲相同文檔提供不一樣視圖)。

9.1.2 包含塊 Containing Blocks

CSS2.1中,許多盒的定位和大小都根據一個名爲包含塊 Containing Block 的矩形盒的邊緣來計算。通常地,生成的盒會充當其後代盒的包含塊;咱們稱盒爲其後代「建立」了包含塊。說「盒的包含塊」便是說「盒所處的包含塊」,而不是盒所產生的包含塊。

每一個盒會被賦予一個相對於其包含塊的位置,但它不會被侷限在其包含塊內;它有可能溢出。

包含塊的尺寸如何計算的細節將在下章講述。

9.2 盒的生成 Controlling Box Generation

本節描述CSS2.1中可生成的盒類型。盒的類型會影響其在視覺格式化模型中的表現。下面描述的 display 屬性用來指定盒的類型。

9.2.1 塊級元素 Block-level Elements 和 塊盒 Block Boxes

塊級元素是源文檔中會被視覺格式化爲塊狀(例:段落)的元素。 display 屬性的如下值會讓一個元素成爲塊級元素: block list-item 以及 table

塊級盒 Block-level Boxes 是參與塊格式化上下文 Block Formatting Context 的盒。每一個塊級元素生成一個主要的塊級盒 Principal Block-level Box 來包含其後代盒和生成的內容,同時參與定位體系 Positioning Scheme 。某些塊級元素還會在主要盒以外產生額外的盒: list-item 元素。這些額外的盒會相對於主要盒來擺放。

除了(下章要講的)表格盒 Table Boxes ,和可替換元素( Replaced Elements ),一個塊級盒同時也是一個塊容器盒 Block Container Box ,一個塊容器盒要麼只包含塊級盒,要麼建立一個行內格式化上下文 Inline Formatting Context 並只包含行內級盒 Inline-level Boxes 。並不是全部的塊容器盒都是塊級盒:不可替換的行內塊 Bon-replaced Inline Blocks 和不可替換的表格單元格 Non-replaced Table Cells 也是塊容器但不是塊級盒。是塊級盒、同時也是塊容器的盒稱做塊盒 Block Boxes

這三個術語,「塊級盒」、「塊容器盒」、「塊盒」在乎義明確時可簡稱爲「塊」。

n8TjeCd.png

9.2.1.1 匿名塊盒

在一個以下文檔中:

<div>
   Some text
   <p>More text</p>
</div>

(假定 div p 都設置了 display: block ,) div 看起來彷佛同時包含了行內類型的內容和塊類型的內容。爲了使界定格式化簡單一些,咱們假定有一個匿名塊盒 Anonymous Block Box 圍繞在「Some text」周圍。

2VCvqi4.png

該例如圖所示,有三個盒,其中一個爲匿名盒。

換句話說:若是一個塊容器盒(如上例中爲 div 生成的盒)內有一個塊級盒(如上例中的 p ),那麼咱們強制它只包含塊級盒。

當一個行內盒 inline box 包含一個文檔流內 In-flow 的塊級盒,這個行內盒(及在同一行盒的 Line Box 它的行內祖先)會在該塊級盒(及其連續的或者中間只被可摺疊空白、脫離文檔流元素分隔的塊級同胞)的周圍打斷,把行內盒分離成兩個盒(甚至一邊爲空也如此),各在塊級盒一邊。在打斷以前和打斷以後的行盒 Line Box 都被匿名塊盒包含,而且該塊級盒成爲匿名塊盒的同胞。當這樣的行內盒受到相對定位影響,任何產生的移動一樣影響到包含在其中的塊級盒。

該模型將應用在下面的例子中。假設有規則以下:

p    { display: inline }
span { display: block }

被應用到以下HTML文檔:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Anonymous text interrupted by a block</title>
</head>
<body>
   <p>
      This is anonymous text before the SPAN。
      <span>This is the content of SPAN.</span>
      This is anonymous text after the SPAN。
   </p>
</body>
</html>

p 元素包含一段匿名文本 C1 ,接着是一個塊級元素,隨後又是另外一段匿名文本 C2 。結果生成了一個表明 body 的塊盒,它包含了圍繞 C1 一個匿名塊盒、 span 的塊盒,和圍繞 C2 的另外一個匿名塊盒。

匿名盒的繼承屬性會從包含它的非匿名盒那裏繼承(好比,在子節標題「匿名塊盒」下的那個例子中的 div 盒)。匿名盒的非繼承屬性將取其初始值。例如,匿名盒的字體屬性繼承自 div ,可是外邊距是 0

當一個元素致使了匿名塊盒的生成,則該元素上設置的屬性同樣能應用於該元素生成的盒和該元素的內容。例如,在上面例子中,若是在 p 元素上設置了邊框,則這個邊框將畫在 C1 (在行的結尾開)和 C2 (在行的結尾閉)周圍。

xpiKFXw.png

一些用戶代理用其它方式實現了行內包含塊 Inlines Containing Blocks 上的邊框。例如,將其內嵌的塊放入「匿名行盒」中,並在這些匿名行盒周圍繪出行內邊框。因爲CSS1和CSS2沒有定義這種表現,僅支持CSS1或CSS2的用戶代理纔會以其它形式來實現,並仍聲稱遵照這部分CSS2.1規範。對於CSS2.1規範發佈以後的用戶代理不會這麼作。

IE6下的效果:

Z63OR8A.png

計算百分比值時,應忽略匿名塊盒,而以最近的非匿名祖先盒來替代。例如,上面的 div 裏,若是一個匿名塊盒的子盒在須要知道其包含塊的高度來得到一個百分比高度。那麼它將使用 div 造成的包含塊的高度,而不是匿名塊盒的高度。

9.2.2 行內級元素 Inline-level Elements 和 行內盒 Inline Boxes

行內級元素是在源文檔中那些不爲其內容造成新的塊、其內容分佈在多行中的元素(如,段落內着重文本,行內圖片等等)。如下的 display 屬性值產生一個行內級元素: inline inline-table ,以及 inline-block 。行內級元素生成行內級盒 Inline-level Boxes ,而這些盒會參與行內格式化上下文 Inline Formatting Context

一個行內盒是行內級盒,且其內容參與了該行內盒的行內格式化上下文。一個 display 值是 inline 的不可替換元素會生成一個行內盒。那些不是行內盒的行內級盒(例如可替換的行內級元素 Replaced Inline-level Elements 、行內塊元素 inline-block 、行內表格元素 inline-table )被稱爲原子行內級盒 Atomic Inline-level Boxes ,由於它們以單一不透明盒的形式來參與它們的行內格式化上下文。

KVmfRh8.png

9.2.2.1 匿名行內盒 Anonymous Inline Boxes

任何被直接包含在一個塊容器元素(不是包含在行內元素)的文本必須做爲匿名行內元素來對待。

一個HTML文檔以下:

<p>Some <em>emphasized</em> text</p>

p 產生一個塊盒,其中包含了一些行內盒。 emphasized 的盒是一個由行內元素 em 生成的行內盒,但其餘盒( some text 的)是由塊級元素 p 生成的行內盒。後面這種盒被稱做匿名行內盒,由於它們沒有相關的行內級元素。

這些匿名行內盒的可繼承屬性將從它們的父級塊盒中繼承。非繼承性屬性取其初始值。在上面例子中,匿名行內盒的 color p 那裏繼承,但 background transparent

空白內容,根據 white-space 屬性,若是可被摺疊則不會產生任何匿名行內盒。

本規範中,若是可根據上下文來清晰界定一個匿名盒的類型,則匿名行內盒和匿名塊盒均可被簡稱爲匿名盒。

在格式化表格時,還會有更多類型的匿名盒出現。

9.2.3 Run-in Boxed 插入盒

爲使章節號同以前的草案一致,特保留此節。 display: run-in 現已定義至CSS3(參見CSS基本盒模型)。

9.2.4 display 屬性

(譯者注:本處暫只記錄常見幾個值的簡略介紹)

  1. block 元素產生一個塊盒。

  2. inline-block 元素產生一個行內級塊容器。行內塊的內部會被看成塊盒來格式化,而此元素自己會被看成原子行內級盒來格式化。

  3. inline 元素產生一個或多個的行內框。

  4. none 元素不出如今格式化結構中(也就是說,在視覺媒體中元素既不產生盒也不影響佈局)。其後代元素也不產生任何盒:該元素及其內容會被從格式化結構中徹底移除。對後代元素設定 display 屬性不能覆蓋這個表現。

請注意 none 值不產生可見盒;它根本就不生成盒。CSS中有使元素在格式化結構中產生盒並影響格式化,但盒自己不可見的機制。請訪問visibility的章節瞭解詳情。

除定位元素和浮動元素以及根元素外(見下文)計算值與指定值相同。根元素的計算值按下文所述改變。

注意,儘管 display 初始值是 inline ,但用戶代理的默認樣式表規則可能覆蓋該值。請見附錄中的HTML4參考樣式表。

9.3 定位體系 Positioning Schemes

在CSS2.1中,盒子根據如下三種體系來佈局:

  1. 常規流 Normal Flow 。CSS2.1中,常規流包括塊級盒的塊格式化,行內盒的行內格式化,以及塊級盒和行內級盒的相對定位。

  2. 浮動 Floats 。在浮動模型中,盒首先根據常規流佈局,而後從常規流中脫離並儘量地向左或向右位移。內容能夠佈局在浮動周圍。

  3. 絕對定位 Absolutr Positioning 。在絕對定位模型中,盒徹底從常規流中脫離(對後面的同胞元素無影響)並根據包含塊來分配位置。

浮動元素、絕對定位元素、根元素都被稱爲脫離文檔流 Out of Flow ;其餘元素被稱爲文檔流內 In-flow 。元素 A 的排版流由 A 、在文檔流內且最近的脫離文檔流的祖先是A的元素構成。

9.3.1 選擇定位體系: position 屬性

(譯者注:本節翻譯有省略)

  1. static:盒爲常規盒,根據常規流佈局, top right bottom left 屬性不生效。

  2. relative:盒的定位根據常規流計算(盒被成爲常規流內定位)。接着盒相對其常規位置移動。當B盒相對定位,B盒以後的盒定位時就當B沒有移動同樣來計算。 table-row-group table-header-group table-footer-group table-row table-column-group table-column table-cell 以及 table-caption 上次未定義此效果。

  3. absolute:盒的位置(還可能包括大小)由 top right bottom left 屬性指定。這些屬性根據盒的包含塊來規定移動。絕對定位盒脫離文檔流。這意味着它們對以後的同胞盒的佈局沒有影響。同時,即使絕對定位盒有外邊距,也不一樣其餘任何外邊距摺疊。

  4. fixed:盒的定位根據 absolute 模型來計算,但除此以外,盒相對某些參照物保持固定。和 absolute 模型同樣,此盒的外邊距也不一樣其餘任何外邊距摺疊。在手持 handheld 、投影 projection 、屏幕 screen 、打字機 tty 、電視 tv 媒體類型中,盒相對視口固定且滾動時不會移動。在打印媒體類型中,即使頁面是經過視口來訪問的(好比打印預覽),盒也渲染在全部頁,而且根據頁盒固定。其餘媒體類型中則未定義此表現。開發者可根據依賴媒體來指定 fixed 。好比說,若是想使盒固定在屏幕視口頂部,但不出如今打印頁的頂部,這兩種設定能夠經過使用@media規則來分開,以下:

@media screen { 
   h1#first { position: fixed } 
}
@media print { 
   h1#first { position: static }
}

用戶代理不可將固定盒的內容分頁顯示。注意用戶代理可能用其餘方法打印不可見內容。參見第13章「頁盒外的內容」。

用戶代理可將根元素上的 position 視爲 static

9.3.2 盒位移 Box Offsets: top right bottom left

(譯者注:本節暫略,可參考CSS手冊)

9.4 常規流 Normal Flow

常規流中的盒子都屬於某個格式化上下文,要麼塊格式化上下文,要麼行內格式化上下文,總之不能兩者得兼。塊級盒參與塊格式化上下文,行內級盒參與行內格式化上下文。

9.4.1 塊格式化上下文

浮動、絕對定位元素、非塊盒的塊容器(如:行內塊 inline-block 、表格單元格 table-cell 以及表格標題 table-caption )以及 overflow 屬性不爲 visible 的塊盒(除了該值被傳播到視口的狀況)將爲其內容建立一個新的塊級格式化上下文。

在塊格式化上下文中,盒從包含塊頂部一個接一個地垂直襬放。兩個同胞盒間的垂直距離取決於 margin 屬性。同一個塊格式化上下文中的相鄰塊級盒的垂直外邊距將摺疊。

在塊格式化上下文中,每一個盒的左外邊緣緊貼包含塊的左邊緣(從右到左的格式裏,則爲盒右外邊緣緊貼包含塊右邊緣),甚至有浮動也是如此(儘管盒裏的行盒可能因爲浮動而收縮),除非盒建立了一個新的塊格式化上下文(在這種狀況下盒子自己可能因爲浮動而變窄)。

關於在頁面媒體 Paged Media 中分頁的信息,請參考容許頁面分頁的章節。

9.4.2 行內格式化上下文

在行內格式化上下文中,盒從包含塊的頂部一個接一個地水平擺放。盒水平方向的外邊距、邊框和內邊距在佈局時都會考慮在內。盒的垂直對齊方式則不一:可能按底部或者頂部對齊,又或者按它們內容文本的基線對齊。包含了一行裏全部盒的矩形區域被稱爲行盒 Line Box

行盒的寬度取決於包含塊以及浮動。行盒的高度取決於在行盒高度計算章節所給出的規則。

行盒的高老是足以容納其包含的全部盒。然而,它可能高於其所包含的最高盒(好比,包含的盒以基線對齊)。當一個盒( B )的高度小於包含它的行盒的高度時, B 的垂直對齊方式由 vertical-align 屬性決定。當在水平方向上幾個行內級盒不能徹底被單個行盒包含時,它們會被分配到兩個或者多個垂直襬放的行盒中。所以,一個段落就是多個行盒的垂直堆疊。行盒的堆疊沒有垂直間距(除非有特別聲明)而且從不重疊。

通常來講,行盒的左邊緣緊貼其包含塊的左邊緣,其右邊緣緊貼包含塊的右邊緣。然而,浮動盒可能被置於包含塊和行盒邊緣之間。所以,儘管在同一行內格式化上下文中的行盒是等寬的(包含塊的寬度),因爲浮動會形成可用的水平空間減小,行盒的寬度仍可能變更。同一行內格式化上下文中的行盒在高度上一般是變更的(好比,一行可能包含圖片但其餘行僅包含文本)。

當一行中的行內級盒的總寬度小於包含它們的包含塊的時候,它們在行裏的水平分佈取決於 text-align 屬性。若是取 justify 值,用戶代理可能拉伸行內盒( inline-table inline-block 盒除外)中的空格和字間距。

當行內盒的寬度超過行盒寬度時,行內盒將被分爲多個盒,被分解出的盒則又分佈在多個行盒中。若是一個行內盒不可切割(好比,行內盒包含的是單個字符或者語言指定的斷字規則不容許斷字,又或者行內盒的 white-space 屬性值爲 nowrap pre ),那麼該行內盒將溢出行盒。

當行內盒被分割,外邊距、邊框和內邊距在任何斷點處都不會產生視覺影響。

行內盒也可能因爲雙向文本處理而在一個行盒內被切割成多個盒。

爲了包含行內格式化上下文中的行內級內容,行盒按需建立。有的行盒不包含文本、保留空白、外邊距或內邊距或邊框不爲零的行內元素、其餘文檔流內 In-flow 內容(如圖片、行內塊或行內表格),而且不以保留的換行符結尾,若是是爲決定它們所包含的元素的定位,則必須視其爲零高度的行盒,除此以外的其餘目的下應視其爲不存在。

下面是一個行內盒構造的例子。下屬的段落(由HTML塊級元素 p 建立)包含了有 em strong 交叉的匿名文本。

<p>Several <em>emphasized words</em> appear
<strong>in this</strong> sentence, dear.</p>

p 元素生成了一個塊盒來包含五個行內盒,其中三個行內盒是匿名的:

  • 匿名:"Several"

  • em:"emphasized words"

  • 匿名:"appear"

  • strong:"in this"

  • 匿名:"sentence, dear."

爲了格式化該段落,客戶端將五個行內盒放進行盒。在這個例子中,由 p 元素生成的盒建立了行盒的包含塊。若是該包含塊足夠寬,全部的行內盒將放置在單個行盒:

Several emphasized words appear in this sentence, dear.

若是寬度不夠,行內盒就會被分割並分佈在多個行盒。段落可能就變成了:

Several emphasized words appear

in this sentence, dear.

或者:

Several emphasized

words appear in this

sentence, dear.

在最後這個狀況裏, em 盒被分割成了兩個 em 盒(現稱之爲 split1 split2 )。外邊距、邊框、內邊距或者文本修飾在 split1 以前或者 split2 以後都沒有視覺效果。

看下面這個例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Example of inline flow on several lines</title>
<style type="text/css">
   EM {
      padding: 2px; 
      margin: 1em;
      border-width: medium;
      border-style: dashed;
      line-height: 2.4em;
   }
</style>
</head>
<body>
<p>Several <em>emphasized words</em> appear here.</p>
</body>
</html>

根據 p 的寬度,這些盒可能分佈以下:

NUuaQrm.png

  • 外邊距插在了 emphasized 以前和 words 以後

  • 內邊距被插在了 emphasized 以前、上、下, words 值後、上、下。虛線邊框渲染在了每一個單詞的三邊。

9.4.3 相對定位 Relative Positioning

一旦一個盒遵循常規流或者浮動而佈局好位置後,它有可能根據這個位置來相對位移。這被稱做相對定位。經過這種方式移動盒( B1 )對隨後的盒( B2 )沒有影響: B2 被賦予了一個如同 B1 沒有位移的位置,而且 B2 B1 移動後不會重定位。這意味着相對定位可能形成盒重疊。然而,若是相對定位形成一個 overflow:auto overflow:scroll 的盒溢出,客戶端必須經過建立滾動條來讓用戶能夠訪問到該內容(在其偏移位置),這可能影響佈局。

一個相對定位盒保持其常規流中的大小,包括斷行和本來爲其保留的空間。包含塊一節解釋了相對定位盒建立新的包含塊的狀況。

對於相對定位元素而言, left right 在不改變盒大小的同時使其水平位移。 left 使盒向右移動, right 時期向左。 left right 沒有形成盒的分割或拉伸,所以應用的值始終知足: left = - right

若是 left right 值均爲 auto (其默認值),應用的值爲 0 (便是說,盒保持在其原位)。

若是 left auto ,其應用值爲 right 的負值(即盒向左移動 right 值)。

若是 right auto ,其應用值爲 left 的負值。

若是 left right 均不爲 auto ,定位則被過分約束,其中一值必須被忽略。若是包含塊的 direction 屬性值爲 ltr ,則 left 值勝出而 right 值改成 - left 。若是包含塊的 direction 屬性值爲 rtl right 值勝出而 left 值被忽略。

舉例。下面三條樣式規則是等效的。

div.a8 {
   position: relative;
   direction: ltr;
   left: -1em;
   right: auto
}
div.a8 {
   position: relative;
   direction: ltr;
   left: auto;
   right: 1em
}
div.a8 {
   position: relative;
   direction: ltr;
   left: -1em;
   right: 5em
}

top bottom 屬性在不改變相對定位元素的大小的同時使其上下位移。 top 使其下移, bottom 則使其上移。 top bottom 沒有形成盒的分割或拉伸,所以應用的值始終知足: top = - bottom 。若是兩者均爲 auto ,其值則均爲 0 。若是其中一個值爲 auto ,則該屬性取另外一屬性的負值。若是兩者均不爲 auto bottom 將被忽略(也就是說, bottom 應用值爲 top 的負值)。

注:在腳本環境中動態移動相對定位盒能夠產生動畫效果(見 visibility 屬性)。儘管相對定位可被用於上標和下標效果,但行高在自動調整時不會將其定位歸入計算。參見行高計算一節的描述瞭解更多信息。

相對定位的例子將在對比常規流、浮動和相對定位一節中提供。

9.5 浮動 Floats

在當前行中一個盒被移動到左側或右側稱爲浮動。浮動最有趣的特色是內容能夠佈局在其旁邊(或者爲 clear 屬性所禁止)。內容會佈局在左浮動盒的右側,或佈局在右浮動盒的左側。下述內容是對浮動定位及內容佈局的介紹。控制浮動行爲的準則已經在 float 屬性一節中描述。

浮動盒將被移動至左側或右側直至其外側緊貼包含盒的邊緣或另一個浮動的外邊緣。若是存在行盒,浮動盒的頂部外邊緣將與行盒的頂部對齊。

若是水平方向沒有足夠的空間容納浮動,它將下移直至可以放下它或者沒有其餘浮動。

因爲浮動不在常規流中,在浮動以前或以後建立的非定位塊盒將垂直襬放,如同浮動不存在同樣。然而,當前行盒和隨浮動後建立的行盒會按需縮短來爲浮動的外邊距盒騰出空間。

當有一個垂直定位知足如下所有四個條件時,行盒將緊挨着浮動:

  1. 在行盒頂部或之下

  2. 在行盒底部或之上

  3. 在浮動的上外邊距邊緣之下,並

  4. 在浮動下外邊距邊緣之上

注:這意味着總高度 Outer Height 爲零或爲負的浮動不會縮短行盒。

若是行盒被縮短到不能容納任何內容,那麼行盒將下移(其寬度會從新計算)直到能夠容納內容或再也不有浮動。當前行中,任何在浮動盒以前的內容將移動到同一行中的浮動的另外一側從新佈局。換句話說,若是行內級盒先於左浮動被放在行盒中,而行盒的剩餘空間能夠容納左浮動,那麼左浮動會被置於該行內,且與行盒頂部對齊,而已經放入該行盒的行內級盒會被相應地移動到浮動的右側(右側便是左浮動的另外一側),反過來對 rtl 和右浮動也是這樣。

表格、塊級可替換元素或者在常規流中建立新的塊格式化上下文的元素(如 overflow 值非 visibile 的元素),它們的邊框盒不可與它們同屬一個塊格式化上下文中的浮動元素的外邊距盒重疊。若是有必要的話,應當經過把它們置於已出現的浮動的後面達到清除浮動的效果,但若是空間足夠,能夠將其放置在浮動旁邊。但這可能使得該元素的框盒變得比10.3.3章節定義的還要窄。CSS2沒有定義用戶代理什麼時候能夠把元素置於浮動旁的狀況,也沒有定義元素會變得多窄的狀況。

舉例。在下面的文檔片斷中,包含塊不足以容納浮動旁邊的內容,所以內容須要移動到浮動下面,並根據其 text-align 屬性來在行盒中定位。

p {
   width: 10em;
   border: solid aqua;
}
span {
   float: left;
   width: 5em;
   height: 5em;
   border: solid blue;
}

<p>
   <span> </span>
   Supercalifragilisticexpialidocious
</p>

該片斷可能以下圖所示:

VuMC2rw.png

浮動能夠並列,而這個模型也適用於同一行中的並列浮動元素。

下面的規則會使全部的 class="icon" img 盒浮動到左側(並設左外邊距爲 0 )。

img.icon { 
   float: left;
   margin-left: 0;
}

考慮以下HTML代碼和樣式表:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Float example</title>
<style type="text/css">
   img { float: left }
   body, p, img { margin: 2em }
</style>
</head>
<body>
   <p><img src=img.png alt="This image will illustrate floats">
   Some sample text that has no other...
</body>
</html>

img 盒左浮動。其後的內容被格式化到浮動的右側,從浮動所在的同一行開始佈局。挨着浮動的行盒因爲浮動之故縮短,但浮動以後就恢復了它們「正常」寬度(即 p 元素建立的包含塊之寬)。該文檔格式化以下:

ReZKRqp.png

若是文檔以下,格式化的結果是同樣的:

<body>
   <p>Some sample text 
   <img src=img.png alt="This image will illustrate floats">
   that has no other...
</body>

這是由於浮動左側的內容爲浮動所替代,並被從新佈局在了浮動的右側。

正如8.3.1節開頭所言,浮動元素的外邊距不會同相鄰盒的外邊距摺疊。所以,在以前的例子中, p 盒和 img 浮動盒的垂直外邊距不會摺疊。

浮動的內容會像浮動建立了新的堆疊上下文 Stacking Context 同樣堆疊起來,但定位元素、建立了新的堆疊上下文並參與了浮動的父級堆疊上下文並的元素除外。浮動能夠同常規流中的其餘盒重疊(好比,浮動旁邊的常規流盒有負外邊距的時候)。當發生重疊時,浮動會被渲染在非定位文檔流內塊 Non-positioned In-flow Blocks 之上,文檔流內行內盒之下。

這有個例子,演示了浮動與常規流中元素的邊框重疊的狀況。

4SAJKo0.png

浮動圖片擋住了與其重疊的塊盒的邊框

下一個例子演示了使用 clear 屬性阻止內容佈局在浮動旁邊。

假設規則以下:

p { clear: left }

格式化結果可能以下所示:

u8za9UD.png

兩個段落都設置了 clear: left ,所以使得第二個段落「被往下推」到浮動之下的位置,這是「空隙」被添加到其上外邊距之上的結果(見 clear 屬性)

9.5.1 浮動定位: float 屬性

(譯者注:此處暫略,可參見CSS手冊)

用戶代理能夠視根元素上的 float none

如下是控制浮動行爲的準則:

  1. 左浮動盒的左外邊緣不可在其包含塊的左邊緣之左。右浮動元素亦是。

  2. 若是當前盒左浮動,而此前源文檔中已有元素生成了左浮動盒,那麼對每一個此前生成的盒而言,要麼當前盒的左外邊緣在此前生成盒的右外邊緣之右,要麼當前盒的頂部必須低於此前生成盒的底部。右浮動元素亦是。

  3. 左浮動盒的右外邊緣不可在其旁邊的右浮動盒的左外邊緣之右。右浮動元素亦是。

  4. 浮動盒的上外邊緣不可高於其包含塊的頂部。當浮動出現兩個摺疊外邊距之間時,浮動會如同它有一個參與常規流的空匿名父塊同樣來定位。該父塊的位置由關於外邊距摺疊那章的規則規定。

  5. 浮動盒的上外邊緣不可高於源文檔中此前元素生成的塊盒或浮動盒的上外邊緣。

  6. 元素的浮動盒的上外邊緣不可高於源文檔中此前元素生成的盒所在的行盒的頂部。

  7. 一個左浮動盒若是有其餘左浮動盒在其左側,其右外邊緣不可在其包含塊的右邊緣之右。(寬鬆點的要求是:左浮動不可超出其包含塊的右邊緣,除非該盒已經儘量靠左了。)右浮動元素亦是。

  8. 浮動盒必須儘量地往高擺放。

  9. 左浮動盒的擺放必須儘量地靠左,右浮動盒必須儘量靠右。更高的位置優先於更靠近左/右的位置。

lI6ls55.png

可是在CSS2.1中,若是,在塊格式化上下文中,有一個文檔流內負垂直高度的外邊距,使得浮動的位置高於它本來應當在的位置,全部這種負外邊距被設爲零,浮動的位置則未定義。

這些規則中提到的其餘元素僅指:在和浮動同屬一個塊格式化上下文的其餘元素。

這個HTML片斷結果爲 b 向右浮動

<p>a<span style="float: right">b</span></p>

若是 p 元素足夠寬, a b 則會各執一邊,以下所示:

RRkbQCc.png

9.5.2 控制浮動後的流: clear 屬性

(譯者注:屬性介紹略,可參看CSS手冊)

該屬性指定元素的某側不容許同此前的浮動盒相鄰。 clear 屬性不考慮其自己內的浮動或者處於其餘塊格式化上下文的浮動。

各值被應用於非浮動塊級盒時,具備以下意義:

  1. left:要求盒的上邊框邊緣低於源文檔內此前元素生成的左浮動盒的下外邊緣。

  2. right:要求盒的上邊框邊緣低於源文檔內此前元素生成的右浮動盒的下外邊緣。

  3. both:要求盒的上邊框邊緣低於源文檔內此前元素生成的左、右浮動盒的下外邊緣。

  4. none:對盒相對於浮動的定位沒有約束。

none 值可能產生空隙 Clearance 。空隙阻止外邊距摺疊並充當元素上外邊距之上的空間。空隙被用於推進元素垂直越過浮動。

計算設置了 clear 值的元素的空隙,首先要計算元素上邊框邊緣的假定位置,該位置即元素 clear 屬性值爲 none 時實際上邊框邊緣應該在的位置。

若是元素上邊框邊緣的假定位置沒有越過有關浮動,那麼空隙就會產生,而且外邊距摺疊要根據8.3.1章規則計算。

空隙的高度被設爲下述中的較大值:

  1. 塊的邊框邊緣與要被清除的最下方的浮動的下外邊緣不相交的必要高度。

  2. 將塊的上邊框邊緣放在其假定位置的必要高度。

二選一的話,空隙高度即第一種。

注意:兩種方式在目前的網頁內容的兼容性上有待評估。將來的CSS規範將規定爲其中一個或另外一個。

注意:空隙能夠爲負或爲零。

例1:假設(爲求簡單)有三個盒,規定以下: B1 塊的下外邊距爲 M1 B1 沒有子元素也沒有內邊距和邊框);浮動塊 F 的高度爲 H B2 塊上外邊距爲 M2 (沒有內邊距或邊框,沒有子元素)。 B2 clear 設爲 both 。假設 B2 不爲空。

不考慮 B2 clear 屬性,狀況以下圖所示。 B1 B2 的外邊距摺疊。 B1 的下邊框邊緣處在 y = 0 的位置, F 的頂部處在 y = M1 的位置, B2 的上邊框邊緣處在 y = max(M1,M2) 的位置, F 的底部處於 y = M1+H 的位置。

kjeqVI0.png

同時假設 B2 不在 F 之下:

max(M1,M2)

也就是說,正如規範說明的狀況,咱們須要添加空隙。

咱們須要兩次計算空隙 C1 C2 ,並取兩者之大: C = max(C1,C2) 。第一種方法是把 B2 的頂部和 F 的底部齊平,即,放在 y= M1+H 。也意味着外邊距之間的空隙使得外邊距再也不折疊:
F 的底部 = B2 的上邊框邊緣 ⇔

M1 + H = M1 + C1 + M2 ⇔

C1 = M1 + H - M1 - M2 = H - M2

第二次計算是保持 B2 頂部位置,即 y=max(M1,M2) 處,即:

max(M1,M2) = M1 + C2 + M2 ⇔

C2 = max(M1,M2) - M1 - M2

假設 max(M1,M2)

C2 = max(M1,M2) - M1 - M2

C2

又由於 C1 = H - M2,得

C2

因此

C = max(C1,C2) = C1

例2:本例中空隙的高度爲負,-1em。(假設全部元素都沒有邊框或者內邊距)

<p style="margin-bottom: 4em">
   First paragraph.
</p>
<p style="float: left; height: 2em; margin: 0">
   Floating paragraph.
</p>
<p style="clear: left; margin-top: 3em">
   Last paragraph.
</p>

說明:要是沒有 clear ,首段和末段兩個段落的邊距將會摺疊而且末段的上邊框邊緣將同浮動段落的頂部齊平。但 clear 使得上邊框邊緣低於浮動,即,降低2em。這意味着必定會產生空隙。由此,外邊距再也不折疊,空隙的高度 clearance 知足

clearance + margin-top = 2em

也就是說,

clearance = 2em - margin-top = 2em - 3em = -1em

clear 設在浮動元素上時,將形成浮動定位規則的修正。第10條額外規定補充以下:

  • (當 clear 設在浮動元素上時,)浮動的上外邊緣必須低於全部此前左浮動盒的下外邊緣( clear: left 情形下),或者低於全部此前的右浮動盒的( clear: right 情形下),或者低於此前左右浮動盒的( clear: both 情形下)。

注意:CSS1中該屬性適用於全部元素,所以全部元素都能實現效果。在CSS2和CSS2.1中, clear 屬性僅支持塊級元素。所以開發者們應當只將此屬性應用於塊級元素。若是要實現行內元素清除浮動效果,不該當如上所講的去設置空隙,而應當強制斷行並插入一個或多個空行盒(或者如9.5章節所講移動新行盒)來使要清除浮動的行內元素的行盒低於浮動盒。

9.6 絕對定位 Absolute Positioning

在絕對定位模型中,盒根據其包含塊來精準位移。盒從常規流中徹底脫離(對後來的同胞元素沒有影響)。絕對定位盒爲其常規流的子元素和絕對定位(非固定定位)後代建立新的包含塊。然而,絕對定位元素的內容不在其餘盒的流中。取決於重疊盒的棧級 Stack Level ,絕對定位元素的內容可能遮擋其餘盒的內容(或被遮擋)。

9.6.1 固定定位 Fixed Positioning

固定定位是絕對定位的一種下屬體系。惟一的區別在於,固定定位盒的包含塊是由視口建立的。在連續媒體中,當文檔滾動時,固定盒不移動。在此意義上,它們同固定背景圖片相像。在頁面媒體中,固定定位盒在每一頁重複。這對佈局頗有用,好比,擺放每頁底部的標識。比頁面區域要大的固定定位盒將會被裁切。固定定位盒在初始化包含塊中不可見的部分將不會打印。

開發者可使用固定定位去建立類框架佈局。考慮以下框架佈局:

JG4nG5f.png

這能夠經過以下HTML文檔和樣式規則實現:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>A frame document with CSS 2.1</title>
<style type="text/css" media="screen">
   body { height: 8.5in }/* 計算百分百高度須要 */
   #header {
      position: fixed;
      width: 100%;
      height: 15%;
      top: 0;
      right: 0;
      bottom: auto;
      left: 0;
   }
   #sidebar {
      position: fixed;
      width: 10em;
      height: auto;
      top: 15%;
      right: auto;
      bottom: 100px;
      left: 0;
   }
   #main {
      position: fixed;
      width: auto;
      height: auto;
      top: 15%;
      right: 0;
      bottom: 100px;
      left: 10em;
   }
   #footer {
      position: fixed;
      width: 100%;
      height: 100px;
      top: auto;
      right: 0;
      bottom: 0;
      left: 0;
   }
</style>
</head>
<body>
   <div id="header"> ...  </div>
   <div id="sidebar"> ...  </div>
   <div id="main"> ...  </div>
   <div id="footer"> ...  </div>
</body>
</html>

9.7 display position float 之間的關係

三種屬性均影響盒生成及佈局,它們的交互以下:

  1. 若是 display 值爲 none ,那麼 position float 不會應用。這種狀況下,元素不生成盒。

  2. 不然,若是 position 值爲 absolute fixed ,盒爲絕對定位, float 的計算值爲 none display 的設值以下表。盒的位置由 top right bottom left 屬性以及盒的包含塊決定。

  3. 不然,若是 float 值不爲 none ,盒浮動且 display 的設值以下表。

  4. 不然,若是元素爲根元素, display 設值以下表,除了其在CSS2.1中未定義 list-item 的指定值是否變爲計算值 block list-item

  5. 不然, dislay 屬性值使用指定值。

對應表:

  • 指定值:inline-table

  • 計算值:table

  • 指定值:inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block

  • 計算值:block

  • 指定值:其餘

  • 計算值:同指定值

相關文章
相關標籤/搜索