這篇文章帶給大家的內容是關於徹底理解CSS中視覺格式化模型(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
不論你在什麼時候開始,重要的是開始之後不要停止。
對於部分前端工程師來講,有時候CSS令他們很頭疼,明明設定了某個樣式,但是佈局就是不起作用。
如果你也有這種問題,那麼是時候學習下什麼是css視覺格式化模型了。知己知彼方能解決問題。
CSS 視覺格式化模型(visual formatting model)是用來處理和在視覺媒體上顯示文件時使用的計算規則。該模型是 CSS 的基礎概念之一。
視覺格式化模型會根據CSS盒子模型將文件中的元素轉換為一個個盒子,每個盒子的佈局由以下因素決定:
盒子的尺寸:精確指定、由約束條件指定或沒有指定
盒子的類型:行內盒子(inline)、行內級盒子(inline-level)、原子行內級盒子(atomic
inline-level)、塊盒子(block)
定位方案(positioning scheme):一般串流定位、浮動定位或絕對定位
#文檔樹中的其它元素:即目前盒子的子元素或兄弟元素
視窗尺寸與位置
所包含的圖片的尺寸
其他的某些外部因素
#該模型會根據盒子的包含區塊(containing block)的邊界來渲染盒子。通常,盒子會創建一個包含其後代元素的包含塊,但是盒子並不由包含塊所限制,當盒子的佈局跑到包含塊的外面時稱為溢出(overflow)
盒子的產生是CSS 視覺格式化模型的一部分,用於從文件元素產生盒子。盒子有不同的類型,不同類型的盒子的格式化方法也有所不同。盒子的類型取決於 CSS 的display屬性。
當元素的 display為 block、list-item或 table時,該元素將成為區塊級元素。一個區塊級元素會被格式化成一個區塊(例如文章的一個段落),預設按照垂直方向依序排列。
每個區塊級盒子都會參與區塊格式化上下文(block formatting context)的創建,而每個區塊級元素都會至少生成一個區塊級盒子,即主區塊級盒子(principal block-level box )。有一些元素,例如清單項目會產生額外的盒子來放置項目符號,而那些會產生清單項目的元素可能會產生更多的盒子。不過,多數元素只生成一個主塊級盒子。
主塊級盒子包含由後代元素產生的盒子以及內容,同時它也會參與定位方案。
一個區塊級盒子可能也是一個塊容器盒子。塊容器盒子(block container box)要么只包含其它塊級盒子,要么只包含行內盒子並同時創建一個行內格式化上下文(inline formatting context)。
能夠注意到塊級盒子與塊容器盒子是不同的這一點很重要。前者描述了元素與其父元素和兄弟元素之間的行為,而後者描述了元素與其後代之間的行為。有些塊級盒子並不是塊容器盒子,例如表格;而有些塊容器盒子也不是塊級盒子,例如非替換行內塊和非替換表格單元格。
一個同時是塊容器盒子的塊級盒子稱為塊盒子(block box)。
匿名方塊盒子
在某些情況下進行視覺格式化時,需要添加一些增補性的盒子,這些盒子不能用CSS選擇符選中,因此稱為匿名盒子(anonymous boxes)。
CSS選擇器不能作用於匿名盒子(anonymous boxes),所以它不能被樣式表賦予樣式。也就是說,此時所有可繼承的 CSS 屬性值都是 inherit ,而所有不可繼承的 CSS 屬性值都是 initial。
區塊包含盒子可能只包含行內級盒子,也可能只包含區塊級盒子,但通常的文件都會同時包含兩者,在這種情況下,就會在相鄰的行內級盒子外建立匿名塊盒子。
範例節
考慮下面的HTML程式碼,假設和都保持預設的樣式(即它們的display 為block):
<div> Some inline text <p>followed by a paragraph</p> followed by more inline text. </div>
此時會產生兩個匿名區塊盒子:一個是元素前面的那些文字(Some inline text),另一個是元素後面的文字(followed by more inline text.)。此時會產生下面的區塊結構:
顯示為:
Some inline text followed by a paragraph followed by more inline text.
对这两个匿名盒子来说,程序员无法像
元素那样控制它们的样式,因此它们会从
那里继承那些可继承的属性,如 color。其他不可继承的属性则会设置为 initial,比如,因为没有为它们指定 background-color,因此其具有默认的透明背景,而 元素的盒子则能够用CSS指定背景颜色。类似地,两个匿名盒子的文本颜色总是一样的。
另一种会创建匿名块盒子的情况是一个行内盒子中包含一或多个块盒子。此时,包含块盒子的盒子会拆分为两个行内盒子,分别位于块盒子的前面和后面。块盒子前面的所有行内盒子会被一个匿名块盒子包裹,块盒子后面的行内盒子也是一样。因此,块盒子将成为这两个匿名块盒子的兄弟盒子。
如果有多个块盒子,而它们中间又没有行内元素,则会在这些盒子的前面和后面创建两个匿名块盒子。
行内级元素和行内盒子节
如果一个元素的display属性为inline、inline-block或inline-table,则称该元素为行内级元素。显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。一个典型的例子是包含多种格式内容(如强调文本、图片等)的段落,就可以由行内级元素组成。
行内级元素会生成行内级盒子,该盒子同时会参与行内格式化上下文(inline formatting context)的创建。行内盒子既是行内级盒子,也是一个其内容会参与创建其容器的行内格式化上下文的盒子,比如所有具有display:inline样式的非替换盒子。如果一个行内级盒子的内容不参与行内格式化上下文的创建,则称其为原子行内级盒子。而通过替换行内级元素或display值为inline-block或inline-table的元素创建的盒子不会像行内盒子一样可以被拆分为多个盒子。
注意:开始的时候,原子行内级盒子叫做原子行内盒子,这并不准确,因为它们并不是行内盒子。后来在一次勘误时修正了这一问题。不过,当你见到某些文章中使用了“原子行内盒子”的时候,你尽可以将其理解为“原子行内级盒子”,因为这仅仅是一个名字的修改。
在同一个行内格式化上下文中,原子行内级盒子不能拆分成多行:
<style> span { display: inline; /* default value*/ }</style> <div> The text in the span <span>can be split in several lines as it</span> is an inline box. </div>
可能会显示为:
The text in the span can be split into several lines as it is an inline box.
而:
<style> span { display: inline-block; }</style> <div> The text in the span <span> cannot be split in several lines as it </span> is an inline-block box. </div>
则可能显示为:
The text in the span cannot be split into several lines as it is an inline-block box.
其中的“cannot be split into several lines as it”永远不会换行。
类似于块盒子,CSS引擎有时候也会自动创建一些行内盒子。这些行内盒子无法被选择符选中,因此是匿名的,它们从父元素那里继承那些可继承的属性,其他属性保持默认值initial。
一种常见的情况是CSS引擎会自动为直接包含在块盒子中的文本创建一个行内格式化上下文,在这种情况下,这些文本会被一个足够大的匿名行内盒子所包含。但是如果仅包含空格则有可能不会生成匿名行内盒子,因为空格有可能会由于white-space的设置而被移除,从而导致最终的实际内容为空。
行盒子由行内格式化上下文创建,用来显示一行文本。在块盒子内部,行盒子总是从块盒子的一边延伸到另一边(译注:即占据整个块盒子的宽度)。当有浮动元素时,行盒子会从向左浮动的元素的右边缘延伸到向右浮动的元素的左边缘。
行盒子更多是以技术性目的而存在的,Web开发者通常不需要关心。
Run-in 盒子通过display:run-in来定义,它可以是块盒子,也可以是行内盒子,这取决于紧随其后的盒子的类型。Run-in 盒子可以用来在可能的情况下将标题嵌入文章的第一个段落中。
注意:Run-in 盒子已经在CSS 2.1的标准中移除了,但可能会在CSS 3中作为一个实验性的内容再次加入。因此最好不要将其用于正式项目。
除了行内格式化上下文和块格式化上下文之外,CSS还定义了几种内容模型,这些模型同样可以应用于元素。这些模型一般用来描述布局,它们可能会定义一些额外的盒子类型:
表格内容模型可能会创建一个表格包装器盒子和一个表格盒子,以及多个其他盒子如表格标题盒子等
多列内容模型可能会在容器盒子和内容之间创建多个列盒子
实验性的网格内容模型或flex-box内容模型同样会创建一些其他种类的盒子
定位規則
一旦產生了盒子以後,CSS引擎就需要定位它們以完成佈局。以下是定位盒子時所使用的規則:
普通流:依序依序定位每個盒子
浮動:將盒子從普通流中單獨拎出來,將其放到外層盒子的某一邊
絕對定位:按照絕對位置來定位盒子,其位置根據盒子的包含元素所建立的絕對坐標系來計算,因此絕對定位元素有可能會覆寫其他元素
在普通流中,盒子會依序放置。在區塊格式化上下文中,盒子在垂直方向依次排列;而在行內格式化上下文中,盒子則水平排列。當CSS的 position 屬性為 static 或 relative,且 float 為 none 時,其佈局方式為普通流。
在浮動定位中,浮動盒子會浮動到目前行的開始或尾部位置。這會導致普通流中的文字及其他內容會「流」到浮動盒子的邊緣處,除非元素透過 clear 清除了前面的浮動。一個盒子的 float 值不為 none,且其 position 為 static 或 relative 時,該盒子為浮動定位。如果將 float 設定為 left,浮動盒子會定位到目前行盒子的起始位置(左側),如果設定為 right,浮動盒子會定位到目前行盒子的尾部位置(右側)。不管是左浮動還是右浮動,行盒子都會伸縮以適應浮動盒子的大小。
在絕對定位中,盒子會完全從當前流中移除,並且不會再與其有任何聯繫(譯註:此處僅指定位和位置計算,而絕對定位的元素在文檔樹中仍與其他元素有父子或兄弟等關係),其位置會使用top、bottom、left 和right
#相對其包含區塊進行計算。若元素的 position 為 absolute 或 fixed,則該元素為絕對定位。
對固定位置的元素來說,其包含區塊為整個視口,該元素相對視口進行絕對定位,因此滾動時元素的位置並不會改變。
#以上是徹底理解CSS中視覺格式化模型(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!