🚀一篇文章带你深入理解CSS选择器&伪类🔥

245 阅读10分钟

🚀 为什么叫CSS?从名字理解「层叠样式表」的奥义

你有没有想过——

  • 为什么CSS不叫「HTML美容仪」或者「网页颜料桶」? 🎨
  • 「层叠」到底是什么意思?样式还能叠在一起?
  • 为什么有时候写的CSS不生效?谁在背后「耍大牌」?

其实,CSS(Cascading Style Sheet) 这个名字暗藏玄机! 它不仅仅是个「样式工具」,更是一套精密运转的规则体系


🎯 拆解CSS:名字里的三个关键秘密

1. Cascading(层叠)—— 样式是怎么「打架」的?

想象你在给网页「穿衣服」:

  • 你写了.button { color: red; },但页面上的按钮还是蓝色
  • 你的同事也写了#submit-btn { color: blue; },结果谁的样式生效了?

这就是「层叠」的威力—— CSS会按照优先级规则,像瀑布一样「冲刷」样式,最终决定谁「胜出」💥

(后面我们会揭秘优先级计算,让你彻底掌控样式战场!)


2. Style(样式)—— 不只是「颜色和字体」

很多人以为CSS就是改改颜色、调调间距…… 但它的真正能力远不止于此!

布局控制(Flexbox、Grid 让网页排版随心所欲)

动画交互(hover、transition 让元素动起来)

响应式适配(媒体查询让网页在手机/电脑上都完美显示)

CSS不是「颜料」,而是「网页的造型师」! ✂️


3. Sheet(表)—— 为什么是「表」而不是「代码」?

早期的CSS真的像一张「表」——

h1 { font-size: 24px; color: #333; }
p { line-height: 1.5; margin: 10px; }

这种「属性-值」的配对形式,就像字典一样清晰可查📖


从名字到本质:CSS的核心思想

关键词含义实际影响
Cascading样式层叠同种样式下,优先级决定最终效果
Style视觉+交互不只美化,还能控制布局和动画
Sheet规则集合结构化书写,易于维护和扩展

💡 思考题 如果你给同一个元素写了:

p { color: red; }
.text { color: blue; }

最终文字是什么颜色? (答案会在文中揭晓!)


🔥CSS的优先级&各种关系选择器

选择器

话不多说,我们直接上例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    你来填写
    </style>
</head>
<body>
    
    <div class="container">
        <p>标题之前的p标签</p>
        <h1>标题</h1>
        <p>this is the first graph</p>
        <p>this is the second graph</p>
        <a href="#">link</a>
        <span>this is a span</span>
        <div class="inner">
            <p>this is within</p>
        </div>
    </div>
</body>
</html>

以下是样式图:

image.png 如果说,我想把标题下的第一个p标签设置为红色,该怎么办呢?

那么大家就要用到相邻兄弟选择器+ 了:

 h1+p  {
        color: red;
     }

h1+p 意为:h1标签后的同级的第一个p标签,这是Selector的内容,之后给了它Key-Value:color:red,完成了这次任务。

那如果我想选择h1后面所有的兄弟p标签呢?

那就需要用到通用兄弟选择器~ 了:

h1~p{
    color:blue;
}

再者,我们能不能把container中所有的p标签全部选择?

可以的兄弟,可以的,只需要用后代选择器 (空格) 就好了:

.container p{
    text-decoration: underline;
}

我们看到,在这个html中,有一个graph是在inner中的,处于container的孙代,那么我们可不可以把它抛弃,除了它全部选择?

那么我们就要用子代选择器>

.container>p{
    font-weight: bold;
}

以上样式结合如下:

 /* 兄弟选择器,只选一个相邻的同级的兄弟*/
        h1+p{
            color: red;
        }
        /*h1后面所有的兄弟*/
        h1~p{
            color:blue;
        }
        /*只选择了子代的p而没有孙代的p*/
        .container>p{
            font-weight: bold;
        }
        /*选择了container中所有的p*/
        .container p{
            text-decoration: underline;
        } 

那么你们猜猜最终展现结果会是怎么样呢?

结果如下:

image.png

为什么结果会是这样?

有的盆友们疑问了:我不是利用

h1+p{ color: red; }

将第一个p(this is the first graph)变为红色了吗?为什么现在变成了蓝色

这就显示出了层叠的威力了:因为我们的选择器虽然都选中的是p标签,但是我们先选中的后来选中的给覆盖掉了,因为它们选择的均是标签,所以在优先级上处于同一级,而代码执行时由上到下,先执行了让文本变红的CSS语句,又执行了让文本变蓝的CSS语句,所以最终呈现的是蓝色。

但如果给第一个p标签加上一个class或者id,再利用这俩选择器去选择,那么结果就不一样了。

优先级

要记住优先级,只需要记住一句话:越精细,说话越有份量

也就是控制的元素越精确,优先级越高

想象一下,CSS选择器的优先级就像一群人试图找到并「真实」同一个人(HTML元素),而 「精度」就像他们的寻人方式

选择器如何找人精度(优先级)结果
*(全局选择器)全国广播:“所有人注意!”最低(0,0,0)谁都能听到,但没人当回事,轻易被覆盖
.class(类选择器)某小区贴告示:“穿红衣服的住户出来!”中等(0,1,0)能定位一群人,但可能误伤(多个元素用同一个class)
#id(ID选择器)直接上门敲门:“502室的张三,开门!”(1,0,0)精准定位唯一目标(ID全局唯一)
<style>内联样式当面揪住衣领:“就你,别跑!”最高(1,0,0,0)直接物理控制,优先级碾压一切

当然你不要以为直接物理控制就是最牛b的了,看下面这个例子:

<p style='color:red;'>Hello my friend</p>
p{
color:blue !important;
}

最终会是什么结果呢?

答案是blue

因为!important已经不是物理真实你的程度了,是直接端着导弹喂你嘴里了,优先级最高!!!

所以,优先级排序如下:

!important>inline-style>id>class>label>*

😰伪类?伪人?

伪类是个什么东西?

伪类咱不知道是个啥,伪人咱还不知道吗,伪人不是人,那当然伪类也不是类,伪人可能不是好东西,但伪类是个好东西🤭,且听我慢慢讲来~

我们都知道 CSS规则由以下属性组成:

image.png

Selector 帮助我们选择我们想要的元素,而伪类的出现,让我们能够选择处于某种状态下的html元素

例如::hover:active:focuschecked ......

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>伪类选择器</title>
    <style>

    </style>
</head>
<body>
    <div class="container">
        <h1>伪类选择器示例</h1>
        <p>CSS伪类用于定义元素的特殊状态,如:hover :active</p>
        <button>惦记我~</button>
        
    </div>
</body>
</html>

:active

首先我们来通过例子理解一下伪类,以:active为例,如果我们想给button加一个在点击状态下按钮变色,文本变色的效果该怎么加呢?

如果按照我们通常的做法,我们只能通过选择器直接选择button,直接变色不符合我们的需求,在这种情况下我们选择的是按钮本身,而不是按钮被点击的状态,如果要选中按钮被点击的状态,就需要用到伪类了:

button:active{
     background-color: red;
     color: white;
}

在这里我们选择了所有的button标签(因为全局就这一个button),利用伪类选择了它被激活的状态,加了一些样式。

其他的一些伪类

接下来我们介绍一下其他的伪类

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>伪类选择器</title>
    <style>
        /*一般用一个冒号,单独写用两个冒号*/
        /*行为伪类 hover active selection*/
        button:active{
            background-color: red;
            color: white;

        }
        p:hover{
            background-color: yellow;
        }
        ::selection{
            background-color: blue;
            color:white;
        }
        /*状态伪类 focus checked*/
        input:focus{
            border: 2px solid blue;
        }
        input:checked+label{
            font-weight:bold;
            
        }
        
        /*input处于checked状态下,所选的label的字体加粗*/
        /*结构伪类 nth-child*/
        li:nth-child(even){
            background-color: rgb(211, 211, 208);
        }
        li:nth-child(odd){
            background-color: rgb(95, 95, 90);
        }
        /*条件伪类*/
        li:not(:last-child){
            margin-bottom: 10px;
        }
    /*选中第几个子元素,odd奇数 even偶数*/
    </style>
</head>
<body>
    <div class="container">
        <h1>伪类选择器示例</h1>
        <p>CSS伪类用于定义元素的特殊状态,如:hover :active</p>
        <button>惦记我~</button>
        <p>鼠标悬浮在这里</p>
        <input autofocus type="text" placeholder="Please enter messages">
        <input type="checkbox" name="check1" id="option1">
        <label for="option1">1</label>
        <input type="checkbox" name="check1" checked id="option2">
        <label for="option2">2</label>
        <ul>
            <li>列表1</li>
            <li>列表2</li>
            <li>列表3</li>
            <li>列表4</li>
        </ul>
        <!-- autofocus自动聚焦,或者按tab从文件上面到下面依次聚焦,checkbox加了checked后默认选中 -->
    </div>
</body>
</html>

:hover

如上述效果可见,:hover选择的是鼠标漂浮在某个元素上的效果,经常被用于按钮上,或实现放大或者发光的效果。

:focus

focus即为聚焦,让所选中的元素聚焦在哪里,你可以现在就按一按tab

::selection

即为选中,大家可以将光标放在p标签上尝试选中一段文本,看看效果

:checked

为checkbox的选中效果,上述可以利用其为label做样式变化:

input:checked+label{
      font-weight:bold;       
      }

我们利用了input框的checked属性,锁定到了一个input的checked状态,再利用兄弟选择器选中了label,使其字体变粗,这就是伪类的实际应用

为什么input框的输入没有被影响?

我们说了 伪类可以表示某个元素的某个状态,但是上面的输入框根本没有checked属性时,它自然就不会被选中影响咯~

:nth-child()

会被用来选中某些元素的子元素,比如上面的例子,如何理解呢?

nth 的意思就是第几个嘛

child 的意思就是孩子

那么连起来就是 第几个孩子,odd代表奇数,even代表偶数,()内可以填任意数字

面试题: nth-child() & nth-of-type()的区别

大家不知道什么是nth-of-type()并没有关系,我们可以通过下面的例子来说明一下: 完整的html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       
        .container p:nth-child(5){
            background-color: yellow;
            color:black;
        }
        
        .container#demo p:nth-of-type(2){
            background-color: aqua;
            color:black;
        } 
    </style>
</head>
<body>
    <div class="container" id="demo">
        <h1>nth-child vs nth-of-type</h1>
        <p>这是个段落</p>
        <div>这是个div
            <p>div内的p</p>
        </div>
        <p>第二个段落</p>
        <p>第三个段落</p>
        <div>这是第二个div</div>
    </div>
</body>
</html>

image.png 这是效果图,但如果我们将

.container p:nth-child(5){
            background-color: yellow;
            color:black;
        }
        改为:
        .container p:nth-child(3){
            background-color: yellow;
            color:black;
        }

那么效果图就为:

image.png

这时候我们可以看出 .container p:nth-child(x)的含义为:选择container下的所有后代的第x个元素,而且这个元素必须是p标签,才会应用样式

接下来我们改变nth-of-type(x):

x=3:

image.png x=1:

image.png

这时我们可以发现 .container#demo p:nth-of-type(x) 的原理是:选择id为demo的元素下的所有的第x个p元素,并改变其样式

总结不同

特性:nth-child(n):nth-of-type(n)
选择依据父元素的所有子元素中的第 n 个(无视标签类型)父元素的同类型子元素中的第 n 个
是否区分元素类型❌ 不区分(任何标签都计入计数)✅ 区分(仅匹配指定标签类型的元素)
语法示例li:nth-child(2) → 选择第 2 个子元素(需是 lili:nth-of-type(2) → 选择第 2 个 li 元素
匹配失败时的行为如果第 n 个子元素不匹配选择器,则无效果仅统计同类型元素,其他标签不影响计数

总结

CSS选择器就像一场相亲大会,各种元素在DOM树里眉来眼去。关系选择器就是它们的红娘,A B这种媒婆最不讲究,只要在家族谱系里能找到的都算数;A > B就比较势利眼了,必须是直系血亲才认;A + B活像个跟屁虫,非要紧挨着才肯配对;A ~ B倒是个海王,只要在同一个屋檐下的都算备胎。

伪类选择器简直就是元素的心情日记。:hover是"人家被鼠标调戏了啦",:active是"被按住了别乱动",:focus是"镜头对准我!"。最精分的是:checked,一会儿勾选一会儿取消,比渣男还善变。

至于:nth-child:nth-of-type这对双胞胎,表面看着像,骨子里完全不同。:nth-child是个死脑筋,非要按出生顺序来,管你是男是女;:nth-of-type就聪明多了,知道把男孩女孩分开排队。就像相亲时,前者会把你的前任都算上,后者只会统计同类型的约会对象。

总结起来,CSS选择器就是一场大型社交现场:有的广撒网(后代选择器),有的挑三拣四(子选择器),有的爱凑热闹(相邻兄弟),还有的专门搞特殊(伪类)。而:nth-child:nth-of-type这对活宝,一个像钢铁直男,一个像贴心闺蜜,用错了可是要闹笑话的!

大家一定要多加练习,好好做笔记才能掌握我们所学的内容!下期见!

开心.gif