zoukankan      html  css  js  c++  java
  • 深入理解css优先级

    为什么要写这篇文章是因为

    <style type="text/css">
    body h1 {
      color: green;
    }
    html h1 {
      color: purple;
    }
    </style><body>
       <h1>Here is a title!</h1>
    </body>

    上面代码执行结果是这样的。按照我的理解,body在DOM中比html近,应该会按body h1中定义的绿色来显示文字,但是恰恰相反,文字颜色是紫色的。

    原因现在我当然是知道的,因为css中优先级无视DOM树中节点的距离远近,就是说DOM树中的距离不会对元素优先级计算产生影响。如果优先级相同,靠后的 CSS 会应用到元素上。而html h1靠后,当然是紫色了,如果调换html h1body h1顺序那就是绿色了。

    以上我刚开始犯的错误,其实是被继承样式给唬住了,但是继承的样式是低于设定的样式的。如果只是继承,那离的近的当然优先级高,比如举个例子:

    <style type="text/css">
    #close{
        color: green;
    }
    #further{
        color: purple;
    }
    </style><body>
    <div id="further">
    <div id="close">
       <h1>Here is a title!</h1>
    </div>
    </div>
    </body>

    不管#close和#further顺序,文字都是绿色的。

    接下来就系统的看看css优先级。

    一、优先级

    浏览器根据优先级来决定给元素应用哪个样式,而优先级仅由选择器的匹配规则来决定。

    内联》ID选择器》伪类=属性选择器=类选择器》元素选择器【p】》通用选择器(*)》继承的样式

    二、优先级计算:

    上面说了,优先级仅有选择器决定,怎么个计算方法呢?

    a、用a表示选择器中ID选择器出现的次数

    b、用b表示类选择器属性选择器伪类选择器出现的总次数。

    c、用c表示标签选择器伪元素选择器出现的总次数

    d、忽略通用选择器

    e、然后计算a*100+b*10+c的大小,这就是优先级了。

    权重:内联样式1000》id选择器100》class选择器10》标签选择器1

    Note:

    ID选择器「如:#header」,Class选择器「如:.foo」,属性选择器「如:[class]」,伪类「如::link」,标签选择器「如:h1」,伪元素「如::after」,选择器「*」

    接下来从以下几点深入分析优先级。

    1、优先级计算无视DOM树中的距离

    开头说明的例子:

    <!DOCTYPE html>
    <html>
    <style type="text/css">
    body h1 {
      color: green;
    }
    html h1 {
      color: purple;
    }
    </style>
    </head>
    <body>
    <h1>Here is a title!</h1>
    </html>
    View Code

    body h1和html h1的优先级相同。

    2、伪类选择器,属性选择器和class选择器的优先级一样【update20170422】

    伪类=属性选择器=类选择器

    所以后面的会覆盖前面的。

    <!DOCTYPE html>
    <html>
    <meta charset="utf-8">
    <style type="text/css">
        :focus {
            color: red;
        }
        [class] {
            color: blue;
        }
        .classtest {
            color: green;
        }
    </style>
    </head>
    <body>
    <div class="classtest">
        什么颜色文字
    </div>
    </body>
    </html>
    View Code

    如下图类选择器在后,所以覆盖前面的样式,所以文字绿色。

    如下图属性选择器在后,会覆盖前面的类选择器样式,所以文本蓝色。

    focus同理,只有放后面才生效,否则会被伪类和属性选择器覆盖

    3、基于类型的优先级

    优先级是根据选择器的类型进行计算的。

    举例:属性选择器尽管选择了一个ID但是在优先级计算中还是根据类型计算,因此即使选择的是相同的元素,但ID选择器有更高的优先级,所以* #foo设置的样式生效。

    <!DOCTYPE html>
    <html>
    <style type="text/css">
    * #foo {
      color: green;
    }
    *[id="foo"] {
      color: purple;
    }
    </style>
    </head>
    <body>
    <p id="foo">I am a sample text.</p>
    </body>
    </html>
    View Code

    4、:not伪类不参与优先级计

    【:not】否定伪类在优先级计算中不会被看做是伪类,但是,会把:not里面的选择器当普通选择器计数。这句话有点不好理解,其实就是忽略掉:not,其他伪类(如:hover)参与CSS优先级的计算,但是「:not」不参与计算。

    举个例子:

    <!DOCTYPE html>
    <html>
    <style type="text/css">
    div.outer p {
      color:red;
    }
    div:not(.outer) p {
      color: blue;
    }
    </style>
    </head>
    <body>
    <div class="outer">
      <p>This is in the outer div.</p>
      <div class="inner">
        <p>This text is in the inner div.</p>
      </div>
    </div>
    </body>
    </html>
    View Code

    该例子中,选择器div.outer p 和选择器div:not(.outer) p的优先级是相同的,:not被忽略掉了,:not(.outer)中的.outer正常计数。

    如果调换位置,inner元素会变成红色

        div:not(.outer) p {
            color: blue;
        }
        div.outer p {
            color:red;
        }

    5、优先级计算不升位

    不要把权重简单的作为10进制数字比较其大小。

    a=1的规则优先级将永远高于其他a=0的。

    比如一个选择器的a>0,b=0即使另外一个选择器的a=0,b=12,c=12那么前者的权重依然更大!!

    为证明我做了一个不现实的demo

    <!DOCTYPE html>
    <html>
    <meta charset="utf-8">
    <style type="text/css">
    
    #test{ /*a=1*/
        color: blue
    }
    div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest{ /*b=12*/
    color:green;
    }
    
    </style>
    </head>
    <body>
    <div  class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div class="classtest">
    <div id="test" class="classtest">
    什么颜色文章
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </body>
    </html>
    View Code

    可见文本颜色还是蓝色!!

    同样有一个带有10个id选择器的规则,优先级也不如内联样式。

    总之优先级的计算不是基于十进制升位的,后面的数优先级再高也不能升到前一位。

    6、其他

    下面再给出一个经典的例子,自己计算一下就明白了。

    Examples:
    
    *               /* a=0 b=0 c=0 -> specificity =   0 */
    LI              /* a=0 b=0 c=1 -> specificity =   1 */
    UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
    UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
    H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
    UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
    LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
    #x34y           /* a=1 b=0 c=0 -> specificity = 100 */
    #s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */

    如果确实有棘手的情况,可以在Firebug中查看优先级。Firebug中按照优先级排序显示规则,将优先级更高的规则显示在最上面,并将被覆盖的规则用删除线划掉。

    三、!import

    为什么没有把!import放在优先级顺序中,因为官方认为!import和优先级没一点关系。

    不建议使用!import

    • Never 绝不要在全站使用!import。
    • Only 只在需要覆盖全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定页面中使用   !important
    • Never 永远不要在你的插件中使用 !important
    • Always 要优先考虑使用样式规则的优先级来解决问题而不是 !important

    选择元素时尽量不要多选,不要放宽选择器的范围。因为范围越小,越具有针对性,优先级越高。

    1、什么场合使用!import?

    使用!import的场合也是有的,但是是在没有别的解决方案的时候。

    比如需要覆盖内联样式,因为内联样式的优先级最高,只能用!import去覆盖内联样式。

    还有一种情况

    <style type="text/css">
    #someElement p {
        color: blue;
    }
    
    p.awesome {
        color: red;
    }
    </style>
    </head>
    <body>
    <div id="someElement">
    <p class="awesome">some text</p>
    </div>
    </body>

    在外层有 #someElement 的情况下,你怎样能使 awesome 的段落变成红色呢?这种情况下,如果不使用 !important ,第一条规则永远比第二条的优先级更高。这也是没有别的办法,如果用内联结果只会更糟糕。

    2、怎样覆盖已有!import规则

    a、再加一条!import的css语句,将其应用到更高优先级的选择器(在原有基础上添加额外的标签、类或者ID选择器)。

    几个更高优先级选择器的例子:

    table td    {height: 50px !important;}
    .myTable td {height: 50px !important;}
    #myTable td {height: 50px !important;}

    b、选择器一样,但添加的位置在原有声明后面。因为相同优先级,后边定义的声明覆盖前面的。

    相同选择器的例子:

    td {height: 30px !important;}
    td {height: 50px !important;}

    四、资源链接

    http://www.w3.org/TR/selectors/#specificity
    https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

  • 相关阅读:
    计算1的个数
    【环境配置】配置git
    Spoj 9887 Binomial coefficients 构造
    程序猿与HR博弈之:有城府的表达你的兴趣爱好
    C和指针 (pointers on C)——第六章:指针(上)
    关于undo表空间配置错误的ORA-30012
    每天进步一点点——Linux系统中的异常堆栈跟踪简单实现
    javaScript 对象的使用
    手机游戏加密那点事儿_2d资源加密_1
    支持向量机
  • 原文地址:https://www.cnblogs.com/starof/p/4387525.html
Copyright © 2011-2022 走看看