做一个现实的理想主义者

CSS选择器优先级以及复杂选择器的权重计算 - 【大前端】

2018.10.13

CSS选择器的优先级

!important > 行间样式 > id > class|属性|伪类 > 标签选择器|伪元素 > 通配符

复杂的选择器

CSS选择器权重值主要用于复杂选择器的权重计算,一般的选择器依据优先级判断即可。

1. 父子选择器/派生选择器

<div>
    <strong>
        <em>234</em>
    </strong>
</div>
div strong em{
    background-color: red;
}

效果如下(浏览器页面放大了5倍,方便观察,下文不再特殊说明):

父子选择器不是只针对标签,也可以是类或者id,比如:

    <div class="wrapper">
        <strong class="box">
            <em>234</em>
        </strong>
    </div>

类与标签的父子选择器

/*div strong em{
    background-color: red;
}*/

.wrapper .box em{
    background-color: green;
}

效果如下:

类、id以及标签的父子选择器

    <div class="wrapper">
        <strong class="box" id="box1">
            <em>234</em>
        </strong>
    </div>
/*div strong em{
    background-color: red;
}*/

/*.wrapper .box em{
    background-color: green;
}*/

.wrapper #box1 em{
    background-color: yellow;
}

效果如下:

父子选择器的生效范围:直接的或者间接的子选择器均生效。

    <div class="wrapper">
        <em>1</em>
        <strong class="box" id="box1">
            <em>234</em>
        </strong>
    </div>
/*div strong em{
    background-color: red;
}*/

/*.wrapper .box em{
    background-color: green;
}*/

/*.wrapper #box1 em{
    background-color: yellow;
}*/

div em{
    background-color: red;
}

效果如下:

2.直接子元素选择器

    <div class="wrapper">
        <em>1</em>
        <strong class="box" id="box1">
            <em>234</em>
        </strong>
    </div>
/*div strong em{
    background-color: red;
}*/

/*.wrapper .box em{
    background-color: green;
}*/

/*.wrapper #box1 em{
    background-color: yellow;
}*/

div em{
    background-color: red;
}

div > em{
    background-color: green;
}

效果如下:

简单的理解是:它的生效范围仅仅为父子选择器中直接的子选择器

父子选择器的浏览器解释顺序

    <section>
        <div>
            <p>
                <a href="">
                    <span></span>
                </a>
            </p>
            <ul>
                <li>
                    <a href="">
                        <span>
                            <em>1</em>
                        </span>
                    </a>
                    <p></p>
                </li>
                <li></li>
            </ul>
        </div>

        <a href="">
            <p>
                <em>2</em>
            </p>
            <div></div>
        </a>
    </section>
section div ul li a em{
    background-color: red;
}

效果如下:

问题来了,父子选择器的解释到底是从左到右呢,还是从右到左呢?

假设从左到右:

因为父子选择器的生效范围包括直接和间接的子选择器,会先找所有的 section 的标签,然后再找 section 下包含了 div 的选择器,不管是间接的还是直接的,这个时候已经有两条路径了,再找 div 下的所有 ul,…… ,依次类推

假设从右到左:

对比下来,明显可以发现,从右到左的解释判断更少、路径更少,也就是解释速度更快

结论:父子选择器的浏览器解释顺序是从右到左的

3.并列选择器

    <div>1</div>
    <div class="demo">2</div>
    <p class="demo">3</p>
div.demo{
    background-color: red;
}

ps.并列选择器之间没有空格

效果如下:

4. 分组选择器

    <em>1</em>
    <strong>2</strong>
    <span>3</span>
em, strong, span{
    background-color:red;
}

效果如下:

然而在实际的开发中,css 一般用如下的写法,便于观察:

em, 
strong, 
span{
    background-color:red;
}

效果是一样的,只不过更便于阅读。

CSS选择器权重值

选择器 权重
!important Infinity
行间样式 1000
id 100
class&属性&伪类 10
标签选择器&伪元素 1
通配符 0

以上数字的进制为256进制

复杂选择器的权重计算

    <div class="classDiv" id="idDiv">
        <p class="classP" id="idP">1</p>
    </div>
#idDiv p{
    background-color: red;
}

.classDiv .classP{
    background-color: green;
}

效果如下:

为什么呢?

id选择器的权重值为100,class选择器的权重值为10,标签选择器的权重值为1

那么,很明显, (#idDiv + p) > (.classDiv + .classP),所以(#idDiv + p)生效了。

如果两个复杂选择器的权重值相同,那么写在后面的复杂选择器生效。

再比如:

div#idDiv p.classP{
    background-color: red!important;
}

div .classDiv#idP{
    background-color: green!important;
}

效果如下:

为什么呢?

在计算机的数学计算里,(无线大 + 1) > 无限大,这个跟数学计算不一样。

参考:

Comments
Write a Comment