CSS 屬性計算

来源:https://www.cnblogs.com/xw-01/p/18257511
-Advertisement-
Play Games

CSS 屬性計算過程 你是否瞭解 CSS 的屬性計算過程呢? 有的同學可能會講,CSS屬性我倒是知道,例如: p{ color : red; } 上面的 CSS 代碼中,p 是元素選擇器,color 就是其中的一個 CSS 屬性。 但是要說 CSS 屬性的計算過程,還真的不是很清楚。 沒關係,通過此 ...


CSS 屬性計算過程

你是否瞭解 CSS 的屬性計算過程呢?

有的同學可能會講,CSS屬性我倒是知道,例如:

p{
  color : red;
}

上面的 CSS 代碼中,p 是元素選擇器,color 就是其中的一個 CSS 屬性。

但是要說 CSS 屬性的計算過程,還真的不是很清楚。

沒關係,通過此篇文章,能夠讓你徹底明白什麼是 CSS 屬性的計算流程。

image-20220813140434032

首先,不知道你有沒有考慮過這樣的一個問題,假設在 HTML 中有這麼一段代碼:

<body>
  <h1>這是一個h1標題</h1>
</body>

上面的代碼也非常簡單,就是在 body 中有一個 h1 標題而已,該 h1 標題呈現出來的外觀是如下:

image-20220813140724136

目前我們沒有設置該 h1 的任何樣式,但是卻能看到該 h1 有一定的預設樣式,例如有預設的字體大小、預設的顏色。

那麼問題來了,我們這個 h1 元素上面除了有預設字體大小、預設顏色等屬性以外,究竟還有哪些屬性呢?

image-20220815094215982

答案是該元素上面會有 CSS 所有的屬性。你可以打開瀏覽器的開發者面板,選擇【元素】,切換到【計算樣式】,之後勾選【全部顯示】,此時你就能看到在此 h1 上面所有 CSS 屬性對應的值。

image-20220813141516153

換句話說,我們所書寫的任何一個 HTML 元素,實際上都有完整的一整套 CSS 樣式。這一點往往是讓初學者比較意外的,因為我們平時在書寫 CSS 樣式時,往往只會書寫必要的部分,例如前面的:

p{
  color : red;
}

這往往會給我們造成一種錯覺,認為該 p 元素上面就只有 color 屬性。而真實的情況確是,任何一個 HTML 元素,都有一套完整的 CSS 樣式,只不過你沒有書寫的樣式,大概率可能會使用其預設值。例如上圖中 h1 一個樣式都沒有設置,全部都用的預設值。

但是註意,我這裡強調的是“大概率可能”,難道還有我們“沒有設置值,但是不使用預設值”的情況麽?

image-20220815094458940

嗯,確實有的,所以我才強調你要瞭解“CSS 屬性的計算過程”。

總的來講,屬性值的計算過程,分為如下這麼 4 個步驟:

  • 確定聲明值
  • 層疊衝突
  • 使用繼承
  • 使用預設值

確定聲明值

首先第一步,是確定聲明值。所謂聲明值就是作者自己所書寫的 CSS 樣式,例如前面的:

p{
  color : red;
}

這裡我們聲明瞭 p 元素為紅色,那麼就會應用此屬性設置。

當然,除了作者樣式表,一般瀏覽器還會存在“用戶代理樣式表”,簡單來講就是瀏覽器內置了一套樣式表。

image-20220813143500066

在上面的示例中,作者樣式表中設置了 color 屬性,而用戶代理樣式表(瀏覽器提供的樣式表)中設置了諸如 display、margin-block-start、margin-block-end、margin-inline-start、margin-inline-end 等屬性對應的值。

這些值目前來講也沒有什麼衝突,因此最終就會應用這些屬性值。

層疊衝突

在確定聲明值時,可能出現一種情況,那就是聲明的樣式規則發生了衝突。

此時會進入解決層疊衝突的流程。而這一步又可以細分為下麵這三個步驟:

  • 比較源的重要性
  • 比較優先順序
  • 比較次序

來來來,我們一步一步來看。

比較源的重要性

當不同的 CSS 樣式來源擁有相同的聲明時,此時就會根據樣式表來源的重要性來確定應用哪一條樣式規則。

那麼問題來了,咱們的樣式表的源究竟有幾種呢?

image-20220823180047075

整體來講有三種來源:

  • 瀏覽器會有一個基本的樣式表來給任何網頁設置預設樣式。這些樣式統稱用戶代理樣式
  • 網頁的作者可以定義文檔的樣式,這是最常見的樣式表,稱之為頁面作者樣式
  • 瀏覽器的用戶,可以使用自定義樣式表定製使用體驗,稱之為用戶樣式

對應的重要性順序依次為:頁面作者樣式 > 用戶樣式 > 用戶代理樣式

更詳細的來源重要性比較,可以參閱 MDNhttps://developer.mozilla.org/zh-CN/docs/Web/CSS/Cascade

我們來看一個示例。

例如現在有頁面作者樣式表用戶代理樣式表中存在屬性的衝突,那麼會以作者樣式表優先。

p{
  color : red;
  display: inline-block;
}

image-20220813144222152

可以明顯的看到,作者樣式表和用戶代理樣式表中同時存在的 display 屬性的設置,最終作者樣式表幹掉了用戶代理樣式表中衝突的屬性。這就是第一步,根據不同源的重要性來決定應用哪一個源的樣式。

比較優先順序

那麼接下來,如果是在在同一個源中有樣式聲明衝突怎麼辦呢?此時就會進行樣式聲明的優先順序比較。

例如:

<div class="test">
  <h1>test</h1>
</div>
.test h1{
  font-size: 50px;
}

h1 {
  font-size: 20px;
}

在上面的代碼中,同屬於頁面作者樣式,源的重要性是相同的,此時會以選擇器的權重來比較重要性。

很明顯,上面的選擇器的權重要大於下麵的選擇器,因此最終標題呈現為 50px

image-20210916151546500

可以看到,落敗的作者樣式在 Elements>Styles 中會被劃掉。

有關選擇器權重的計算方式,不清楚的同學,可以進入此傳送門:https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

比較次序

經歷了上面兩個步驟,大多數的樣式聲明能夠被確定下來。但是還剩下最後一種情況,那就是樣式聲明既是同源,權重也相同。

此時就會進入第三個步驟,比較樣式聲明的次序。

舉個例子:

h1 {
  font-size: 50px;
}

h1 {
  font-size: 20px;
}

在上面的代碼中,同樣都是頁面作者樣式選擇器的權重也相同,此時位於下麵的樣式聲明會層疊掉上面的那一條樣式聲明,最終會應用 20px 這一條屬性值。

image-20220823183928330

至此,樣式聲明中存在衝突的所有情況,就全部被解決了。

使用繼承

層疊衝突這一步完成後,解決了相同元素被聲明瞭多條樣式規則究竟應用哪一條樣式規則的問題。

那麼如果沒有聲明的屬性呢?此時就使用預設值麽?

No、No、No,別急,此時還有第三個步驟,那就是使用繼承而來的值。

例如:

<div>
  <p>Lorem ipsum dolor sit amet.</p>
</div>
div {
  color: red;
}

在上面的代碼中,我們針對 div 設置了 color 屬性值為紅色,而針對 p 元素我們沒有聲明任何的屬性,但是由於 color 是可以繼承的,因此 p 元素從最近的 div 身上繼承到了 color 屬性的值。

image-20220813145102293

這裡有兩個點需要同學們註意一下。

首先第一個是我強調了是最近的 div 元素,看下麵的例子:

<div class="test">
  <div>
    <p>Lorem ipsum dolor sit amet.</p>
  </div>
</div>
div {
  color: red;
}
.test{
  color: blue;
}

image-20220813145652726

因為這裡並不涉及到選中 p 元素聲明 color 值,而是從父元素上面繼承到 color 對應的值,因此這裡是誰近就聽誰的,初學者往往會產生混淆,又去比較權重,但是這裡根本不會涉及到權重比較,因為壓根兒就沒有選中到 p 元素。

第二個就是哪些屬性能夠繼承?

關於這一點的話,大家可以在 MDN 上面很輕鬆的查閱到。例如我們以 text-align 為例,如下圖所示:

image-20220813150147885

使用預設值

好了,目前走到這一步,如果屬性值都還不能確定下來,那麼就只能是使用預設值了。

如下圖所示:

image-20220813150824752

前面我們也說過,一個 HTML 元素要在瀏覽器中渲染出來,必須具備所有的 CSS 屬性值,但是絕大部分我們是不會去設置的,用戶代理樣式表裡面也不會去設置,也無法從繼承拿到,因此最終都是用預設值。

好了,這就是關於 CSS 屬性計算過程的所有知識了。

image-20220814234654914

一道面試題

好了,學習了今天的內容,讓我來用一道面試題測試測試大家的理解程度。

下麵的代碼,最終渲染出來的效果,a 元素是什麼顏色?p 元素又是什麼顏色?

<div>
  <a href="">test</a>
  <p>test</p>
</div>
div {
  color: red;
}

大家能說出為什麼會呈現這樣的結果麽?

解答如下:

image-20220813151941113

實際上原因很簡單,因為 a 元素在用戶代理樣式表中已經設置了 color 屬性對應的值,因此會應用此聲明值。而在 p 元素中無論是作者樣式表還是用戶代理樣式表,都沒有對此屬性進行聲明,然而由於 color 屬性是可以繼承的,因此最終 p 元素的 color 屬性值通過繼承來自於父元素。

你答對了麽?-)


-EOF-


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近需要做一個三維場景切換的功能,切換場景後,還可以進行二三維模式的切換,二三維切換時,要定位到當前場景視角,那麼場景的視角參數信息就需要保存到狀態數據中,以供二三維場景切換時使用。 項目是用vue做的,這裡並沒有使用vue的狀態管理庫,我是這樣實現的: 定義狀態數據sceneInfo let sc ...
  • 你習慣在js代碼中使用async await嗎? 我經常在js代碼中寫一些非同步方法,使用await調用的地方,如果方便修改成非同步方法,就修改成非同步方法,如下所示: async setPosition(graphic, lng, lat) { this.lng = lng; this.lat = la ...
  • 你不知道的 CSS 之包含塊 一說到 CSS 盒模型,這是很多小伙伴耳熟能詳的知識,甚至有的小伙伴還能說出 border-box 和 content-box 這兩種盒模型的區別。 但是一說到 CSS 包含塊,有的小伙伴就懵圈了,什麼是包含塊?好像從來沒有聽說過這玩意兒。 好吧,如果你對包含塊的知識一 ...
  • 作為一名前端開發者,vscode想必大家應該都接觸過,就像大多數 IDE 一樣,VSCode 也有一個擴展和主題市場,包含了數以千計質量不同的插件。 作為一名熟練掌握各種前端開發工具安裝和卸載的大師兄來說,為大家安利好玩有用的工具插件是我義不容辭的責任,所以我精挑細選了九款必備的vscode插件 C ...
  • ‍ 寫在開頭 點贊 + 收藏 學會 需求背景 從第三方採購的vue2 + ElementUI實現的雲管平臺,乙方說2011年左右就開始有這個項目了(那時候有Vue了嗎,思考.jpg)。十幾年的項目,我何德何能可以擔此責任。裡面的代碼經過多人多年迭代可以用慘不忍睹來形容,吐槽歸吐槽 ...
  • 摘要:本文深入探討了Nuxt 3的組件開發與管理,從基礎概念、安裝配置、目錄結構、組件分類與開發實踐、生命周期與優化,到測試與維護策略。詳細介紹了Nuxt 3的核心特點,如伺服器端渲染(SSR)、靜態站點生成(SSG)以及與Vue生態系統的無縫集成。文章以Nuxt 3為基礎,指導開發者如何高效構建高... ...
  • 問題分析 當我們需要用摺疊面板的時候,往往會考慮element-ui的el-collaspe,然而大多數時候原生預設的樣式並無法拿來就用。我們往往會自定義組件的樣式,或者在預設的基礎上進行修改。最近在Vue項目中進行組件修改的時候,無意間某個文件自動設置成了scoped(應該是插件自動化生成的結構代 ...
  • 前言 眾所周知,在vue2的時候使用一個vue組件要麼全局註冊,要麼局部註冊。但是在setup語法糖中直接將組件import導入無需註冊就可以使用,你知道這是為什麼呢?註:本文中使用的vue版本為3.4.19。 關註公眾號:【前端歐陽】,給自己一個進階vue的機會 看個demo 我們先來看個簡單的d ...
一周排行
    -Advertisement-
    Play Games
  • 問題 有很多應用程式在驗證JSON數據的時候用到了JSON Schema。 在微服務架構下,有時候各個微服務由於各種歷史原因,它們所生成的數據對JSON Object屬性名的大小寫規則可能並不統一,它們需要消費的JSON數據的屬性名可能需要大小寫無關。 遺憾的是,目前的JSON Schema沒有這方 ...
  • 首先下載centos07鏡像,建議使用阿裡雲推薦的地址: https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/?spm=a2c6h.25603864.0.0.59b5f5ad5Nfr0X 其實這裡就已經出現第一個坑了 centos 07 /u ...
  • 相信很多.NETer看了標題,都會忍不住好奇,點進來看看,並且順便準備要噴作者! 這裡,首先要申明一下,作者本人也非常喜歡Linq,也在各個項目中常用Linq。 我愛Linq,Linq優雅萬歲!!!(PS:順便吐槽一下,隔壁Java從8.0版本推出的Streams API,抄了個四不像,一點都不優雅 ...
  • 在人生的重要時刻,我站在了畢業的門檻上,望著前方的道路,心中涌動著對未來的無限憧憬與些許忐忑。面前,兩條道路蜿蜒伸展:一是繼續在職場中尋求穩定,一是勇敢地走出一條屬於自己的創新之路。儘管面臨年齡和現實的挑戰,我仍舊選擇勇往直前,用技術這把鑰匙,開啟新的人生篇章。 迴首過去,我深知時間寶貴,精力有限。 ...
  • 單元測試 前言 時隔多個月,終於抽空學習了點新知識,那麼這次來記錄一下C#怎麼進行單元測試,單元測試是做什麼的。 我相信大部分剛畢業的都很疑惑單元測試是乾什麼的?在小廠實習了6個月後,我發現每天除了寫CRUD就是寫CRUD,幾乎用不到單元測試。寫完一個功能直接上手去測,當然這隻是我個人感受,僅供參考 ...
  • 一:背景 1. 講故事 最近在分析dump時,發現有程式的卡死和WeakReference有關,在以前只知道怎麼用,但不清楚底層邏輯走向是什麼樣的,藉著這個dump的契機來簡單研究下。 二:弱引用的玩法 1. 一些基礎概念 用過WeakReference的朋友都知道這裡面又可以分為弱短和弱長兩個概念 ...
  • 最近想把ET打表工具的報錯提示直接調用win系統彈窗,好讓策劃明顯的知道表格哪裡填錯數據,彈窗需要調用System.Windows.Forms庫。操作如下: 需要在 .csproj 文件中添加: <UseWindowsForms>true</UseWindowsForms> 須將目標平臺設置為 Wi ...
  • 從C#3開始,拓展方法這一特性就得到了廣泛的應用。 此功能允許你能夠使用實例方法的語法調用某個靜態方法,以下是一個獲取/創建文件的靜態方法: public static async Task<StorageFile> GetOrCreateFileAsync(this StorageFolder f ...
  • 在Windows 11下,使用WinUI2.6以上版本的ListView長這樣: 然而到了Win10上,儘管其他控制項的樣式沒有改變,但ListViewItem變成了預設樣式(初代Fluent) 最重大的問題是,Win10上的HorizontalAlignment未被設置成Stretch,可能造成嚴重 ...
  • 前言 周六在公司加班,幹完活後越顯無聊,想著下載RabbiitMQ做個小項目玩玩。然而這一下就下載了2個小時,真讓人頭痛。 簡單的講一下如何安裝吧,網上教程和踩坑文章還是很多的,我講我感覺有用的文章放在本文末尾。 安裝地址 erlang 下載 - Erlang/OTP https://www.erl ...