CSS并不简单--选择器你们庭

梳理选择器的种类,理解选择器的优先级,从而避免莫名其妙的样式重叠问题。css

1、选择器的种类

一、基本选择器

  基本选择器包含:通配选择器、元素选择器、ID选择器、类选择器和群组选择器。html

  对于类选择器的命名,'-'和'_'二者多有,具体能够看这里学习

  通配选择器(*),它用来选择全部元素,不过这个选择器的效率比较低,因此慎重选择,可是瞅了一眼Boostrap4.0是这样设置box-sizing:网站

html {
        box-sizing: border-box;
    }
    *, *::before, *::after {
        box-sizing: inherit;
    }
复制代码

  因此吧,也不是不能用,不过也就这一处,仍是得少用。ui

  ID选择器,它的惟一性是规范,可是应用于多个元素,样式一样生效,不推荐这样作。spa

  群组选择器,经过逗号隔开,能够有效的减小一些冗余代码,例如上面的例子中:code

*, *::before, *::after {
        box-sizing: inherit;
    }
复制代码

二、属性选择器

  属性选择器主要针对于元素的属性值进行筛选,包含这几种操做符:=、|=、~=、*=、^=和$=:cdn

  • [attr=val]:属性值为val;
  • [attr|=val]:属性值为val或者以val-开头;
  • [attr~=val]:属性值为val或者以多个空格分开含有val;
  • [attr*=val]:属性值包含val;
  • [attr^=val]:属性值以val开头;
  • [attr$=val]:属性值以val结尾。

  属性选择器的应用不少,例如Vue中的scoped css也正是利用属性选择器实现的。htm

三、层次选择器

  层次选择器包含后代选择器(E F)、子选择器(E > F)、相邻兄弟选择器(E + F)和通用选择器(E ~ F)。blog

  后代选择器与子选择器的区别:相比较前者,子选择器的搜索范围局限于儿子节点。

  相邻兄弟选择器,选择E后面相邻的兄弟节点F。很遗憾不能选择前面的。这个选择器的应用也不少,好比咱们设置列表项之间的距离为20px:

li:not(:last-child) + li {
        margin-top: 20px;
    }
复制代码

  通用选择器,选择E后面全部的兄弟节点F。一样上面的例子:

li:first-child ~ li {
        margin-top: 20px;
    }
复制代码

  若是你能理解上面这两种写法,基本上这两个选择器你就理解了。

四、伪元素选择器

  首先对于伪元素的写法,标准是推荐双冒号,感受这样写挺好的,能够和伪类区别开来。

  ::first-letter做用于整块文本的第一段的第一个文字,元素必须为块级元素。例如修饰段落第一个单词的样式:

p::first-letter {
        color: red;
        font-size: 20px;
    }
复制代码

  ::first-line则是做用于整块文本的第一段,一样必须为块级元素。

  ::before和::after分别向元素的先后添加内容,用处很大,好比咱们实现这样的购物车:

购物车

<span role="btn" aria-label="购物车" attr-quantity="2" class="caricon"></span>
复制代码
/* 这里就不展示可有可无的样式了 */
    .caricon {
        /* 这里设置容器的样式 */
    }
    .caricon::before {
        /* 经过伪元素设置购物车图标 */
    }
    .caricon::after {
        /* 这两个伪元素多有一个重要的content属性,用来设置伪元素的内容 这里经过attr获取元素的属性值,实现购物车数量 */
        content: attr(attr-quantity);
    }
复制代码

  在一些网站中,当你鼠标选择文字会发生样式变化,这是由于用了::selection,不过它能改变的CSS属性比较有限,具体能够查询MDN。

  还有咱们讨厌input的placeholder样式太丑时,你可使用::placeholder来修改,可是这是一个试验性的伪元素,还有不少试验性的伪元素,有兴趣能够搜索一下。

五、伪类

  伪类的组成就更丰富了,这里选择两个比较重要可能还有点容易混淆的说说。

  首先看看否认伪类选择器:not,在前面的例子中你已经看到它的身影了,它匹配不符合描述的元素,用处能够说很大。

  而后就是结构伪类选择器,这里的内容也多,并且很容易混淆。

  例如:first-child和:first-of-type:

p:first-child {
        /* 计算范围:全部的兄弟节点 */
    }
    
    p:first-of-type {
        /* 计算范围:兄弟节点中全部p元素 */
    }
复制代码

  一样还有:last-child和:last-of-type,就很容易懂了。

  :nth-child就比较强大了,不只可使用odd和even,还可使用表达式。例如咱们列表的斑马线:

li:nth-child(even) {
        background: red;
    }
复制代码

  关于:nth-child重要的几点能够总结为:

  • 值的下标是从1开始的;
  • 可是n的下标是从0开始;
  • 当表达式的值为0或者负数是无效的;
  • 采用表达式能够实现不少需求,例如我只想让列表的前三项设置样式:nth-child(-n + 3);

  像什么:nth-of-type,:nth-last-child和:nth-last-of-type是否是小case了。

  :only-child表示父节点只有一个子节点,其实学习了上面的一些选择器,咱们彻底能够找到等价的表达方式:

li:first-child:last-child {
        background: yellow;
    }
复制代码

  固然还有:only-of-type是必不可少的。

2、选择器的优先级

  上面这么多的选择器,是否是很头大,这也是为何这里要特意说一下选择器优先级。当多条样式应用在一个元素上,系统会将样式合并,当一个属性被赋了屡次值,到底取哪一个值呢?这时候就须要优先级了,优先级高的覆盖优先级低的。

  选择器优先级规则:

  • 首先通配符是没有权重的(因此我感受这点也是不推荐使用它的缘由);
  • !important的权重bug级的高;
  • 权重第二高的就是元素的行内样式(style属性中的值);

  接下来的状况咱们能够数值化:

  • id选择器的权重为100;
  • 类选择器、属性选择器和伪类选择器的权重为10;
  • 元素和伪元素的权重为1。
  • 若是优先级同样,则后声明的优先级高。

  看个例子:

li {
        width: 300px;
        height: 90px;
        background: red;
    }
    ul li {
        background: yellow;
    }
复制代码

  首先对于没有重复赋值的width和height,并不存在什么优先级的问题,而对于background,第一个样式的优先级为1,而第二个样式的优先级为2,因此将yellow赋值给background。

3、总结

  前面写了不少废话,也没有将选择器罗列完整,可是基本的构成,你们应该很清晰了。

  对于后面说的选择器优先级的计算,并非说你每次写完样式多要求算一下,最重要的目的是:你理解计算规则后,让你对每种选择器的应用场景更加清晰,而不是说随便用,从而形成意想不到的样式覆盖问题。

  最后,谢谢你们看完这篇文章。

参考资料: 图解CSS3 CSS Specificity: Things You Should Know


  喜欢本文的小伙伴们,欢迎关注个人订阅号超爱敲代码,查看更多内容.

相关文章
相关标签/搜索