close
文章出處

  記得大學時候,專業課的網頁設計書籍里面講過css選擇器權重的計算:id是100,class是10,html標簽是5等等,然后全部加起來的和進行比較。。。
  我只想說:真是誤人子弟,害人不淺!

  最近,在前端群里還發現以上觀點類似的奇葩聊天,真是***

  其實,也是在很久以前,看了騰訊ISUX的一位前端工程師-麥時分享的一篇技術文章(個人站點已失效,就不貼出來了),才了解到真正的css選擇器權重計算。

  以下是css選擇器權重計算精華所在,翻譯自國外的文檔(記得是W3C給出的計算規則)


  如果一個聲明來自style屬性而不是選擇器,計作1或者a=1(在一個html文檔中,元素“style”的值是樣式表規則,這個規則中沒有選擇器,所以a=1, b=0, c=0, and d=0)
  選擇器中id屬性的個數,計作b
  選擇器中其他屬性以及偽類的個數計作c
  選擇器中元素及偽元素的個數計作d
  優先級只基與選擇器的形式,特殊的,一個“[id=p33]“形式的選擇器是按照屬性選擇器來計算的(a=0, b=0, c=1, d=0),即使用定義中包含ID
  一些例子:  

 1 * {}     /* a=0 b=0 c=0 d=0 -> 優先級= 0,0,0,0 */
 2 li {}     /* a=0 b=0 c=0 d=1 -> 優先級 = 0,0,0,1 */
 3 li:first-line {}     /* a=0 b=0 c=0 d=2 -> 優先級 = 0,0,0,2 */
 4 ul li {}     /* a=0 b=0 c=0 d=2 -> 優先級 = 0,0,0,2 */
 5 ul ol+li {}     /* a=0 b=0 c=0 d=3 -> 優先級 = 0,0,0,3 */
 6 h1 + *[rel=up]{}     /* a=0 b=0 c=1 d=1 -> 優先級 = 0,0,1,1 */
 7 ul ol li.red {}     /* a=0 b=0 c=1 d=3 -> 優先級 = 0,0,1,3 */
 8 li.red.level {}     /* a=0 b=0 c=2 d=1 -> 優先級 = 0,0,2,1 */
 9 #x34y {}     /* a=0 b=1 c=0 d=0 -> 優先級 = 0,1,0,0 */
10 style=""     /* a=1 b=0 c=0 d=0 -> 優先級 = 1,0,0,0 */

 

  [備注] 
  :first-line 偽元素
  [rel=up] 其他屬性

  了解了這些 你應該不會再對”11個class與一個id”誰的優先級高“這類的問題有疑問了吧,因為a,b,c,d只是在各自位置數字的累加,而不會越級。


  其實,這里還漏了一個重要的東西,那就是!important了。這是一個神奇的東西~

  首先強調的是!important的使用問題:如height:100px !important; 菜鳥一定會疑問,為什么important前面要加空格,其實沒什么,不加也可以,只是為了閱讀方便,呵呵~

  important可以讓前面所有的權重計算變得可笑,因為css屬性值添加了important后,前面所有的努力白費了,行內式的權重也高不過它,除非再聲明一個加important的屬性值來覆蓋它(注意是由css屬性值讀取的順序決定的)。

  比如h1{height:100px !important;}要覆蓋這個height值為200px的話,要在其后加上h1{height:200px !important;}

  而一般!important值的相互覆蓋,是取決于瀏覽器在加載css文件時,對樣式表的讀取順序決定的。在大項目中,很難預料你的文件是先加載還是后加載,特別是公用css文件,不建議加這個特殊值。

  講到這里,提個額外的點:css樣式的讀取解析,是按從右到左進行的,所以不要誤以為寫#id .class1 .class2 .class3{}這樣的選擇器,瀏覽器會因為唯一id存在而查找很快,其實是更慢,最好是保持三個層級,不要層級過多。

  還有,很多人喜歡寫.class1.class2{}這樣的交集選擇器,一般是跟js配合做一些顯示效果。關鍵是IE6不支持這種交集選擇器,像p.class1{}這樣的標準復合選擇器,IE6等低版本瀏覽器才能完美支持。(ps:公司同事踩過這個坑,在IE6下把我的css代碼給覆蓋了,我還查了老半天——最后知道真相的我眼淚掉下來)

   

  其實,懂得上面的這些東西了,你的css水平才算入門(沒錯,只算入門)。

  接下來,講一些很實用的技巧(其實也就是上面基礎知識的融會貫通):

  場景:當鼠標hover到id為content的div后,將高度由auto改變為30px;

  1.菜鳥級寫法

1 $("#content").hover(function(){
2     $(this).css({"height":"30px"});
3 },function(){
4     $(this).css({"height":"auto"});
5 });

  那如果這個div本身height不是auto呢,你是不是又得知道其默認的height屬性值。

  所以這種寫法很不好,學術一點的叫做硬編碼、強耦合。

  2.普通寫法

1 .content_normal{height:20px;} /*默 認應用的樣式*/
2 .content_change{height:30px} /*hover時候應用的樣式*/
1 $("#content").hover(function(){
2     $(this).addClass("content_change");
3 },function(){
4     $(this).removeClass("content_change");
5 });

 

  3.適用性的高級寫法

var $extStyle = $("head").find("#extStyle");

$("#content").hover(function(){
    
    //向頭部插入一個內鏈樣式表
    if($extStyle.length < 1){
         var styleElem = document.createElement("style");
         styleElem.setAttribute("type", "text/css");
         styleElem.setAttribute("id", "extStyle");
          $("head").append(styleElem);
         $extStyle = $("head").find("#extStyle");
      }
    
     $extStyle.append("#content{height:30px;}");
},function(){
     $extStyle.empty();
});

  第三種寫法的好處就是,不管需求怎么變,都可以輕松覆蓋樣式,也可以避免第一種寫法存在的style="height:auto;"的情況。因為height:auto;有時也是致命的,在項目中就遇到過這樣的問題。

  缺點就是要向頭部插入一個style節點,對于小需求的話就有點小題大做。但是大項目中,可以內部默認一個style節點負責插入這些暫時性修改的樣式數據,方便刪除,不弄臟代碼。

  最后提一個很重要的點:在IE下,style節點最多是31個,多了它不認,呵呵~

  via:cnblogs.com/walls/p/4263463.html 


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()