視覺格式化模型

在 CSS 中,**視覺格式化模型**描述了使用者代理如何獲取文件樹,並將其處理和顯示為視覺媒體。這包括諸如計算機螢幕之類的**連續媒體**和諸如書籍或瀏覽器列印功能列印的文件之類的**分頁媒體**。大部分資訊同樣適用於連續媒體和分頁媒體。

在視覺格式化模型中,文件樹中的每個元素根據盒模型生成零個或多個盒子。這些盒子的佈局受以下因素控制:

  • 盒子尺寸和型別。
  • 定位方案(普通流、浮動和絕對定位)。
  • 文件樹中元素之間的關係。
  • 外部資訊(例如,視口大小、影像的內在尺寸等)。

關於視覺格式化模型的大部分資訊都定義在 CSS2 中,但是,各種 CSS 佈局模組擴充套件了這些資訊。在閱讀規範時,您通常會發現對 CSS2 中定義的模型的引用,因此,在閱讀其他佈局規範時,瞭解該模型以及 CSS2 中用於描述該模型的術語非常有價值。

在本文件中,我們定義了該模型並介紹了一些相關的術語和概念,並連結到更具體的頁面以獲取更多詳細資訊。

視口的角色

在連續媒體中,**視口**是瀏覽器視窗的檢視區域。當視口大小發生變化時,使用者代理可以更改頁面的佈局——例如,如果您調整視窗大小或更改移動裝置的方向。

如果視口小於文件的大小,則使用者代理需要提供一種滾動到未顯示的文件部分的方法。我們最常看到的是在**塊維度**中滾動——在水平的從上到下的語言中垂直滾動。但是,您可能需要設計一些需要在**內聯維度**中滾動的內容。

框生成

**盒子生成**是 CSS 視覺格式化模型中從文件的元素建立盒子的部分。生成的盒子型別不同,這會影響它們的視覺格式。生成的盒子的型別取決於 CSS display 屬性的值。

display 屬性最初在 CSS2 中定義,並在 CSS 顯示模組級別 3 中進行了擴充套件。此外,自 CSS2 以來,圍繞顯示的一些術語已更新並得到澄清。

CSS 將您的源文件呈現到畫布上。為此,它會生成一箇中間結構,即**盒子樹**,它表示渲染文件的格式化結構。盒子樹中的每個盒子都表示其對應元素(或偽元素)在畫布上的空間和/或時間,而盒子樹中的每個文字執行都表示其對應文字節點的內容。

然後,對於每個元素,CSS 會根據該元素的display屬性值生成零個或多個盒子。

注意:盒子通常以其顯示型別來指代——例如,由具有display: block的元素生成的盒子稱為“塊級盒子”或簡稱“塊”。但是請注意,塊級盒子、塊級容器和盒子容器都存在細微差別;有關更多詳細資訊,請參見下面的塊級盒子部分。

主盒子

當一個元素生成一個或多個盒子時,其中一個盒子是主盒子,它包含其後代盒子和在盒子樹中生成的內容,並且也是任何定位方案中涉及的盒子。

某些元素除了主盒子之外,還可以生成其他盒子,例如display: list-item會生成多個盒子(例如,一個主塊級盒子和一個子標記盒子)。並且某些值(例如nonecontents)會導致元素及其後代根本不生成任何盒子。

匿名盒子

當沒有HTML元素可用於盒子時,就會建立匿名盒子。例如,當您在父元素上宣告display: flex,並且在其內部直接有一段未包含在其他元素中的文字時,就會發生這種情況。為了修復盒子樹,會在該文字段周圍建立一個匿名盒子。然後它將表現為一個彈性專案,但是,由於沒有元素可以作為目標,因此無法像常規盒子一樣對其進行定位和樣式設定。

當您在文字段與塊級元素之間交錯時,也會發生相同的情況。在下一個示例中,我在一個<div>中有一段字串;在我的字串中間有一個包含部分文字的<p>元素。

該字串在盒子樹中被分成三個盒子。段落元素之前的字串部分包裝在一個匿名盒子中,然後是我們生成的盒子的<p>,然後是另一個匿名盒子。

關於這些匿名盒子需要注意的一點是,它們繼承自其直接父級的樣式,但您無法透過定位匿名盒子來更改其外觀。在我的示例中,我使用直接子元素選擇器來定位容器的子元素。這不會更改匿名盒子,因為它們本身不是“元素”。

當字串被內聯元素分割時,會建立內聯匿名盒子,例如,一個包含用<em></em>包裹的部分的句子。這將句子分成三個內聯盒子——強調部分之前的匿名內聯盒子、用<em>元素包裹的部分,然後是最終的匿名內聯盒子。與匿名塊級盒子一樣,這些匿名內聯盒子無法像<em>那樣獨立設定樣式;它們只是繼承其容器的樣式。

其他格式化上下文也會建立匿名盒子。網格佈局的行為與上面彈性盒子示例相同,將文字字串轉換為具有匿名盒子的網格專案。多列佈局會在列周圍建立匿名列盒子;這些盒子也不能設定樣式或以其他方式定位。表格佈局將新增匿名盒子以建立正確的表格結構——例如,如果不存在具有display: table-row的盒子,則新增匿名錶格行。

行盒子

行盒子是包裹每一行文字的盒子。如果您浮動一個專案,然後在其後跟隨一個具有背景顏色的塊,則可以檢視行盒子與其包含塊之間的區別。

在下面的示例中,浮動<div>後面的行盒子被縮短以包裹浮動項。盒子的背景在浮動項後面執行,因為浮動項已被移出文件流。

定位方案以及內聯和外聯元素

在 CSS 中,盒子可以根據三種定位方案進行佈局——普通流浮動絕對定位

普通流

在 CSS 中,普通流包括塊級盒子的塊級格式化、內聯盒子的內聯級格式化,還包括塊級和內聯級盒子的相對和粘性定位。

閱讀有關 CSS 中流佈局的更多資訊。

浮動

在浮動模型中,盒子首先根據普通流進行佈局,然後從流中取出並進行定位,通常位於左側或右側。內容可能會沿著浮動的一側流動。

詳細瞭解浮動

絕對定位

在絕對定位模型(也包括fixed定位)中,盒子完全從普通流中移除,並相對於包含塊(在固定定位的情況下為視口)或CSS 錨點定位中的一個或多個錨元素進行定位。

如果一個元素是浮動的、絕對定位的或根元素,則稱為脫離文件流。如果一個元素沒有脫離文件流,則稱為在文件流中

閱讀有關CSS 定位佈局的資訊。

格式化上下文和 display 屬性

盒子可以被描述為具有外部顯示型別,即blockinline。此外部顯示型別指的是盒子在頁面上與其他元素一起如何表現。

盒子也具有內部顯示型別,用於指示其子元素的行為。對於正常的塊級和內聯級佈局或普通流,此顯示型別為flow。這意味著子元素也將是blockinline

但是,內部顯示型別可能是gridflex之類的型別,在這種情況下,直接子元素將顯示為網格或彈性專案。在這種情況下,該元素被描述為建立網格或彈性格式化上下文。在許多方面,這類似於塊級格式化上下文,但是,子元素的行為表現為彈性專案或網格專案,而不是普通流中的專案。

塊級和內聯級盒子之間的互動在display屬性參考中進行了描述。

此外,特定顯示值的參考解釋了這些格式化上下文在盒子佈局方面的運作方式。

獨立格式化上下文

元素要麼參與其包含塊的格式化上下文,要麼建立獨立的格式化上下文。例如,網格容器為其子元素建立了一個新的網格格式化上下文

獨立格式化上下文包含浮動,並且邊距不會跨格式化上下文邊界摺疊。因此,建立新的塊級格式化上下文可以確保浮動和邊距保留在盒子內部。為此,請在您希望在其上建立新的塊級格式化上下文的盒子上新增display: flow-root

以下示例顯示了display: flow-root的效果。具有黑色背景的盒子似乎包裹在浮動項和文本週圍。如果您從可編輯的 CSS 中刪除display: flow-root,則浮動項將從盒子的底部突出,因為它不再被包含。

塊級盒子

在規範中,塊級盒子、塊級容器和塊級容器在某些地方都被稱為塊級盒子。這些東西有點不同,只有在沒有歧義的情況下才能使用術語塊級盒子。

塊級容器

塊級容器要麼僅包含參與內聯格式化上下文的內聯級盒子,要麼僅包含參與塊級格式化上下文的塊級盒子。因此,我們看到了上面解釋的行為,其中引入了匿名盒子以確保所有專案都可以參與塊級或內聯格式化上下文。只有當元素包含塊級或內聯級盒子時,它才是塊級容器。

內聯級和塊級盒子

這些分別是包含在塊級容器內並分別參與內聯或塊級佈局的盒子。

塊級盒子

塊級盒子是一個也是塊級容器的塊級盒子。如 CSS display中所述,盒子可以是塊級盒子,但不能也是塊級容器(例如,它可能是彈性容器或網格容器)。

另請參閱