層疊樣式表

本課程旨在向您介紹層疊樣式表,這是一項更高階的功能,它建立在CSS 層疊CSS 特異性的基本概念之上。

如果您是 CSS 新手,學習本課程可能會感覺不太相關,而且比課程的其他部分更學術化。但是,瞭解層疊樣式表的基礎知識,以便在您的專案中遇到它們時,將會很有幫助。您使用 CSS 越多,瞭解層疊樣式表以及如何利用其強大功能,就能避免在管理來自不同方、外掛和開發團隊的 CSS 程式碼庫時,遇到很多麻煩。

當您使用來自多個來源的 CSS 時,層疊樣式表最為相關,這時會出現衝突的 CSS 選擇器和競爭的特異性,或者您正在考慮使用!important

先決條件 瞭解 CSS 的工作原理,包括層疊和特異性(學習CSS 初步層疊、特異性以及繼承)。
目標 瞭解層疊樣式表的工作原理。

對於應用於元素的每個 CSS 屬性,只能有一個值。您可以透過在瀏覽器開發者工具中檢查元素來檢視應用於元素的所有屬性值。該工具的“樣式”面板顯示應用於正在檢查的元素的所有屬性值,以及匹配的選擇器和 CSS 原始檔。具有優先順序的來源中的選擇器將其值應用於匹配的元素。

除了應用的樣式外,“樣式”面板還會顯示被劃掉的匹配所選元素但未應用的值,這是由於層疊、特異性或源順序導致的。被劃掉的樣式可能來自具有優先順序的相同來源,但特異性較低,或者具有匹配的來源和特異性,但在程式碼庫中較早找到。對於任何應用的屬性值,可能有多個宣告從許多不同的來源被劃掉。如果您看到一個被劃掉的樣式具有特異性更高的選擇器,則表示該值在來源或重要性方面存在不足。

通常,隨著站點複雜性的增加,樣式表的數量也會增加,這使得樣式表的源順序變得更加重要和複雜。層疊樣式表簡化了跨此類程式碼庫維護樣式表的過程。層疊樣式表是明確的特異性容器,提供更簡單、更強大的對最終應用的 CSS 宣告的控制,使 Web 開發人員能夠優先處理 CSS 部分,而無需與特異性作鬥爭。

要理解層疊樣式表,您必須充分理解 CSS 層疊。以下部分快速回顧了重要的層疊概念。

層疊概念回顧

CSS 中的“C”代表“層疊”。它是樣式層疊在一起的方法。使用者代理會執行幾個明確定義的步驟來確定為每個元素的每個屬性分配的值。我們將在此處簡要列出這些步驟,然後深入探討步驟 4,**層疊樣式表**,這是您來這裡學習的內容

  1. **相關性:**查詢所有具有元素選擇器匹配的宣告塊。
  2. **重要性:**根據規則是普通規則還是重要規則進行排序。重要樣式是設定了!important標誌的樣式。
  3. **來源:**在兩個重要性桶中的每一箇中,按作者、使用者或使用者代理來源對規則進行排序。
  4. **層疊樣式表:**在六個來源重要性桶中的每一箇中,按層疊樣式表排序。普通宣告的層級順序是從建立的第一個層到最後一個層,然後是未分層的普通樣式。重要樣式的順序相反,未分層的重要樣式具有最低優先順序。
  5. **特異性:**對於具有優先順序的來源層中相互競爭的樣式,按特異性對宣告進行排序。
  6. **作用域鄰近性**:當具有優先順序的來源層中的兩個選擇器具有相同的特異性時,作用域規則中距作用域根節點 DOM 層級躍遷次數最少的屬性值獲勝。有關更多詳細資訊和示例,請參閱如何解決@scope衝突

  7. 出現順序:當起源層中兩個具有優先順序的選擇器具有相同的特異性和範圍接近度時,來自最後宣告的選擇器(具有最高特異性)的屬性值獲勝。

對於每個步驟,只有“仍在執行”的宣告才能繼續在下一步中“競爭”。如果只有一個宣告在執行,它將“獲勝”,隨後的步驟將變得毫無意義。

起源和層疊

有三種層疊起源型別:使用者代理樣式表、使用者樣式表和作者樣式表。瀏覽器根據起源和重要性將每個宣告排序到六個起源桶中。層疊有八個級別:六個起源桶、正在過渡的屬性和正在動畫的屬性。優先順序順序從普通的使用者代理樣式(優先順序最低)到當前應用動畫內的樣式,再到重要的使用者代理樣式,最後是正在過渡的樣式(優先順序最高)。

  1. 使用者代理普通樣式
  2. 使用者普通樣式
  3. 作者普通樣式
  4. 正在動畫的樣式
  5. 作者重要樣式
  6. 使用者重要樣式
  7. 使用者代理重要樣式
  8. 正在過渡的樣式

“使用者代理”是瀏覽器。“使用者”是網站訪問者。“作者”是您,即開發者。使用<style>元素直接在元素上宣告的樣式是作者樣式。不包括動畫和過渡樣式,使用者代理普通樣式的優先順序最低;使用者代理重要樣式的優先順序最高。

起源和特異性

對於每個屬性,獲勝的宣告來自根據權重(普通或重要)具有優先順序的起源。暫時忽略層,來自優先順序最高的起源的值將被應用。如果獲勝的起源對某個元素有多個屬性宣告,則會比較這些競爭屬性值的選擇器特異性。不同起源的選擇器之間永遠不會比較特異性。

在下面的示例中,有兩個連結。第一個沒有應用任何作者樣式,因此只應用使用者代理樣式(以及您的個人使用者樣式,如果有)。第二個透過作者樣式設定了text-decorationcolor,即使作者樣式表中的選擇器特異性為0-0-0。作者樣式“獲勝”的原因是,當來自不同起源的樣式發生衝突時,將應用來自具有優先順序的起源的規則,而不管不具有優先順序的起源中的特異性如何。

在撰寫本文時,使用者代理樣式表中“競爭”的選擇器是a:any-link,其特異性權重為0-1-1。雖然這大於作者樣式表中的0-0-0選擇器,但即使您當前使用者代理中的選擇器不同,也不要緊:永遠不會比較來自作者和使用者代理起源的特異性權重。詳細瞭解如何計算特異性權重

起源優先順序始終高於選擇器特異性。如果元素屬性在多個起源中使用普通樣式宣告進行樣式設定,則作者樣式表將始終覆蓋在使用者或使用者代理樣式表中宣告的冗餘普通屬性。如果樣式很重要,則使用者代理樣式表將始終優先於作者和使用者樣式。層疊起源優先順序確保起源之間的特異性衝突永遠不會發生。

在繼續之前,還有一點需要注意:只有當優先順序起源中競爭的宣告具有相同特異性時,出現順序才會變得相關。

層疊樣式表概述

現在我們瞭解了“層疊起源優先順序”,但什麼是“層疊層優先順序”?我們將透過解決什麼是層疊層、它們是如何排序的以及樣式是如何分配給層疊層的來回答這個問題。我們將介紹常規層巢狀層和匿名層。讓我們首先討論什麼是層疊層以及它們解決了哪些問題。

層疊層優先順序順序

與我們根據起源和重要性有六個優先順序級別類似,層疊層使我們能夠在這些起源中的任何一個內建立子起源級別的優先順序。

在六個起源桶中的每一箇中,都可以有多個層疊層。層建立順序非常重要。正是建立順序決定了起源內層之間的優先順序順序。

在普通起源桶中,層按每個層的建立順序排序。優先順序順序是從第一個建立的層到最後一個層,然後是未分層的普通樣式。

對於重要樣式,此順序會反轉。所有未分層的重要樣式會一起層疊到一個隱式層中,該層優先於所有非過渡普通樣式。未分層的重要樣式的優先順序低於任何重要的分層樣式。在相同起源中,較早宣告的層中的重要樣式優先於後續宣告的層中的重要樣式。

在本教程的其餘部分,我們將討論範圍限制在作者樣式,但請記住,層也可以存在於使用者和使用者代理樣式表中。

層疊層可以解決的問題

大型程式碼庫可能來自多個團隊、元件庫、框架和第三方。無論包含多少個樣式表,所有這些樣式都會在一個起源中層疊在一起:作者樣式表。

來自許多來源的樣式層疊在一起,特別是來自不一起工作的團隊的樣式,可能會造成問題。不同的團隊可能具有不同的方法;一個團隊可能將降低特異性作為最佳實踐,而另一個團隊可能將每個選擇器中包含一個id作為標準。

特異性衝突可能迅速升級。Web 開發人員可能會透過新增!important標誌來建立一個“快速修復”。雖然這可能感覺像一個簡單的解決方案,但它通常只是將特異性衝突從普通宣告轉移到重要宣告。

層疊起源在使用者、使用者代理和作者樣式之間提供權力平衡的方式,層疊層也提供了一種結構化的方法來組織和平衡單個起源內的關注點,就好像起源中的每個層都是一個子起源一樣。可以為每個團隊、元件和第三方建立一個層,優先順序基於層順序。

層內的規則層疊在一起,不會與層外的樣式規則競爭。層疊層使能夠優先考慮整個樣式表而不是其他樣式表,而無需擔心這些子起源之間的特異性。

層優先順序始終高於選擇器特異性。具有優先順序的層中的樣式優先於具有較低優先順序的層。失敗層中選擇器的特異性無關緊要。特異性對於層內競爭的屬性值仍然很重要,但層之間沒有特異性問題,因為只考慮每個屬性的最高優先順序層。

巢狀層疊層可以解決的問題

層疊層允許建立巢狀層。每個層疊層都可以包含巢狀層。

例如,可以將元件庫匯入到components層中。常規層疊層會將元件庫新增到作者起源,消除與其他作者樣式之間的任何特異性衝突。在components層中,開發人員可以選擇定義各種主題,每個主題作為一個單獨的巢狀層。這些巢狀主題層的順序可以根據媒體查詢(請參閱下面的層建立和媒體查詢部分)來定義,例如視口大小或方向。這些巢狀層提供了一種建立基於特異性不衝突的主題的方法。

巢狀層的功能對於任何從事元件庫、框架、第三方小部件和主題開發的人員都非常有用。

建立巢狀層的功能還消除了對層名稱衝突的擔憂。我們將在巢狀層部分介紹這一點。

“作者可以建立層來表示元素預設值、第三方庫、主題、元件、覆蓋和其他樣式問題,並且能夠以顯式方式重新排序層的層疊,而無需更改每個層內的選擇器或特異性,或依賴出現順序來解決跨層的衝突。”

——層疊和繼承規範

建立層疊樣式表

可以使用以下任何一種方法建立層

  • 使用@layer語句@規則,宣告使用@layer後跟一個或多個層的名稱的層。這會建立命名層,而不會為其分配任何樣式。
  • @layer塊@規則,其中塊中的所有樣式都新增到命名或未命名的層中。
  • 使用layer關鍵字或layer()函式的@import規則,它將匯入檔案的內容分配到該層。

這三種方法都會建立層,前提是尚未初始化具有該名稱的層。如果在@layer@規則或帶有layer()@import中未提供層名稱,則會建立一個新的匿名(未命名)層。

注意:層的優先順序順序是建立它們的順序。不在層中的樣式或“未分層樣式”會一起層疊到最終的隱式標籤中。

在討論巢狀層之前,讓我們更詳細地介紹建立層的這三種方法。

用於命名層的@layer語句@規則

層的順序由層在 CSS 中出現的順序設定。使用@layer後跟一個或多個層的名稱來宣告層,而無需分配任何樣式,是定義層順序的一種方法。

@layer CSS @規則用於宣告層疊層,並在存在多個層疊層時定義優先順序順序。以下@規則按列表順序聲明瞭三個層

css
@layer theme, layout, utilities;

您通常希望將 CSS 的第一行設定為此@layer宣告(當然,使用對您的站點有意義的層名稱),以便完全控制層排序。

如果上述語句是站點 CSS 的第一行,則層順序將為themelayoututilities。如果在上述語句之前建立了一些層,只要具有這些名稱的層不存在,這三個層就會被建立並新增到現有層列表的末尾。但是,如果已存在具有相同名稱的層,則上述語句將只建立兩個新層。例如,如果layout已存在,則只會建立themeutilities,但在這種情況下,層的順序將為layoutthemeutilities

用於命名層和匿名層的@layer塊@規則

可以使用塊@layer@規則建立層。如果@layer@規則後跟一個識別符號和一個樣式塊,則該識別符號用於命名層,並且此@規則中的樣式將新增到該層的樣式中。如果尚未存在具有指定名稱的層,則會建立一個新層。如果已存在具有指定名稱的層,則樣式將新增到先前存在的層中。如果在使用@layer建立樣式塊時未指定名稱,則@規則中的樣式將新增到一個新的匿名層中。

在下面的示例中,我們使用了四個@layer塊@規則和一個@layer語句@規則。此 CSS 按列出的順序執行以下操作

  1. 建立一個名為layout的層
  2. 建立一個未命名的匿名層
  3. 宣告一個包含三個層的列表,並只建立兩個新層themeutilities,因為layout已存在
  4. 向已存在的layout層新增其他樣式
  5. 建立一個第二個未命名的匿名層
css
/* file: layers1.css */

/* unlayered styles */
body {
  color: #333;
}

/* creates the first layer: `layout` */
@layer layout {
  main {
    display: grid;
  }
}

/* creates the second layer: an unnamed, anonymous layer */
@layer {
  body {
    margin: 0;
  }
}

/* creates the third and fourth layers: `theme` and `utilities` */
@layer theme, layout, utilities;

/* adds styles to the already existing `layout` layer */
@layer layout {
  main {
    color: #000;
  }
}

/* creates the fifth layer: an unnamed, anonymous layer */
@layer {
  body {
    margin: 1vw;
  }
}

在上面的 CSS 中,我們建立了五個層:layout<anonymous(01)>themeutilities<anonymous(02)> - 按此順序 - 以及包含在body樣式塊中的第六個隱式未分層樣式層。層的順序是建立層的順序,未分層樣式的隱式層始終是最後一個。建立後無法更改層順序。

我們將一些樣式分配給了名為layout的層。如果命名層尚不存在,則在@layer@規則中指定名稱(無論是否為層分配樣式),都會建立該層;這會將層新增到現有層名稱序列的末尾。如果命名層已存在,則命名塊中的所有樣式都會附加到先前存在的層中的樣式中 - 透過重用現有層名稱在塊中指定樣式不會建立新層。

匿名層是透過在不命名層的情況下為層分配樣式來建立的。只能在建立匿名層時向未命名層新增樣式。

注意:隨後使用@layer且沒有層名稱會建立其他未命名的層;它不會將樣式附加到先前存在的未命名層。

@layer@規則建立命名或未命名的層,或者如果命名層已存在,則將樣式附加到該層。我們將第一個匿名層稱為<anonymous(01)>,第二個稱為<anonymous(02)>,這僅僅是為了我們能夠解釋它們。這些實際上是未命名的層。無法引用它們或向它們新增其他樣式。

在層之外宣告的所有樣式都合併到一個隱式層中。在上面的示例程式碼中,第一個宣告在body上設定了color: #333屬性。這是在任何層之外宣告的。即使未分層樣式的特異性較低且在出現順序中排在首位,普通未分層宣告也優先於普通分層宣告。這解釋了為什麼即使未分層 CSS 在程式碼塊中首先宣告,包含這些未分層樣式的隱式層也具有優先順序,就像它是最後宣告的層一樣。

@layer theme, layout, utilities;一行中,聲明瞭一系列層,僅建立了themeutilities層;layout已在第一行建立。請注意,此宣告不會更改已建立層的順序。目前,一旦宣告就無法重新排序層。

在以下互動式示例中,我們將樣式分配給兩個層,並在過程中建立並命名它們。因為它們已經存在,所以在第一次使用時被建立,所以在最後一行宣告它們沒有任何作用。

嘗試移動最後一行@layer site, page;,使其成為第一行。會發生什麼?

層建立和媒體查詢

如果使用媒體功能查詢定義層,並且媒體不匹配或不支援該功能,則不會建立該層。下面的示例顯示了更改裝置或瀏覽器的尺寸如何可能更改層順序。在此示例中,我們僅在較寬的瀏覽器中建立site層。然後,我們按順序為pagesite層分配樣式。

在寬螢幕上,site層在第一行宣告,這意味著site的優先順序低於page。否則,site優先於page,因為它在窄螢幕上稍後宣告。如果這不起作用,請嘗試將媒體查詢中的50em更改為10em100em

使用@import將樣式表匯入命名層和匿名層

@import規則允許使用者將樣式規則從其他樣式表直接匯入到 CSS 檔案或<style>元素中。

在匯入樣式表時,@import 語句必須定義在樣式表或 <style> 塊中的任何 CSS 樣式之前。@import 語句必須放在首位,位於任何樣式之前,但可以在其前面使用一個 @layer at-rule 建立一個或多個層,而無需為這些層分配任何樣式。(@import 也可以放在 @charset 規則之前。)

您可以將樣式表匯入到命名層、巢狀命名層或匿名層中。以下層分別將樣式表匯入到 components 層、components 層內的巢狀 dialog 層以及未命名的層中

css
@import url("components-lib.css") layer(components);
@import url("dialog.css") layer(components.dialog);
@import url("marketing.css") layer();

您可以將多個 CSS 檔案匯入到單個層中。以下宣告將兩個單獨的檔案匯入到單個 social 層中

css
@import url(comments.css) layer(social);
@import url(sm-icons.css) layer(social);

您可以使用 媒體查詢特性查詢 根據特定條件匯入樣式並建立層。以下僅當瀏覽器支援 display: ruby 時,才將樣式表匯入到 international 層中,並且正在匯入的檔案取決於螢幕寬度。

css
@import url("ruby-narrow.css") layer(international) supports(display: ruby) and
  (width < 32rem);
@import url("ruby-wide.css") layer(international) supports(display: ruby) and
  (width >= 32rem);

注意: 沒有等效於 <link> 連結樣式表的方法。當您無法在樣式表中使用 @layer 時,請使用 @import 將樣式表匯入到層中。

巢狀層疊樣式表概述

巢狀層是在命名層或匿名層內的層。每個級聯層,即使是匿名層,也可以包含巢狀層。匯入到另一個層中的層成為該層內的巢狀層。

巢狀層的優勢

巢狀層的能力使團隊能夠建立級聯層,而不必擔心其他團隊是否會將其匯入到層中。類似地,巢狀使您可以將第三方樣式表匯入到層中,而不必擔心該樣式表本身是否包含層。因為層可以巢狀,所以您不必擔心外部和內部樣式表之間存在衝突的層名稱。

建立巢狀級聯層

巢狀層可以使用與常規層相同的方法建立。例如,可以使用 @layer at-rule 後跟一個或多個層的名稱,使用點表示法建立。多個點和層名稱表示多個巢狀。

如果將一個塊 @layer at-rule 巢狀在另一個塊 @layer at-rule 內部,無論是否有名稱,巢狀塊都將成為巢狀層。類似地,當使用包含 layer 關鍵字或 layer() 函式的 @import 宣告匯入樣式表時,樣式將被分配到該命名或匿名層。如果 @import 語句包含層,則這些層將成為該匿名或命名層內的巢狀層。

讓我們看下面的例子

css
@import url("components-lib.css") layer(components);
@import url("narrowtheme.css") layer(components.narrow);

在第一行中,我們將 components-lib.css 匯入到 components 層中。如果該檔案包含任何層(命名或未命名),則這些層將成為 components 層內的巢狀層。

第二行將 narrowtheme.css 匯入到 narrow 層中,該層是 components 的子層。巢狀的 components.narrow 將作為 components 層內的最後一個層建立,除非 components-lib.css 已經包含一個 narrow 層,在這種情況下,narrowtheme.css 的內容將附加到 components.narrow 巢狀層。可以使用 components.<layerName> 模式將其他巢狀命名層新增到 components 層。如前所述,可以建立未命名的層,但隨後無法訪問它們。

讓我們看另一個例子,我們 使用以下語句將 layers1.css 匯入到命名層中

css
@import url(layers1.css) layer(example);

這將建立一個名為 example 的單個層,其中包含一些宣告和五個巢狀層 - example.layoutexample.<anonymous(01)>example.themeexample.utilitiesexample.<anonymous(02)>

要向命名巢狀層新增樣式,請使用點表示法

css
@layer example.layout {
  main {
    width: 50vw;
  }
}

根據層級順序確定優先順序

層的順序決定了它們的優先順序順序。因此,層的順序非常重要。與級聯按來源和重要性排序的方式相同,級聯按來源層和重要性對每個 CSS 宣告進行排序。

常規級聯層的優先順序順序

css
@import url(A.css) layer(firstLayer);
@import url(B.css) layer(secondLayer);
@import url(C.css);

以上程式碼建立了兩個命名層(C.css 樣式將附加到未分層樣式的隱式層)。假設這三個檔案(A.cssB.cssC.css)在其內部不包含任何其他層。以下列表顯示了在這些檔案內部和外部宣告的樣式將如何從最低(1)優先順序到最高(10)優先順序進行排序。

  1. firstLayer 普通樣式 (A.css)
  2. secondLayer 普通樣式 (B.css)
  3. 未分層普通樣式 (C.css)
  4. 內聯普通樣式
  5. 動畫樣式
  6. 未分層重要樣式 (C.css)
  7. secondLayer 重要樣式 (B.css)
  8. firstLayer 重要樣式 (A.css)
  9. 內聯重要樣式
  10. 過渡樣式

在層內宣告的普通樣式具有最低優先順序,並按建立層的順序排序。第一個建立的層中的普通樣式具有最低優先順序,而最後一個建立的層中的普通樣式在層中具有最高優先順序。換句話說,如果存在任何衝突,則在 firstLayer 中宣告的普通樣式將被列表中任何後續樣式覆蓋。

接下來是層外宣告的任何樣式。C.css 中的樣式未匯入到層中,並將覆蓋來自 firstLayersecondLayer 的任何衝突樣式。在層外宣告的樣式始終優先於在層內宣告的樣式(重要樣式除外)。

內聯樣式使用 style 屬性 宣告。以這種方式宣告的普通樣式將優先於在未分層和分層樣式表(firstLayer – A.csssecondLayer – B.cssC.css)中找到的普通樣式。

動畫樣式優先於所有普通樣式,包括內聯普通樣式。

重要樣式,即包含 !important 標誌的屬性值,優先於我們列表中之前提到的任何樣式。它們按普通樣式的相反順序排序。在層外宣告的任何重要樣式都比在層內宣告的樣式優先順序低。在層內找到的重要樣式也按層建立順序排序。對於重要樣式,最後建立的層具有最低優先順序,而第一個建立的層在宣告的層中具有最高優先順序。

內聯重要樣式再次優先於在其他地方宣告的重要樣式。

過渡樣式具有最高優先順序。當普通屬性值正在過渡時,它優先於所有其他屬性值宣告,即使是內聯重要樣式;但僅在過渡期間。

在此示例中,最初使用 @layer 語句 at-rule 定義了兩個層(AB),沒有任何樣式。層樣式定義在兩個 @layer 塊 at-rule 中,它們出現在任何層外部宣告的 h1 CSS 規則之後。

使用 style 屬性在 h1 元素上新增的內聯樣式設定了普通 color 和重要 background-color。普通內聯樣式覆蓋所有分層和未分層的普通樣式。重要內聯樣式覆蓋所有分層和未分層的普通和重要作者樣式。作者樣式無法覆蓋重要內聯樣式。

普通 text-decoration 和重要 box-shadow 不是 style 內聯樣式的一部分,因此可以被覆蓋。對於普通非內聯樣式,未分層樣式優先。對於重要樣式,層順序也很重要。雖然未分層普通樣式覆蓋層中設定的所有普通樣式,但對於重要樣式,優先順序順序相反;未分層重要樣式的優先順序低於分層樣式。

僅在層內宣告的兩個樣式是 font-style(具有普通重要性)和 font-weight(具有 !important 標誌)。對於普通樣式,最後宣告的 B 層覆蓋先前宣告的層 A 中的樣式。對於普通樣式,後面的層優先於前面的層。重要樣式的優先順序順序相反。對於重要 font-weight 宣告,第一個宣告的層 A 優先於最後宣告的層 B

您可以透過將第一行從 @layer A, B; 更改為 @layer B, A; 來反轉層順序。試試看。哪些樣式會因此而更改,哪些樣式保持不變?為什麼?

層的順序由層在 CSS 中出現的順序設定。在我們的第一行中,我們使用 @layer 後跟層名稱聲明瞭層,而沒有分配任何樣式,最後以分號結尾。如果我們省略了這一行,結果將相同。為什麼?我們在命名 @layer 塊中按 A 然後 B 的順序分配了樣式規則。這兩個層是在第一行建立的。如果沒有,這些規則塊將按該順序建立它們。

我們包含第一行有兩個原因:首先,以便您可以輕鬆地編輯該行並切換順序;其次,因為您通常會發現預先宣告層順序是層順序管理的最佳實踐。

總結

  • 層的優先順序順序是建立層的順序。
  • 建立後,無法更改層順序。
  • 普通樣式的層優先順序是建立層的順序。
  • 未分層普通樣式優先於分層普通樣式。
  • 重要樣式的層優先順序相反,先建立的層具有優先順序。
  • 所有分層重要樣式都優先於未分層重要(和普通)樣式。
  • 普通內聯樣式優先於所有普通樣式,無論是否分層。
  • 重要內聯樣式優先於所有其他樣式,正在過渡的樣式除外。
  • 作者樣式無法覆蓋重要內聯樣式(過渡除外,過渡是臨時的)。

巢狀級聯層的優先順序順序

巢狀層的級聯優先順序順序類似於常規層的優先順序順序,但包含在層內。優先順序順序基於巢狀層建立的順序。層中的非巢狀樣式優先於巢狀普通樣式,而重要樣式的優先順序順序相反。巢狀層之間的特異性權重無關緊要,儘管對於巢狀層內的衝突樣式,特異性權重很重要。

以下建立並向 components 層、components.narrow 巢狀層和 components.wide 巢狀層新增樣式

css
div {
  background-color: wheat;
  color: pink !important;
}

@layer components {
  div {
    background-color: yellow;
    border: 1rem dashed red;
    color: orange !important;
  }
}

@layer components.narrow {
  div {
    background-color: skyblue;
    border: 1rem dashed blue;
    color: purple !important;
    border-radius: 50%;
  }
}

@layer components.wide {
  div {
    background-color: limegreen;
    border: 1rem dashed green;
    color: seagreen !important;
    border-radius: 20%;
  }
}

以下是使用的屬性以及每個宣告應用的原因的摘要

  • background-color:因為未分層普通樣式優先於分層普通樣式,所以 wheat 顏色獲勝。
  • border:因為在層內,非巢狀樣式優先於普通巢狀樣式,所以 red 顏色獲勝。
  • color:對於重要樣式,分層樣式優先於未分層樣式,並且在先前宣告的層中的重要樣式優先於後續宣告的層中的重要樣式。在此示例中,巢狀層建立的順序是 components.narrow,然後是 components.wide,因此 components.narrow 中的重要樣式優先於 components.wide 中的重要樣式,這意味著 purple 顏色獲勝。
  • border-radius:該屬性僅在巢狀層中設定,因此按宣告順序 20% 半徑獲勝。

測試你的技能!

您已閱讀完本文,但您能記住最重要的資訊嗎?在繼續之前,您可以找到一些進一步的測試來驗證您是否保留了這些資訊——請參閱 測試您的技能:級聯,任務 2

總結

如果您理解了本文的大部分內容,那麼恭喜您——您現在已經熟悉了 CSS 級聯層的根本機制。接下來,我們將詳細瞭解 盒模型