ABC 狗咬豬,CSS 也有 ABCD
164 views,
03-22,
 0
事實上我英文很差
所以這篇絕不是要說英文的,請大家放心

不知道大家有沒有這種困擾
隨著專案越來越大,CSS 也就越寫越多 (廢話 = =)
在這時候,好的設計師會開始統一元件的樣式
並在各頁面中套用

但相同的元件總會有幾個需要跟其他頁面長不一樣
而這時候該怎麼辦呢?

這時候,會有這兩種做法
  1. 將這些長不同的樣式,在定義時加入前層物件的 class 或 id 名稱
  2. 定一套新的樣式
這兩種做法其實我覺得是種演進的過程
寫 CSS 最大的目的就是要共用樣式,樣式能共用當然最好
因此一開始應先將長不同的物件樣式
在定義時加入前一層物件的 class 或 id 名稱 (也就是方法 2)
但可能實在越差越多 就該分第二個樣式出來
<style>
    .c1  {color:#f00; ...}
    .c2 .c1 {color:#0f0;} /* 在 .c2 裡面的 .c1 */
</style>
<div class='c1'>I'm c1</div>
<div class='c2'><div class='c1'>Inside c2</div></div>
字體顏色 在第二個 Div 中的結果是綠色 (#0f0)
我們來看看實際運作情況
好,這下問題來了
話說問題有一就會有二
上面的範例都是以 class 來定義
如果是 id 呢?
<style>
    .c1  {color:#f00; ...}
    .c2 .c1 {color:#0f0;}
    #id1 .c1{color:#00f;}
</style>
<div class='c1'>I'm c1</div>
<div class='c2'><div class='c1'>Inside c2</div></div>
<div id='id1' class='c2'><div class='c1'>Inside id1</div></div>
在這個範例我們可以發現
第三個 Div 的樣式定義有三個衝突
分別是
  1. #id1 .c1
  2. .c2 .c1
  3. .c1

但文字是 藍色的 (#00f)
也就代表 #id1 .c1 覆蓋了 .c2 .c1 和 .c1
但為甚麼他有這種特權呢?
原來在 W3C 官方文件中
定義了各個選擇器的權重
在發生衝突時,便以各個權重求出的結果
來決定最後的樣式
文件在這邊:Calculating a selector's specificity (一樣別問我英文在寫啥 = =)
總之漏漏長的文件要告訴我們的就是
權重的規則就是
style > #id > .class > *
我們來各別講解他們的意義
  1. style:將樣式用 style 的方式直接寫在標籤中,有人稱這行內選擇器
  2. #id:id 選擇器
  3. .class:樣式選擇器
  4. *:直接以標籤、偽元素或 * 的樣式
舉幾個範例來看看
<style>
    .class             {...}   /* a=0, b=0, c=1, d=0 */
    #id .class         {...}   /* a=0, b=1, c=1, d=0 */
    #id .class .class2 {...}   /* a=0, b=1, c=2, d=0 */
    .class div         {...}   /* a=0, b=0, c=1, d=1 */
</style>
這些範例比較簡單
如果看得懂 就可以嘗試挑戰 W3C 官方的範例
( 意思是:沒人把 CSS 寫這麼麻煩 你把範例搞這麼難做啥 = = )

樣式套用發生衝突時
就從 a 開始往下比
只要前面贏了就不需比下去
樣式便套用贏的那方

也有人用得分來解釋
  1. 代表 1000 分
  2. 代表 100 分
  3. 代表 10 分
  4. 代表 1 分

只要總合分數高的就贏了 ( 這兩種法都可以 )

以剛剛的範例來看

<style>
    .class             {color:#f00}   /* a=0, b=0, c=1, d=0 */
    #id .class         {color:#0f0}   /* a=0, b=1, c=1, d=0 */
    #id .class .class2 {color:#00f}   /* a=0, b=1, c=2, d=0 */
    .class div         {color:#ff0}   /* a=0, b=0, c=1, d=1 */
</style>
<div class='class'>
    .class {color:#f00}   /* a=0, b=0, c=1, d=0 */ 
    <div>
        .class div {color:#ff0}   /* a=0, b=0, c=1, d=1 */
    </div>
</div>
<div id="id">
    <div class='class'>
	#id .class {color:#0f0}   /* a=0, b=1, c=1, d=0 */
    </div>
    <div class='class'>
	<div class='class2'>
		#id .class .class2 {color:#00f}   /* a=0, b=1, c=2, d=0 */
	</div>
    </div>
</div>
上面實際的結果 http://jsfiddle.net/culaido/eaRdF/
所以大家就知道樣式發生衝突時
該要看誰的了吧

但如果好死不死
兩個得分相同怎麼辦?

<style>
    #id .class1 {color:#f00}  /* a=0, b=1, c=1, d=0 */
    #id .class2 {color:#0f0}  /* a=0, b=1, c=1, d=0 */
</style>
<div id='id'>
    <div class='class1 class2'>
        我的顏色是甚麼呢?
    </div>
</div>

上面實際的結果 http://jsfiddle.net/culaido/UN6NZ/

得分都一樣時
就會以寫在後面的樣式覆蓋掉前面的
所以答案是 綠色 color:#0f0


=============== 我是英文不好分隔線 ===============

寫到這裡時我開始懷念我以前的英文老師
雖然學的不好,但有一句話記得很清楚
"凡有規則就必有例外"

的確
6.4.2 !important rules 節中
還有一個 !important 規則 ( 潛規則 喔 ㄎㄎ )

只要屬性帶有 !important
則不管剛剛那些阿雜的計算問題
直接套用加入 !important 的屬性
驚歎號不是 NOT
<style>
    #id .class1 {color:#f00 !important}  /* a=0, b=1, c=1, d=0 */
    #id .class2 {color:#0f0}  /* a=0, b=1, c=1, d=0 */
</style>
<div id='id'>
    <div class='class1 class2'>
        我的顏色是甚麼呢?
    </div>
</div>

剛剛的範例字就變成紅色的了
雖然 !important 可以超越一切
但實際在寫的時候最好不要依靠它

因為如果寫的太氾濫 其實跟沒寫意思一樣
維護會很頭大

這期的文字多了些 感謝大家耐心的看完
並敬請期待下期的 CSS 的故事: inline-block 來一個殺一個 來兩個殺一對

(中華隊 GG 了 T.T)
留言
訪客如要回應,請先以 Camdemy、facebook 或 google+ 帳號 登入