CSS 2.2 Specification —— Selector

Clloz · · 853次浏览 ·

前言

去年曾经仔细地学习了一下css2.2的规范。其中,选择器,属性的赋值、层叠和继承,盒模型,视觉格式化模型 几章是最重要的,其实去看这个规范的原因很简单,自己在使用 css 的过程中,经常出现让自己很迷惑的问题,比如 inline-block 布局为什么两个块之间出现空隙,vertical-align 怎么有时有用有时没用,行内元素的高度怎么计算的等等,以往遇到这些问题只能依靠搜索引擎,但是依然不得要领,后面就到 w3c 去找规范看了看,其实内容也不是非常多,但是要理解透彻还是要结合不断的实践,不然感觉看懂了,理解了,很快又会忘了。

什么是CSS选择器

CSS选择器是我们在前端写样式的时候每天都要用到的,刚接触 CSS 的时候就会用到 类选择器ID选择器子选择器后代选择器等等,说白了选择器的目的就是准确地定位到我们想要赋予样式的元素,我们只要掌握 CSS 的语法和模式匹配的规则,那么我们在使用选择器的时候就能够得心应手了。

模式匹配 Pattern matching

模式匹配的规则看下图,不管你的选择器是简单的类型选择器,还是丰富的上下文选择器,如果模式中的所有条件对于某个元素都为真,那么选择器就会匹配该元素。这里面有我们熟悉的类型选择器(标签),后代选择器,子选择器,兄弟选择器,属性选择器,伪类选择器。其实我们平时用的最多的类选择器和ID选择器,在 HTML 里面也属于属性选择器的范畴,比如途中的E#myid写成E[id=”myid”]也是可以匹配的。
CSS选择器模式匹配规则

选择器语法

在我刚开始写 CSS 的时候,类型和属性,属性和属性之间,是否有空格,逗号,把我搞得很迷糊,踩了不少坑,晚上文章虽多却很少有写的透彻的。其实这也就是选择器语法的问题。复杂的选择器也是由简单选择器通过连接符来构成的,简单选择器包括:类型选择器(标签选择器),属性选择器(包括类选择器和ID选择器),伪类,伪元素,通配符选择器。而连接符一般就是空白符,>+ ,不过要注意的是我们一般使用 >+ 也会在它们和选择器之间留空白符比如 .a > .b 而不会写成 .a>.b,主要是为了可读性。除了上面说到的三个连接符,还有一个逗号需要提一下,在规范中被称之为分组( grouping ),就是当几组选择器具有相同的声明的时候我们可以把他们当作一个分组来处理,比如:

h1 { font-family: sans-serif }

h2 { font-family: sans-serif }

h3 { font-family: sans-serif }
h1, h2, h3 { font-family: sans-serif }

他们是等价的。

通配符选择器,类型选择器

通配符选择器就是选择所有元素,一般是不建议使用的。类型选择器就是我们理解的标签选择器,他可以匹配文档树中所有该类型元素。

后代选择器

当我们想要选择某个元素的后代元素,比如匹配所有 h1 元素包裹的 em 元素,我们就会用 h1 em { color: red;} 这种表达方式,后代元素可以有多层,一个后代选择器由两个或者多个选择器由用空白符隔开的选择器组成,注意,此处的多个选择器不一定非要是简单选择器,比如我们可以这样 p .a.b.c { color: blue;}来选择被p包裹的同时具有 abc 三个类的元素。还有一个场景就是当我们想选择某个元素的所有非子元素的后代的时候我们可以这样写 div * p {display: inline-block;},需要注意,这里的 * 不是连接符,而是通配符选择器。

子选择器

子选择器匹配某个元素的子集元素,子选择器可以和后代选择器类比,子选择器是后代选择器的子集,因为它只检索一层,而后代选择器则要检索对应元素的全部子元素。子选择器用连接符 > 连接两个或多个选择器,同样这里的选择器不一定是简单选择器。不同类型的选择器是可以一起使用的,比如 div ul > li p {font-size: 1.2em} 匹配了作为 div 后代的无序列表 ul 的子级li 的后代 p 元素。

相邻兄弟选择器

如果两个元素在文档中共享父元素,且他们相邻,那么他们就属于兄弟元素,用 + 连接符连接。这个选择器平时用的比较少,但是在很多时候是我们把它遗忘了,在特定的场景里还是非常有作用的。h1.opener + h2 { margin-top: -5mm }

属性选择器

属性选择器有几种表达方式
1. [attr] : 匹配拥有属性 attr 的元素,无论属性值是多少;
2. [attr=val]: 匹配拥有属性 attr 且属性值为 val 的元素;
3. [attr~=val] : 匹配拥有属性 attrattr 属性值中包含 val 的元素( DOM 元素的属性可以包含多个属性值,每一个属性值对应一个属性节点,我们常用的 class 属性就可以有多个值,用逗号分隔开,该条规则同样适用于 attr 属性值只有一项的元素)。
4. [attr|=val] :匹配一个有 attr 属性且值 以 val 开头后面紧跟着 - ( U+002D )的元素。*[lang|="en"] {color: red;} 就会匹配下面代码的前三行。

<p lang="en">Hello!</p>
<p lang="en-us">Greetings!</p>
<p lang="en-au">G'day!</p>
<p lang="fr">Bonjour!</p>
<p lang="cy-en">Jrooana!</p>
  1. [attr^="val"] : 匹配拥有属性 attr 且属性值是以 val 开头的元素。
  2. [attr$="val"] : 匹配拥有属性 attr 且属性值是以 val 结尾的元素。(第五和第六两项要注意,以’val’开头和结尾不是 <div attr="val1 val2"> 中的 val1="val" 的意思,而是 val1 字符串是以 val 开头的,例如 val='clloz' ,那么如果 val1="clloztest" ,那么该元素就是匹配的,以 val 结尾同理。
  3. [attr*="val"]: 匹配拥有 attr 属性,且属性值包含 val 的元素。(只要 attr 属性中的任意一项包含val字符串就匹配该模式)

5,6,7三项都是在CSS2.1规范之后发布的。

类选择器

类选择器其实也是属性选择器的一种,我们平时使用的 . 其实和刚刚属性选择器中的第三个表达方式 [attr~=val] 是同样的作用。当我们需要同时匹配多个属性的时候,我们可以将多个属性写到一起,不适用空白符 p.marine.pastoral { color: green }

ID选择器

注意,一个元素只能拥有一个 id,并且文档树中的元素不可以具有相同的 ID,如果同一个元素两次设置 ID,那么只有前面一个生效;如果两个元素设置了相同的 ID,他们的样式都会生效,但是如果你用 js 获取 ID 对应的元素只有第一个会被返回。

总结

关于 CSS 选择器就写这么多,其实还有伪类和伪元素,准备单独拿出来讲,另外层叠和继承也放到那篇文章中。


Clloz

人生をやり直す

发表评论

电子邮件地址不会被公开。 必填项已用*标注

我不是机器人*

EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00