「前端早讀君007」css進階之徹底理解視覺格式化模型

今日勵志

不論你在什么時候開始,重要的是開始之后不要停止。

前言

對于部分前端工程師來講,有時候CSS令他們很頭疼,明明設置了某個樣式,但是布局就是不起作用。

clipboard.png

如果你也有這種問題,那么是時候學習下什么是css視覺格式化模型了。知己知彼方能解決問題。

clipboard.png

CSS 視覺格式化模型(visual formatting model)是用來處理和在視覺媒體上顯示文檔時使用的計算規則。該模型是 CSS 的基礎概念之一。

視覺格式化模型會根據CSS盒子模型將文檔中的元素轉換為一個個盒子,每個盒子的布局由以下因素決定:

  1. 盒子的尺寸:精確指定、由約束條件指定或沒有指定
  2. 盒子的類型:行內盒子(inline)、行內級盒子(inline-level)、原子行內級盒子(atomic
    inline-level)、塊盒子(block)
  3. 定位方案(positioning scheme):普通流定位、浮動定位或絕對定位
  4. 文檔樹中的其它元素:即當前盒子的子元素或兄弟元素
  5. 視口尺寸與位置
  6. 所包含的圖片的尺寸
  7. 其他的某些外部因素

該模型會根據盒子的包含塊(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.)。此時會生成下面的塊結構:

clipboard.png

顯示為:

Some inline textfollowed by a paragraphfollowed by more inline text.

對這兩個匿名盒子來說,程序員無法像<p>元素那樣控制它們的樣式,因此它們會從<div>那里繼承那些可繼承的屬性,如 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 style="width:20em;">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 style="width:20em;">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 盒子

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,該元素為絕對定位。

對固定位置的元素來說,其包含塊為整個視口,該元素相對視口進行絕對定位,因此滾動時元素的位置并不會改變。

參考資料MDN文檔:https://developer.mozilla.org...

你可能喜歡

clipboard.png

打開微信掃一掃關注早讀君,每天早晨為你推送前端知識,度過擠地鐵坐公交的時光

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280991.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280991.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280991.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

.NET周報【11月第3期 2022-11-22】

國內文章.NET Conf China 2022 第一批講師陣容大揭秘&#xff01;整個期待了&#xff01;https://mp.weixin.qq.com/s/4p89hhBPw6qv-0OB_T_TOg目光看過來 2022 年 12 月 3-4 日&#xff0c;一場社區性質的國內規模最大的 線上線下.NET Conf 2022 技術大會 即將盛大開幕。目前大…

解讀Facebook CAN:如何給人工智能賦予藝術創作的力量

雷鋒網 AI 科技評論按&#xff1a;能夠迭代進化、模仿指定數據特征的GAN&#xff08;生成式對抗性網絡&#xff09;已經是公認的處理圖像生成問題的好方法&#xff0c;自從提出以來相關的研究成果不少&#xff0c;在圖像增強、超分辨率、風格轉換任務中的效果可謂是驚人的。 &a…

全向輪底盤磁導軌尋跡

全向輪底盤上安裝兩條磁傳感器帶用于磁導軌尋跡 如簡圖所示&#xff0c;兩條與Y直線相交的黑色線條我們認為是兩條磁檢測傳感器帶 矢量方法修正車體位置 定義軌道左為負向&#xff0c;軌道右為正向。傳感器左檢測為負&#xff0c;右檢測為正&#xff1b; 定義底盤坐標系為αβ&…

02-1.CSS邊框,邊界,布局相關筆記

目錄 CSS盒子模型 padding內填充 邊框 邊框屬性 border-radius margin外邊距 CSS盒子模型 Content(內容): 盒子的內容&#xff0c;顯示文本和圖像 >>>>類似word 文字A&#xff0c;改變字體與大小padding: 用于控制內容與邊框之間的距離 …

圖表庫

在2018年最后一天開源了自己的基于svg圖表庫mcharts 后面要大量時間去維護 mcharts 希望多提Issues 具體用法可以看文檔 可以一塊探討下技術問題 2019年新的開始新的起點 加油

android仿ios彈框_在“提示”框中:iOS外觀(在Android上運行),Google Maps作為Time Machine,下載Wii游戲保存...

android仿ios彈框Once a week we round up some great reader tips and share them with everyone. Read on to see how to make your Android phone look like iOS, use a Google Maps mashup like a time machine, and download Wii game saves. 每周一次&#xff0c;我們收集…

使用 C# 開發的摸魚背單詞軟件 ToastFish

你好&#xff0c;這里是 Dotnet 工具箱&#xff0c;定期分享 Dotnet 有趣&#xff0c;實用的工具和組件&#xff0c;希望對您有用&#xff01;摸魚神器ToastFish 是一個使用 C# 開發的桌面軟件&#xff0c;由 Uahh 開發&#xff0c; 這是一個利用Windows通知欄背單詞的軟件&…

使用log4Net 輸出日志到mongodb

將日志輸入到nosql 數據庫可以保證日志輸出速度和統一管理日志&#xff0c;log4mongo-net 項目http://log4mongo.org/display/PUB/Log4mongofor.NET使用log4net把日志保存到Mongodb。通常可用于代替log4netMS SSQL logging &#xff0c;和SQL Server相比可以節省40%的存儲空間&…

03.JavaScript對DOM操作

JavaScript引入方式 外部引入 在head或者body中&#xff0c;添加以下代碼 <script type"text/javascript" src"js/demo.js"></script> 內部引入 在head或body中&#xff0c;定義script標簽&#xff0c;然后在script標簽里面寫js代碼 <…

kotlin的suspend對比csharp的asyncawait

協程的出現大大降低了異步編程的復雜度&#xff0c;可以讓我們像寫同步代碼一樣去寫異步代碼&#xff0c;如果沒有它&#xff0c;那么很多異步的代碼都是需要靠回調函數來一層層嵌套&#xff0c;這個在我之前的一篇有介紹 rxjava回調地獄-kotlin協程來幫忙本篇文章主要介紹kotl…

file協議 控制面板_如何在Windows File Explorer導航窗格中顯示控制面板和回收站

file協議 控制面板By default, the Windows File Explorer’s sidebar is divided into big categories like Quick Access, This PC, Network, and so on. But a quick setting change can make your navigation pane look a bit more like the traditional tree you’d see i…

hdu-2612-Find a way(廣搜,bfs)

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city.…

過濾器(Filter)

1 什么是過濾器 過濾器JavaWeb三大組件之一&#xff0c;它與Servlet很相似&#xff01;不它過濾器是用來攔截請求的&#xff0c;而不是處理請求的。 當用戶請求某個Servlet時&#xff0c;會先執行部署在這個請求上的Filter&#xff0c;如果Filter“放行”&#xff0c;那么會繼…

03-1.JavaScript基礎語法略寫/模版字符串

基礎語法 參考前端基礎之JavaScript - Q1mi - 博客園 略寫原因 由于后續主要用jQuery編寫&#xff0c;jQuery簡化編程。大概了解JavaScript語法即可。 jQuery是一個輕量級的、兼容多瀏覽器的JavaScript庫。jQuery使用戶能夠更方便地處理HTML Document、Events、實現動畫效果…

發布適用于 .NET 7 的 .NET MAUI

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;6分鐘)我們在六個月前向您介紹了 .NET 多平臺應用程序 UI (MAUI)&#xff0c;現在我們很高興地宣布 .NET MAUI 在我們的下一個主要版本 .NET 7 中普遍可用。在此短的時間范圍內&#xff0c;我們在 .NET MAUI 中的主要…

bzoj3160(FFT+回文自動機)

題目描述 https://www.lydsy.com/JudgeOnline/problem.php?id3160 題解 先把問題轉化一下&#xff0c;我們要求的是非連續對稱回文子序列。 ans回文子序列數-回文子串數。 回文子串數可以用PAM或manachar求出來。 復習了一下PAM&#xff0c;用它求回文子串數和SAM一樣&#xf…

03:數據結構 棧、隊列、鏈表與數組

算法其他篇 目錄&#xff1a; 1.1 數據結構中的一些概念1.2 棧&#xff08;stack&#xff09;1.3 隊列1.4 鏈表1.5 python中字典對象實現原理1.6 數組1.1 數據結構中的一些概念 返回頂部 1、數據結構是什么 1、簡單來說&#xff0c;數據結果就是設計數據以何種方式存儲在計…

力登:以智能化管理提升數據中心服務能力成熟度

2017年2月28日&#xff0c;由全國信息技術標準化技術委員會信息技術服務分技術委員會指導的《信息技術服務數據中心服務能力成熟度模型》發布&#xff0c;在業界首次提出“數據中心服務能力成熟度”概念&#xff0c;使得數據中心的管理真正實現了數字化和持續優化&#xff0c;是…

基于.NET 7 的 WebTransport 實現雙向通信

Web Transport 簡介WebTransport 是一個新的 Web API&#xff0c;使用 HTTP/3 協議來支持雙向傳輸。它用于 Web 客戶端和 HTTP/3 服務器之間的雙向通信。它支持通過 不可靠的 Datagrams API 發送數據&#xff0c;也支持可靠的 Stream API 發送數據。因為 HTTP/3 使用了基于 UDP…

Django01: 安裝/基礎命令/設置筆記

安裝 按官網版本支持&#xff0c;現在比較適合使用1.11版本。 下載安裝命令 pip3 install django1.11.9 新建項目 django-admin startproject mysite 運行項目 python manage.py runserver 127.0.0.1:8000 運行相關 目錄介紹 mysite/ ├── manage.py # 管理文件 └…