你知道的CSS选择器都有哪些?

先来思考一个问题,我们为什么需要CSS选择器?

反过来想,如果没有CSS选择器,那么会出现哪些现象呢?我认为会出现下面这些:

  1. 所有CSS样式都要写在Tag上,对开发效率不利;
  2. 根据1,Cascading Style Sheets这个名字估计会变成Style Sheets;
  3. 一旦页面完成加载和显示,则无法动态修改Tag的样式,退化至“静态页面”时代;

所以,上面三条的对立面则是我们为什么需要CSS选择器的理由。除此之外,CSS选择器还提供了更加强大的能力,比如众多伪元素的加入,会起到优化HTML的结构的作用。

按照选择器的结构做个划分,从简单到复杂可分为下面这些类:

  • 简单选择器:针对单一特征判断是否选中元素。
  • 复合选择器:连写在一起的简单选择器,相当于多个简单选择器的并集。
  • 复杂选择器:由“(空格)”、“ >”、“~”、“+”、“||”等符号连接的复合选择器,根据元素之间的关系精确选择。
  • 选择器列表:由 , 分隔的复杂选择器,表示“或”关系。

简单选择器

根据单一特征匹配元素的选择器,主要包含这些:

  • 类型选择器:根据标签类型匹配,比如 div p {};
  • ID选择器:根据ID值匹配,比如 #main-area {};
  • Class选择器:根据特定属性 class 匹配,比如 .user-info {};
  • 属性选择器:根据属性名和值匹配
    • [attr]
    • [attr=val]
    • [attr~=val]
    • [attr|=val]
  • 伪类选择器:根据系统添加的类匹配
    • 树形关系伪类选择器
    • 链接和行为伪类选择器
    • 用户界面伪类选择器
    • 逻辑伪类选择器
    • 其他伪类选择器

类型选择器

根据元素的标签名匹配,比如

    div {
        font-size:40px
    }

这看上去非常简单,但有时候我们要考虑HTML和XML的命名空间。比如svg元素,实际上在: http://www.w3.org/2000/svg 命名空间之下。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>CSS Selectors</title>
    </head>
    <body>
        <svg width="100" height="28" viewBox="0 0 100 28" version="1.1"
            xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
            <desc>Example link01 - a link on an ellipse
            </desc>
            <a xlink:href="http://www.w3.org">
                <text y="100%">name</text>
            </a>
        </svg>
        <br/>
        <a href="javascript:void 0;">name</a>
    </body>
    </html>

在上面的代码中,SVG和HTML中都有a元素,如果要区分它们,就得用带有命名空间的选择器。

    @namespace svg url(http://www.w3.org/2000/svg);
    @namespace html url(http://www.w3.org/1999/xhtml);

    svg|a {
        font-size: 20px;
    }
    html|a {
        font-size:40px;
        color: red;
    }

另外,还有一个特殊的选择器 * ,称为全体选择器,可选中任意元素。

id、class选择器

id 选择器和 class 选择器都是针对特定属性的选择器。id 选择器是“#”号后面跟随 id 名,class 选择器是“.”后面跟随 class 名。基本用法如下:

    #myid {
        stroke:blue;
        stroke-width:1;
    }

    .mycls {
        font-size:40px
    }

对于class选择器,有时候会用空格把多个class分割开放在一起,这时候任何一个类都能选中。

    <a class="a b c">xxx</a>

    .a {
        color:red;
    }

这种情况下,用 .a.b.c 都能选中该元素。

属性选择器

根据属性名和属性值的对应关系匹配元素,主要有四种形式。

[attr]

在方括号中放入属性名,检查元素是否具有这个属性,只要元素有这个属性,不论属性是什么值,都可以被选中。

[attr=val]

要同时满足属性名和属性值之间的对应关系。比如:

    div[class=error] { 
        color:#f00; 
    }

[att~=val]

多种匹配,检查一个元素的值是否是若干值之一,这里的val不是一个单一的值了,可以是用空格分隔的一个序列。

td[headers~=col1] {
    color: green;
}

[att|=val]

开头匹配,检查一个元素的值是否是以 val 或者 val- 开头开头。典型的应用场景是用来匹配语言简写代码(如 zh-CN,zh-TW 可以用 zh 作为 value)。

另外,还有CSS3中加入的新能力,语法类似正则表达式。

选择器 说 明
att^="val" 属性att的值以"val"开头的元素
att$="val" 属性att的值以"val"结尾的元素
att*="val" 属性att的值包含"val"字符串的元素

伪类选择器

伪类选择器是一系列由CSS规定好的选择器,它们以冒号:开头。伪类选择器有普通型和函数型两种。

树形关系伪类选择器

因为DOM是树形结构,对应到CSS中也会有一个属性关系,主要有下面这些伪类。

选择器 说 明
:root 树的根元素,一般用html标签即可选中根元素
:nth-of-type(An+b) 符合当前标签类型的第(An+b)个元素
:nth-last-child(*) 同上,但是从后到前计数
:nth-child(odd) 符合条件的序列号为奇数的元素
:nth-child(even) 符合条件的序列号为偶数的元素
:nth-child(4n-1) 符合条件的序列号为4n-1的元素,比如3、7、11、···
:nth-child(3n+1 of li.important) 同上,但是还要满足一个条件li.important
:last-of-type 符合当前标签类型的最后一个元素
:first-child 符合条件的第一个元素
:last-child 符合条件的最后一个元素
:first-of-type 符合当前标签类型的第一个元素
:empty 没有子节点的元素

其他请看MDN web docs

链接与行为伪类选择器

这些伪类是最常用的一类。

选择器 说明
:any-link 任意的链接,包括a、area和link标签都可能匹配
:link 未访问过的链接
:visited 已经访问过的链接
:hover 鼠标悬停在上的元素
:active 用户正在激活这个元素,用户按下按钮但鼠标还未抬起时
:focus 焦点落在这个元素之上时
:target 选中浏览器URL的hash部分所指示的元素

逻辑伪类选择器

选择器 说明
:not 与括号内选择器不相符的元素,只支持简单选择器
:is 在Selector Level 4草案中引入的新伪类
:where 在Selector Level 4草案中引入的新伪类

用户界面相关

选择器 说明
:default 默认表单元素
:defined 任何已定义的元素,包括标准元素和自定义元素
:enabled 表单中激活的元素
:disabled 表单中禁用的元素
:checked 表单中被选中的radio(单选框)或checkbox(复选框)元素

复合选择器

在实际工作中,除过使用简单选择器之外,还会大量使用由数个简单选择器组合而成的选择器,就给它起个名字叫“复合选择器”。具体而言,是用空格、>~ 等符号连接组合多个简单选择器而成的。

连接符号

总共有5种符号,用来连接简单选择器,如下:

  • “空格”:后代,表示选中所有符合条件的后代节点, 例如 ".a p" 表示选中所有具有class为a的后代节点中的p节点。
  • >” :子代,表示选中符合条件的子节点,例如“.a>.b”表示选中所有“具有class为a的子节点中,class为b的节点”。
  • ~” : 后继,表示选中所有符合条件的后继节点,后继节点即跟当前节点具有同一个父元素,并出现在它之后的节点,例如“.a~.b”表示选中所有具有class为a的后继中,class为b的节点。
  • +”:直接后继,表示选中符合条件的直接后继节点,直接后继节点即nextSlibling。例如 “.a+.b ”表示选中所有具有class为a的下一个class为b的节点。
  • ||”:列选择器,表示选中对应列中符合条件的单元格。

针对下面这段代码:

    <!DOCTYPE html>
    <html>
    <body>
    <div class="o">
    <div class="a"><p> First</p></div>
    <div class="b">
        <p> Second</p>
        <p class="a">Inner Paragraph</p>
    </div>
    </div>
    <div class="a"><p> Last</p></div>
    <div class="c">
    <p> Third</p>
    <p class="a">Outer Paragraph</p>
    </div>
    </body>
    </html>

使用不同CSS选择器效果如下所示:

复合选择器效果

在实际工作中,用的最多的是前两个。另外,设置合理的class有助于降低选择器的复杂程度。

伪元素

伪元素和伪类比较相似,区别主要在于伪类会把实际存在的元素选择出来,而伪元素则能够把实际并不存在的元素选择出来。

目前,兼容性比较好的几个是:

  • ::first-line
  • ::first-letter
  • ::before
  • ::after

::first-line ::first-letter

::first-line 表示一段文字的第一行,注意:是经过浏览器排版之后最终显示的第一行,而非用户编写时的第一行。

比如,针对这段代码:

<p>The browser tries to help us by mixing namespaces of JS and DOM.
That’s fine for simple scripts, inlined into HTML, but generally isn’t a good thing. There may be naming conflicts. Also, when one reads JS code and doesn’t have HTML in view, it’s not obvious where the variable comes from.
Here in the tutorial we use id to directly reference an element for brevity, when it’s obvious where the element comes from.</p>
    p::first-line {
      font-size: 26px;
      color: green;
    }

在不同浏览器尺寸下的显示效果如下:

first-line显示效果

另外,还需要注意的是:CSS标准规定了first-line必须出现在最内层的块级元素之内,也就是说必须出现在 p div 等块级元素内,如果出现在 span 等行级元素之内,则会失效。

::first-letter表示第一个字母,这个意义比较明确。

还是针对上面这段文字,如果使用 ::first-letter 效果如下:

    p::first-letter {
      font-size: 32px;
      color: green;
    }
first-letter显示效果

::before ::after

这两个伪元素会真正地“无中生有”,消无声息地造出一个元素,但是它们并不会显示在DOM树中::before 表示在元素内容之前插入一个虚拟的元素,::after 则表示在元素内容之后插入。

这两个伪元素所在的CSS样式必须指定content属性才会生效,下面看看例子。

    <p class="special">I'm real element</p>
    p.special::before {
        display: block;
        content: "Before";
    }
    p.special:after {
        display: block;
        content: "After";
        color: red;
        padding: 100px;
        font-size: 60px;
        height: 600px;
        background: url(https://search-operate.cdn.bcebos.com/bf38b0d32a3f51e8d06ad1d3c93201a5.jpg);
    }
::before&::after显示效果

总结

首先,我们认识到CSS选择器的作用主要体现在两点:

  1. 经济性,可加快程序开发效率以及提高程序的可读性;
  2. 实用性,可动态修改特定Tag的样式,满足多变的用户需求。

接着,学习了最基本的简单选择器的用法,主要包括类型选择器、id选择器、class选择器和属性选择器。其中,id选择器和class选择是使用最多的。

然后,主要了解了伪类选择器,包括树形结构选择器、链接行为选择器、用户界面选择器和逻辑选择器。其中前两个是用的最多的,因为DOM本身就是树形结构,树形结构选择让选择DOM中的特定Tag变得非常容易;各种各样的链接不断延伸Web的能力,全世界共同编制了一个Internet,链接行为选择器对此贡献了力量。

最后,学习了符合选择器,即由简单选择器通过空格、>、~、+、||和逗号连接的选择器,这在实际工作中是用的最多的,因为功能更加强大,能满足复杂的需求。另外,还有四个伪元素选择器,它们和伪元素选择器类似,主要区别在于前者可以无中生有地创造出一些元素,优化DOM树的结构。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343