【转】刨根究底CSS(2):CSS中的各种值——初始值,就是默认值吗?
先問個非常簡單的問題,這個問題的答案,相信大部分Web開發人員都自認為顯而易見,但卻又多半會答錯:CSS屬性中的初始值(initial value),就是默認值(default value)嗎?
難道不對嗎?請往下看。
默認值
默認值(default value)指的是沒有顯式地為CSS屬性聲明一個值的情況下,所默認使用的隱式缺省值。
注:?這里所說的默認值,并非各個瀏覽器自帶的CSS默認值,為避免混淆,下面稱瀏覽器默認值為瀏覽器自帶值。CSS規范中并未顯式地明確定義默認值的概念,但根據對CSS規范的理解,可認為其隱式地定義了默認值,如下:
- 對于非繼承屬性(CSS屬性一覽表[1]中inherited為no的屬性),默認值為初始值initial;
- 對于繼承屬性(CSS屬性一覽表中inherited為yes的屬性):
判斷一個屬性是不是繼承屬性,除了查詢W3C官網上的CSS屬性一覽表,還有沒有相對快捷的方法呢?
有的,大致上來說:
- 跟文本、聲音等與內容相關的屬性,比如font、color、text-align、line-height、white-space、speak、voice-family、volume等屬性,都是可繼承屬性;
- 跟框模型、定位等與布局相關的屬性,比如background、border、display、float、height、left、overflow、vertical-align、z-index等屬性,都是非繼承屬性。
初始值
在W3C CSS規范的每個CSS屬性定義表中,已經給出了屬性的初始值(initial value),如下圖所示。
初始值對于繼承屬性和非繼承屬性[2],有著不同的含義:
- 對于繼承屬性,初始值只能被用于沒有指定值的根元素上;
- 對于非繼承屬性,初始值可以被用于沒有指定值的任意元素上。
在CSS 3中,允許使用initial關鍵詞明確地設定初始值,也就是說,關鍵詞initial代表初始值,不過目前各瀏覽器對關鍵詞initial的支持情況較差,可通過http://caniuse.com查看具體的支持情況。
繼承值
每個CSS屬性定義表中,都指出了這個屬性是默認繼承的("Inherited: Yes"),還是默認不繼承的("Inherited: no")(可參看W3C的CSS屬性全表Full property table[3])。
繼承值(inherit value)決定了當沒有為元素的屬性手動設置其值時該如何確定其值。
當元素的一個繼承屬性?沒有手動設置其值時,則取父元素相同屬性的計算值computed value[4],該值即為繼承值。
注意,子元素不直接繼承為其父元素所指定的相對數值,而是繼承其父元素經過計算之后的數值——計算值,可能是絕對數值,也可能仍然還是相對數值,詳見下文對計算值的介紹。
比如,在以下規則中,如果"h1"是"body"元素的子級,則"h1"元素所繼承的"text-indent"屬性值將為36px,而不是3em,因此最終其值不會是45px:
body {font-size: 12px;text-indent: 3em; /* 計算值為36px */}h1 { font-size: 15px; }下面的示例中,P元素的子元素繼承的"line-height"的值為12px,而不是百分比值(120%):
p {font-size: 10px;line-height: 120%; }但文檔根元素由于沒有父元素,如果在根元素上為某個CSS屬性設置了inherit值,則會取該屬性在CSS規范中所定義的初始值[5](但如果設置了瀏覽器自帶值,則取瀏覽器自帶值)。
聲明值
為每個屬性顯式地聲明的值(或者說設置的值),稱之為聲明值(declared value),或稱之為設置值。
聲明值可能是程序員手動顯式聲明的值(包括內聯樣式、外部樣式、行間樣式中所聲明的值),也可能是瀏覽器顯式設置的瀏覽器自帶值。
聲明值是相對于默認值而言的,如果一個CSS屬性在各級樣式(包括瀏覽器自帶樣式、內聯樣式、外部樣式、行間樣式)中都沒有顯式的聲明值,則使用隱式的默認值。
層疊值
層疊值(cascaded value),也譯作級聯值,指的是對多個來源的各級樣式(包括瀏覽器自帶樣式、瀏覽器用戶自定義樣式、內聯樣式、外部樣式、行間樣式)的默認值或聲明值進行層層疊加計算后的結果值。
該結果值是參與層疊計算的樣式值中符合層疊計算規則的優先級最高的值,要么是某級樣式中的一個默認值,要么是某級樣式中的一個聲明值。
這也就是“CSS層疊樣式表”這個名稱的來源。
因此,層疊值的計算相當于各級樣式優先級的計算,最后以優先級最高的為準。
層疊值的計算,涉及到樣式的來源origin、重要性important、特殊性specificity,需遵循CSS層疊規則。
一個元素某個CSS屬性的層疊值,在按層疊計算規則計算之后,如果該屬性最終有“勝出的”聲明值,則該值為層疊值。
層疊計算規則比較復雜,后面將專文進行介紹。
指定值
CSS屬性的指定值(specified value)通過以下途徑獲取:
- 如果當前文檔的各級樣式層疊后的層疊值不是空值,則該層疊值為指定值。例如:各級樣式層疊計算后,color屬性的值為green,則green為color屬性的指定值;
- 否則,如果層疊值是空值,則以該屬性的默認值作為指定值。具體而言:
這樣,指定值就保證了為每個元素的每個CSS屬性都一定指定了一個值。
計算值
一個CSS屬性的計算值(computed value)通過以下方式獲得:
- 處理特殊的值:inherit、initial、unset和revert;以及
- 進行計算,以達到屬性定義表中“計算值Computed Value”所描述的值。
達到屬性"計算值"所需的計算,通常涉及到相對計算,也就是將相對比值(如em單位或百分比值)轉換成絕對數值的計算過程。
例如,一個元素具有聲明值為:font-size: 16px和padding-top: 2em,則padding-top的計算值為32px(字體大小的2倍)。
然而,有些屬性的百分比值會轉換成百分比的計算值,也就是說,計算后還是百分比值,因此仍然是相對比值,而不是絕對數值,因為這些元素的百分比值是相對于需要布局后才能知道的值,如width、margin-right、text-indent和top等。
另外,line-height屬性值如果是不帶單位的數字值(這屬于相對比值),則該值就是其計算值。
這些計算值中的相對比值會在使用值(used value)確定后再被轉換成絕對數值。
計算值通常是為了在繼承的準備過程中對屬性值盡可能進行絕對化。當然,也只是盡可能而已,如上所述,計算值仍然有可能是相對比值,而不是絕對數值。
注意:?由于歷史原因,CSS 2.1之后,計算值不一定是[Window.getComputedStyle()](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/getComputedStyle?"Window.getComputedStyle( "Window.getComputedStyle()")") 函數返回的值,所以該函數所返回的值被稱之為“解析值”(詳見下文解釋),而不是“計算值”,雖然有時候返回的值確實就是計算值。使用值
CSS屬性的使用值(used value)是在取得計算值,并完成剩余計算(如果有的話)后的結果值。
使用值一定是絕對數值,這一點與計算值仍然有可能是相對比值是不同的。
相對于下面要提到的實際值(actual value)而言,使用值是文檔布局中所使用的理論值。
如果一個屬性不適用于某個元素,則該元素沒有這個屬性的使用值(但其計算值很可能仍然是存在的,只是會被忽略)。比如,flex屬性在非flex項目的元素上沒有使用值。
計算出CSS屬性的使用值,有如下三個步驟:
這些計算步驟是在內部完成的,JavaScript腳本只能使用Window.getComputedStyle()獲得最終計算后的使用值(通過Window.getComputedStyle()獲得的值,還有可能是計算值,具體請看下文對解析值resolved value的解釋)。
使用值示例
- 沒有設置明確的寬度,則寬度的指定值為auto(默認),計算值為auto,使用值為998px (舉例而言);
- 設置了明確的寬度為50%,則寬度的指定值為50%,計算值為50%,使用值為447px;
- 設置了明確的寬度為inherit,則寬度的指定值為50%(舉例而言),計算值為50%,使用值為221px。
使用值與計算值的區別
CSS 2.0只定義了計算值作為屬性計算的最后一步。CSS 2.1引進了定義明顯不同的使用值,這樣當父元素的計算值為百分比值時,比如上述示例中的寬度值,子元素仍然可以顯式地繼承該值。
對于不依賴于布局的CSS屬性(例如display、font-size、line-height),其計算值與使用值一樣,否則就會不一樣。
解析值
CSS屬性的解析值(resolved value)是Window.getComputedStyle()返回的值。
對于大多數屬性,解析值等于其計算值,但對于一些舊屬性,比如width、height等,它等于其使用值。
實際值
一個CSS屬性的實際值(actual value),是使用值(used value)被使用后的近似值。
例如,瀏覽器可能只能渲染一個整數像素值的邊框,而該整數像素值(實際值)可能是一個小數值(使用值)被強制四舍五入取整之后的近似結果值。
下表為W3C CSS規范[6]上的示例(表中的Winning declaration為層疊計算后最終“勝出的”屬性聲明值):
參考資料
[1] CSS屬性一覽表:?https://www.w3.org/TR/CSS21/propidx.html
[2] 繼承屬性和非繼承屬性:?https://developer.mozilla.org/en-US/docs/CSS/inheritance
[3] CSS屬性全表:?https://www.w3.org/TR/CSS21/propidx.html
[4] 計算值:?https://developer.mozilla.org/en-US/docs/CSS/computed_value
[5] 初始值:?https://developer.mozilla.org/en-US/docs/CSS/initial_value
[6] W3C CSS 規范:?https://www.w3.org/TR/css-cascade-3/#stages-examples
總結
以上是生活随笔為你收集整理的【转】刨根究底CSS(2):CSS中的各种值——初始值,就是默认值吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017以卡办卡可以在网上申请吗
- 下一篇: 【转】C#实现SM3国密加密