1. 程式人生 > >大前端學習筆記【七】關於CSS再次整理

大前端學習筆記【七】關於CSS再次整理

如果你在日常工作中使用 CSS,你的主要目標可能會重點圍繞著使事情“看起來正確”。如何實現這一點經常是遠不如最終結果那麼重要。這意味著比起正確的語法和視覺結果來說,我們更少關心 CSS 的工作原理。

CSS 的視覺結果通常是操作隱藏屬性的間接後果,你可能還沒有意識到這一點。某些 CSS 屬性(比如 background-color)與你看到的內容有直接而明顯的關係。同時,其它像 display 這樣的屬性對於我們很多人來說仍然是模稜兩可的,因為結果似乎與上下文環境有很大關係。所以...我們需要對於CSS進行再次的整理和探索

渲染過程概述

當載入一個 HTML 文件時,為了讓該頁面渲染,有很多事情要發生。

第一個步驟就是解析 HTML 文件。瀏覽器從這一步建立一個文件樹。樹狀結構是表示像 HTML 這種具有明顯層次結構資訊的一種方法。樹中的元素可以被描述為類似於族譜,比如祖先、父親、孩子和兄弟姐妹。

你可能聽說過術語 DOM。它代表文件物件模型(Document Object Model)。這是文件樹結構的一種擴充套件,被用於儲存和操作 Web 文件內容有關的資訊。

隨著 HTML 被解析,樣式表和其它資源也被獲取。樣式宣告通過一個稱為層疊的過程來解釋和確定。

在此過程期間,CSS 屬性的最終值被確定。在計算後,這些值可能與樣式表中定義的有所不同。例如,像 auto 這種關鍵字和相對單位被指派了真實值,並且繼承值被應用了。這些計算值被儲存在一個樹中,類似於 DOM 中的元素,毫不奇怪,它被稱為 CSS 物件模型或者 CSSOM。

現在才有可能開始渲染頁面的過程。這個過程的第一步是盒模型的計算。這是一個算出元素的尺寸和間距的重要步驟,雖然不一定是元素的最終位置。

與盒模型相比,不那麼被人熟知的是一個稱為視覺格式化模型的過程。這個過程確定元素在頁面上的佈局和位置。它包含了一些你可能已經熟悉的概念,比如定位方案、格式化上下文、顯示模式和堆疊上下文。

最後,頁面被渲染。

上面的段落中可能有一些你還不熟悉的一些術語。如果是這樣的話,最重要的是要理解層疊、盒模型以及視覺格式化模型。這些術語都是解釋、處理和渲染 HTML 和 CSS 的核心步驟。我們下面要更詳細地研究一下這三個步驟。

層疊

層疊可能是最被誤解的 CSS 特性之一。它是指組合不同樣式表以及解決 CSS 選擇器之間衝突的過程。

層疊檢視宣告的重要性、來源、特殊性以及順序,來確定使用哪個樣式規則。

你需要知道什麼:

大多數網站有多個樣式表。通常,樣式是用引用一個 CSS 檔案的一個 link 標記,或者 HTML 主體部分的 style 標記新增的。即使最基礎的頁面也會有瀏覽器提供的預設樣式。這種預設樣式表有時被稱為 user-agent 樣式表。

在層疊期間,樣式表是按如下順序被解釋的:

  1. !important 宣告

  2. 作者的樣式表

  3. 瀏覽器預設的樣式表

注意:這裡我跳過了使用者樣式表,是因為它們不再常見,可能不會是讀這本文的所有人要考慮的因素。

在組合這些來源後,如果多個規則應用到同一元素,就用特殊性來確定應用哪條規則。

特殊性

特殊性(Specificity)是給選擇器的權重。它常被誤認為是一個數字。實際上是 4 個單獨的數字或者 4 種權重類別。

要計算特殊性,要統計如下選擇器的數目:

  1. ID 選擇器

  2. 類選擇器、屬性選擇器和偽類選擇器

  3. 元素選擇器和偽元素選擇器

例如:#nav .selected:hover > a::before 將是 1, 2, 2

無論有多少個類選擇器,都不會比一個 ID 選擇器有更高的特殊性。當比較選擇器時,我們首先比較 ID 選擇器的特殊性。只有 ID 選擇器相等時,才比較類選擇器、屬性選擇器和偽類選擇器的特殊性值。如果最後依然相等,才比較元素和偽元素選擇器。

如果每個類別的特殊性都是相等的,那麼來源中最後的宣告獲勝。

是的!我知道我說的是 4 個類。行內樣式比 ID 選擇器有更高的特殊性。不過由於在技術上行內樣式在特殊性計算中是第一類,通常你不會與行內樣式競爭,所以很容易記住行內樣式的特殊性總是會佔優。

重要的注意事項:雖然 !important 宣告不會作為特殊性計算的因素,不過它們比層疊中的普通宣告有更大的優先順序。

繼承

繼承不是層疊的一部分,不過我在這裡把它包含進來,是因為它經常被與層疊結合在一起討論。

繼承是應用給一個元素的值可以被傳遞到(或者繼承)子元素上的過程。

你肯定知道這個事實,即當把字型屬性應用到 body 或者其它容器元素時,該屬性也會被容器內的所有元素所繼承。這就是繼承。

並非所有屬性預設都被繼承。理解繼承是編寫更優雅更簡潔 CSS 的關鍵。有時候用 inherit 關鍵字強制繼承會相當有用。

注意: 有些屬性(比如 border-color)預設值是 currentcolor。也就是說,它們會使用在 color 屬性上設定的值。預設值與繼承不是一碼事。不過,color 屬性本身經常是被繼承的,所以我傾向於認為這是一種事實上的繼承。

盒模型

理解盒模型是佈局和定位時防止挫敗所必需的。盒模型是 CSS 中最基本的概念之一。

盒模型用於計算元素的寬度和高度。它只是計算過程中的一個步驟,確定元素的最終佈局和定位並非完全依賴於它。

你需要知道什麼:

HTML 中的每個元素都是一個矩形的盒子。每個盒子有用元素的外邊距(margin)、邊框(border)、內邊距(padding)和內容區定義的四個區域。

預設情況下,當我們設定一個元素的寬度時,只是設定內容區的寬度。當給一個元素新增內邊距、邊框或者外邊距時,是增加了除寬度以外的部分。實際上,這就是說寬度為 50% 的兩個元素如果添加了內邊距、外邊距或者邊框,就不會並排填滿寬度(因為已經超過了 100% 寬度)。

當設定元素的背景時,不僅會填充內容區,還會填充內邊距區和邊框區。

概念上,我們把一個 HTML 元素當作是一個東西,所以很容易認為一個元素的視覺邊界等於它的寬度,不過實際卻並非如此。雖然一個元素的視覺邊界包含了內邊距和邊框區,不過 width 屬性是顯式地被應用到內容盒。

Width Auto

另一個潛在的困惑來源是 width: auto 的工作機制。寬度為 auto 是大多數 HTML 元素的預設元素,對於像 div、p 這種塊元素來說,auto 會計算寬度,這樣外邊距、邊框、內邊距以及內容區都組合在一起也能剛好放在可用空間內。

在這種情況下,感覺新增內邊距和外邊距會向內擠壓內容,不過實際上,寬度會被重新計算,以確保所有東西都能剛好放下。相比之下,在設定寬度為 100% 時,光內容區就會把可用空間填滿,而不管外邊距、內邊距和邊框。

Box-sizing

box-sizing 屬性會改變盒模型的工作方式。當 box-sizing 被設定為 border-box 時,內邊距和邊框會減少內容區的內部寬度,而不是新增元素的整體寬度。也就是說,元素的寬度現在與其視覺寬度是相同的。

視覺格式化模型

盒模型計算元素的大小,而視覺格式化模型(Visual Formatting Model)負責確定這些盒子的佈局。視覺視覺化模型考慮盒子的型別、定位方案、元素之間的關係以及內容施加的約束,來確定頁面上每個元素的最終位置和呈現。

你需要知道什麼:

視覺格式化模型遍歷文件樹,根據 CSS 盒模型生成一到多個渲染元素所需的盒子。CSS 的 display 屬性在確定一個元素如何參與當前上下文和定位方案中發揮關鍵作用。這些部分綜合在一起,確定元素的最終佈局和定位。

這是一個複雜的步驟,也是目前為止最難嘗試和總結的。如果你還沒了解所有這些知識的話,沒有關係。理解如何通過 CSS 屬性操縱定位方案和格式化上下文是個好的開端。如果你理解了該模型的不同部分之間的相互作用的話,你就會比大多數人做得更好。起碼你應該知道它們的存在。

Display 型別

我們知道,在 CSS 中設定 display 屬性可以確定如何渲染元素,但是還不清楚其工作原理。事實上,它有時甚至好像是不可預測的。

這是因為,display 屬性確定了元素的”盒子型別“。這個隱藏屬性由一個內部顯示型別和一個外部顯示型別組成,二者在一起幫助確定如何渲染元素。

外部顯示型別通常要麼是解析為 block,要麼是解析為 inline,並且與我們對 CSS 中這些 display 屬性的期望幾乎是一致的。從技術上講,外部顯示型別規定一個元素如何參與其父元素的格式化上下文。

內部顯示型別決定元素會生成什麼樣的格式化上下文。這會影響其子元素的佈局排列方式。

想想彈性盒容器的工作機制。其外部型別是 block,內部型別是 flex。它的子元素也可以有一個 block 外部型別,不過子元素的佈局是受彈性盒容器的格式化上下文所影響的。

思考這種問題的一個方法是,display 的職責是在元素及其父元素之間共享的。

格式化上下文

格式化上下文都是與佈局有關。它們是控制容器內元素的佈局以及它們之間如何相互作用的規則。

有些格式化上下文可以直接在容器上設定,比如通過用 display 屬性值 flexgridtable。其它型別的格式化上下文,比如塊格式化上下文和行內格式化上下文可以被瀏覽器根據需要建立。

注意:在過去,因為塊格式化上下文與浮動互動的方式,理解如果讓瀏覽器建立一個新的塊格式化上下文是很重要的。設定為塊格式化上下文的元素會包含浮動。不過現在它沒有以前那麼重要。事實上,它甚至都不是現代清除浮動技術的工作原理了。

定位方案

一個盒子可以根據三種定位方案之一來佈局,包括常規流、浮動和絕對定位。你可能熟悉浮動和絕對定位,因為在編寫 CSS 時,我們會更直接與這兩個打交道。常規流只是一個在元素沒有浮動或者定位時預設定位方案的名字。

常規流

常規流(Normal Flow)描述了預設定位方案,'in-flow'(流內)描述遵從該方案的元素。你可以把流內當作是元素根據其源順序和格式化上下文佈局時的自然位置。

浮動

浮動(float)是一個 CSS 屬性,它會導致元素脫離常規流,儘可能遠地向左或者向右移動,直到它挨著其包含盒或者另一個浮動元素的邊緣。當浮動發生時,文字和行內元素會環繞著浮動元素。

正常情況下,如果沒有設定浮動,一個元素的高度會調整以容納其所有的後代元素。當元素被浮動時,就會從流中脫離出來,這意味著容器不會調整其高度以清除它們。

正是這種行為,讓多行文字、標題以及其它元素環繞著浮動內容而流動。但是有時這是有問題的。清除浮動並設立新的塊格式化上下文會導致容器清除其浮動子元素。這種技術允許浮動被用在佈局上,已經成為 Web 開發技術的奠基石很久了。它依然是要知道的重要技術,不過正在逐漸被像 Flexbox 和 Grid 這種更新的佈局技術所替代。

絕對定位

絕對定位的元素是徹底從流中刪除,並且不像浮動元素,它們對周圍的內容沒有影響。

相對定位的容器允許我們用絕對定位來控制後代元素的偏移。

相對定位元素也可以設定偏移,不過這種偏移是相對於父元素的常規位置,而不是另一個相對定位的容器。

CSS 屬性 topbottomleftright 被用於計算盒子的偏移。這些屬性都不是二維偏移,不過都可以相對於其容器的內容盒來定位每個邊。

具有重疊偏移的定位元素可以導致元素佔用同一空間。堆疊上下文用於解決這個問題。

堆疊上下文

堆疊上下文決定渲染到頁面上的東西的順序。你可以把一個堆疊上下文當作一個層。堆疊底部的層先繪製,該堆疊之上更高的元素出現在上面。

在一個絕對或者相對定位元素上設定 z-index 屬性是建立新的堆疊上下文的最常見手段。不過,有很多組成堆疊上下文的其它手段,包括設定透明度(opacity)、轉換(transform)、濾鏡(filter)或者使用 will-change 屬性。

不過,使用這些其它手段的原因並不直觀,並且比開發者的預期相比,這些手段對渲染效能有一定影響。只不過它們有助於理解這些層可以被瀏覽器單獨渲染。因此,有時因為效能的原因,有意建立新的堆疊上下文是很有用的。

除非建立了堆疊上下文,否則設定 z-index 是沒有效果的。z-index 越高,層在堆疊中放在的位置越高。

有關堆疊的最讓人感到困惑的部分之一是,一個新的堆疊上下文可以建立在一個已有的堆疊上下文內。也就是說可以有層中層。

在這種情況下,並非總是最高的 z-index 會放在最上面。

寫在最後

  太久沒有過好好寫部落格了...感覺好多東西彷彿你理解和寫出來完全是兩個不同的概念...慶幸自己憋著氣還是把想寫的內容寫出來了。其實關於CSS,我一直都不認為是一個簡單的樣式表而已。深入去研究,會發現其難度並不比JS的各種理論知識輕鬆。後面我會嘗試去更深入的去分析CSS中的各種屬性,以及認真研究研究grid和flex佈局的優勢。

  完結撒花~

  PS:參考資料:《CSS權威指南(第3版)》

相關推薦

前端學習筆記關於CSS再次整理

如果你在日常工作中使用 CSS,你的主要目標可能會重點圍繞著使事情“看起來正確”。如何實現這一點經常是遠不如最終結果那麼重要。這意味著比起正確的語法和視覺結果來說,我們更少關心 CSS 的工作原理。 CSS 的視覺結果通常是操作隱藏屬性的間接後果,你可能還沒有意識到這一點。某些 CSS 屬性(比如 backg

OpenCV學習筆記方框濾波、均值濾波、高斯濾波

1.平滑處理 平滑處理(smoothing)也稱模糊處理(bluring),是一種簡單且使用頻率很高的影象處理方法。平滑處理的用途有很多,最常見的是用來減少影象上的噪點或者失真。在涉及到影象解析度時,平滑處理是非常好用的方法。 2.影象濾波與濾波器 影象濾波,指儘量保留影象細節特徵的條件

前端學習筆記整理CSS盒模型與基於盒模型的6種元素居中方案

概覽 CSS盒模型,規定了元素框來處理元素的 內容、內邊距、邊框和外邊距的方式 元素部分是指內容部分,也是最實際的內容,包圍內容的稱之為內邊距,內邊距外圍是邊框,邊框外圍就是外邊距;且外邊距是透明的,所以並不會阻擋其後的元素   * {     margin: 0;     padding: 0;   }

前端學習筆記整理HTTP協議以及http與https的區別

前言 還是老樣子,新部落格開始前總是想先囉嗦幾句...HTTP協議其實在當初學習java時老師就有提過...但是...反正就那麼過去了... 這段時間公司的專案正好要求做https的轉換和遷移,然後自己思考了一下,好像自己對於http連一知半解都算不上...更不提http與https的區別...想想作為一個未

前端學習筆記整理CSS視覺格式化模型

1. 概念 在視覺格式化模型中,文件樹中的每個元素都將會根據盒模型產生零到多個盒子。這些盒子的佈局由如下因素決定: 盒子的尺寸和型別 定位策略(正常文件流,浮動或者絕對定位) 和文件樹中其他元素的關係 額外的資訊(比如視口的大小,圖片的原始尺寸等) 1.1 視口(viewport) 連續媒體(contin

前端學習筆記整理rem與px換算的計算方式

前言 這段時間的小專案中算是真正意義上使用了rem來進行移動端的頁面佈局,專案結束了我反思了一下之前的對於rem的使用...原來我以前對rem用法完全是在搞笑啊!!結合這次這個小專案,我覺得我也有必要對rem佈局以及用法進行一次總結。 ps.文筆可能不太好... 1.什麼是rem 來自於鵝廠ISUX團隊的解釋

前端學習筆記整理行內元素與塊級元素的區別以及絕對定位與固定定位的差異

1.簡要說明: 1. 行內元素會再一條直線上,是在同一行的。比如span和strong; 2. 塊級元素各佔一行。是垂直方向的!比如div和p 假如你要將行內元素變成塊級元素,那麼就只需要在該標籤上加上樣式 display:block; 塊級元素可以用樣式控制其高、寬的值,而行內元素不可以。 行內元素和wi

前端學習筆記整理關於JavaScript中的關鍵字——this

寫在前面 工作有那麼一段時間了,但是在工作中,發現自己的理論知識還是有所欠缺。特別是在javascript上,很多東西其實自己屬於知道要用這個,但是不知道為什麼要這麼用...這種情況很是尷尬了,所以寫部落格的很重要一個目的就是鍛鍊我自己的總結能力,把學到的東西總結出來,感覺這樣能讓我更快的去理解所學到的東西。

前端學習筆記整理LESS基礎

第一次接觸CSS預編譯,然後對比後發現其實less的上手容易度確實比sass高不少,再加上公司專案也是使用的less。所以想想還是根據網上的各種教程,整理出來了一些比較基礎的、而且比較能讓我們這種初學者快速上手的例子。 菜雞一隻,程式碼要是有錯或者表達不清的地方,請各位批評指正! 那麼,現在我們就開始正文部分

前端學習筆記整理this關鍵字詳解

 這裡有一個微妙但是非常重要的細節,雖然 this 的繫結規則完全取決於呼叫位置,但是隻有 foo() 執行在非 strict mode 下時,預設繫結才能繫結到全域性物件;嚴格模式下與 foo()的呼叫位置無關: function foo() {      console.log( this.a );

前端學習筆記2017.6.12 CSS控制DIV

banner 成像 個性化 logs 一個 style 切換 back 成了 前一篇文章中用div布局了豆瓣東西的頁面,如果用html代碼表示的話大概是這個樣子的 <!DOCTYPE html><html><head></head

TDD學習筆記一Unit Test - Stub, Mock, Fake 簡介

-i moc load customers eight foreach 存在 執行 repo 這篇文章簡介一下,如何通過 mock framework,來輔助我們更便利地模擬目標對象的依賴對象,而不必手工敲堆只為了這次測試而存在的輔助類型。 而模擬目標對象的部分,常見的有

Docker學習筆記安裝Redis

art port 再次 dock 使用 contain bash Go red 項目中使用到Redis,平常都是別人搭建的,今天試著在Google Cloud Platform 上搭建一個學習環境。 1.使用 docker pull redis 從docker hub中下載

system generator學習筆記01

分享 基本功 hle ima 安裝 分享圖片 use 內容整理 blank 作者:桂。 時間:2018-05-18 18:26:50 鏈接:http://www.cnblogs.com/xingshansi/p/9045914.html 前言 學習使用s

響應式布局學習筆記1----基礎知識

網頁設計 water com 文章 tar 屏幕分辨率 優點 light gin 本篇文章主要解決:什麽是響應式布局?有什麽優點和缺點? 一 什麽是響應式布局? 伊桑·馬科特(Ethan Marcotte)在2010年首先提出了響應式網頁設計(RWD,Responsive

Grunt學習筆記3---- filter詳解

add 行處理 class 一個 特殊 col filter詳解 很多 https 本文主要講配置任務中的filter,包括使用默認fs.Stats方法名和自定義過濾函數。 通過設置filter屬性可以實現一些特殊處理邏輯。例如:要清理某個文件夾下的所有空文件夾,這時使用c

Tomcat學習筆記1--- WEB服務器、JavaEE、Tomcat背景

javascrip http .cn 目的 java log 進行 瀏覽器 靜態資源 本文主要講學習Tomcat需要知道的基礎知識。 一 Web服務器 Web服務器可以解析HTTP協議。當Web服務器接收到一個HTTP請求,會返回一個HTTP響應,例如送回一個HTML頁面。

Python學習筆記Supervisor:使用Supervisor監控Tornado程序

Linux常見應用服務配置模式nginx和supervisor:採用主配置檔案+專案配置檔案 安裝(如果使用pip安裝注意看是否需要指定使用python2版本)   第一步:在Linux中使用apt-get 指令安裝 sudo apt-get install supervisor

Python學習筆記Nginx:Nginx使用與完全解除安裝

 安裝與啟動nginx 第一步:通過指令安裝包 sudo apt  install nginx  sudo apt install nginx   第二步:安裝成功後檢視相關配置檔案 ls /etc/nginx/ 在這裡主要是 conf.d

資料分析---《Python for Data Analysis》學習筆記01

《Python for Data Analysis》一書由Wes Mckinney所著,中文譯名是《利用Python進行資料分析》。這裡記錄一下學習過程,其中有些方法和書中不同,是按自己比較熟悉的方式實現的。   第一個例項:1.usa.gov data from bit.ly &n