所以這絕對不是英文教學 請大家放心
不知道大家有沒有這種困擾
隨著專案越來越大,CSS 也越寫越多 ( 這個是廢話 )
在這時候,好的設計師會想辦法統一模組
並套用相同樣式
但相同的模組總還是會有幾個需跟其他長不同
而這時該怎麼辦呢?
有兩種解決辦法
- 將不同的模組,在定義時加入前層物件的 class 或 id 名稱
- 定一套全新的樣式
這兩種做法其實我覺得是種演進過程
原本寫 CSS 最大的目的就是要共用樣式
能共用當然最好,實在越差越多時就該分第二套樣式出來
因此我們先在定義時加入前一層物件的 class 或 id 名稱 (也就是方法 1)
假設是這樣
<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)
我們來看看實際運作情況:http://jsfiddle.net/culaido/Hqn95/
好,這下問題來了
上面的範例都是以 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>
實際結果: http://jsfiddle.net/culaido/zXVuH/
在這個範例可以發現
第三個 <div> 的樣式定義會有三個衝突
分別是
- #id1 .c1
- .c2 .c1
- .c1
但文字是藍色 (#00f)
也就代表 #id1 .c1 覆蓋了 .c2 .c1 和 .c1
但為甚麼他有這種特權呢?
原來這在 W3C 官方文件中
定義了各個選擇器的權重,在發生樣式衝突時
便以各個權重求出的結果決定最後的樣式
文件低家啦:Calculating a selector's specificity (一樣別問我英文在寫啥 = =)
http://www.w3.org/TR/CSS2/cascade.html#specificity
權重的計算方法:style > #id > .class > *
這樣寫大家肯定看不懂
我們來各別講解他們的意義
- a: style:將樣式用 style 的方式直接寫在標籤中 (也有人稱行內選擇器)
- b: #id:id 選擇器
- c: .class:樣式選擇器
- d: *:直接以標籤、偽元素或 * 的樣式
舉例來看看
<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 開始往下比
只要前面贏了就不需比下去
樣式便套用贏的那方
也有人用得分來解釋
- a 代表 1000 分
- b 代表 100 分
- c 代表 10 分
- d 代表 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>
得分都一樣時
就會以寫在後面的樣式覆蓋掉前面的
所以答案是 綠色 color:#0f0
上面實際的結果: http://jsfiddle.net/culaido/UN6NZ/
大家有猜對嗎?
寫到這裡時我開始懷念我以前的英文老師
雖然學的不好,但有一句話記得很清楚
"凡有規則,就必有例外"
的確,在 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>
剛剛的範例字就變成紅色
實際範例:http://jsfiddle.net/culaido/2tpSj/
這邊是題外話
雖然 !important 可以超越一切
但實際寫的時候能不用就最好最好不要依靠它
因為如果寫的太氾濫
大家都不想自己的屬性被覆蓋,就變成每個都要寫 !important
就變成沒寫一樣 維護會很頭大
=============== 我是英文不好分隔線 ===============
這期的文字多了些 感謝大家耐心的看完
並敬請期待下期的 CSS Storia:inline-block 來一個殺一個 來兩個殺一對
(中華隊 GG 了 T.T)
沒有留言:
張貼留言