前端开发小技巧 - 【CSS】 - 常见的伪类选择器 及 新增的伪类选择器【:has、:is、:where】
前言
常见的选择器
- 以下就是我目前遇到的所有的 伪类选择器:
选择器 例子 描述 a元素(其他元素一样适用) :linka:link 匹配所有未被访问的链接 :visiteda:visited 匹配所有已经访问过的链接 :activea:active 匹配被点击的链接 :hovera:hover 匹配鼠标悬停其上的元素 表单元素 :focusinput:focus 匹配获得焦点的 <input>元素:checkedinput:checked 匹配处于选中状态的 <input>元素:disabledinput:disabled 匹配每个被禁用的 <input>元素:requiredinpuy:required 匹配指定了 required属性的<input>元素:validinput:valid 匹配所有具有有效值的 <input>元素:read-onlyinput:read-only 匹配指定了 readonly属性的<input>元素:read-writeinput:read-write 匹配不带 readonly属性的<input>元素:enabledinput:enabled 匹配每个已启用的 <input>元素:in-rangeinput:in-range 匹配具有指定取值范围的 <input>元素:invalidinput:invalid 匹配所有具有无效值的 <input>元素:optionalinput:optional 匹配不带 required属性的<input>元素:out-of-rangeinput:out-of-range 匹配值在指定范围之外的 <input>元素选择子元素 :first-childp:first-child 匹配父元素中的第一个子元素 <p>,<p>必须是父元素中的第一个子元素:last-childp:last-child 匹配父元素中的最后一个子元素 <p>,<p>必须是父元素中的最后一个子元素:nth-child(n)p:nth-child(2) 匹配父元素中的第二个子元素 <p>:nth-last-child(n)p:nth-last-child(2) 匹配父元素中的倒数第二个子元素 <p>:first-of-typep:first-of-type 匹配父元素中的第一个 <p>元素:last-of-typep:last-of-type 匹配父元素中的最后一个元素 <p>:nth-last-of-type(n)p:nth-last-of-type(2) 匹配父元素中的倒数第二个子元素 <p>:nth-of-type(n)p:nth-of-type(2) 匹配父元素中的第二个子元素 <p>:only-of-typep:only-of-type 匹配父元素中唯一的 <p>元素:only-childp:only-child 匹配父元素中唯一的子元素 <p>其他伪类选择器 :lang(language)p:lang(it) 匹配每个 lang属性值以it开头的<p>元素:emptyp:empty 匹配任何没有子元素的 <p>元素:not(selector):not(p) 匹配每个非 <p>元素的元素:rootroot 匹配元素的根元素,在HTML中,根元素永远是 HTML:target#news:target 匹配当前活动的 #news元素(单击包含该锚的URL)
关于:link、:visited、:hover、:active伪类选择器使用的注意事项:
- :link:定义普通或未访问链接的样式;
- :visited:定义已经访问过链接的样式;
- :hover:定义当鼠标经过或悬停在链接上时的样式;
- :active:定义点击链接时的样式;
- 通过上面的四个伪类选择器,您可以像给普通文本定义样式那样,为链接定义任何想要的 CSS 样式,例如颜色、字体、背景、边框等。
注意:
- 在定义四个伪类选择器时需要按照一定的顺序,一般情况下
:hover必须位于:link和:visited之后,:active必须位于:hover之后。
在 Chrome、Firefox、Safari 等主流的 Web 浏览器中,都为链接定义了一套默认的样式,如果不专门为链接设置样式,浏览器则会使用默认的链接样式。
普通链接:带有 下划线 的 蓝色 文本;
已访问的链接:带有 下划线 的 紫色 文本;
点击链接时:带有 下划线 的 红色 文本;
经过或悬停在链接上时:链接的外观并没有变化,它将保持 先前状态的颜色。
- 除了上面这些伪类选择器,:is、:has、:where这些新增的伪类选择器在开发中也是能够帮助我们解决一些问题(之前需要使用JS进行配合,现在不使用JS通过这些伪类选择器也能解决);
一、:has()
1.1 作用
- 通过 子元素 找到 父元素,给父元素设置相应的样式;
- 通过一个兄弟节点,找到上一个或上面所有的兄弟节点,设置相应的样式;
1.2 语法
选择器:has(选择器) {}
1.3 使用示范
<style>
    div {
        width: 300px;
        height: 300px;
        margin: 10px auto;
        border: 2px solid #ccc;
    }
    /* 通过子元素找到父元素,给父元素设置相应的样式 */
    /* 看 div 里面是否包含 span 元素,如果有,设置的背景颜色就会生效 */
    div:has(span) {
        background-color: red;
    }
    /* 给 紧挨着 div 的 下一个兄弟节点 h1 设置 字体颜色 */
    div + h1 {
        color: aqua;
    }
    /* 给紧挨着 h1 的 上一个兄弟节点 div 设置 字体颜色 */
    div:has(+ h1) {
        color: blue;
    }
    /* 给 h1 前面 所有的兄弟节点 设置 字体颜色 */
    div:has(~ h1) {
        color: blue;
    }
</style>
<body>
    <div>
        <span>hello word</span>
    </div>
    <div>hello world</div>
    <h1>hello world</h1>
    <h1>hello world</h1>
</body>
 

1.4 示例展示
- 按照以往的方式,以下效果需要我们使用JS才能完成,现在有了:has伪类选择器,我们单靠CSS就能实现;
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    ul {
        display: flex;
        justify-content: center;
        align-items: flex-end;
        flex-wrap: nowrap;
        width: 800px;
        height: 100px;
        margin: 100px auto;
        border: thick double #32a1ce;
    }
    li {
        list-style: none;
        width: 50px;
        height: 50px;
        border: 1px solid #333;
        border-radius: 50%;
        background-color: #2cff02;
        font-size: 30px;
        text-align: center;
        line-height: 50px;
        cursor: pointer;
        transition: .2s;
    }
    li:hover {
        width: 80px;
        height: 80px;
        font-size: 40px;
        line-height: 80px;
    }
    /* 当前 hover li 的上一个li(当前li的下一个li被hover) */
    li:has(+ li:hover),
    /* 当前 hover li的 下一个 li */
    li:hover + li {
        width: 65px;
        height: 65px;
        font-size: 35px;
        line-height: 65px;
    }
</style>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
    </ul>
</body>

二、:is() / :where()
2.1 作用
- 相当于是一个条件,将满足条件的进行筛选,添加样式;
2.2 语法
:is(选择器) 选择器 {}
:where(选择器) 选择器 {}
2.3 优点
2.3.1 选择器之间相互独立
- 基于本小节的例子来说,按照传统的方式去写,虽然也能实现效果,但是如果我想要将鼠标放在第二个h1上的时候,字体变大一些,但是我的:hover写错了,那么传统写法的样式就会不生效,因为它是将他们看作是一个规则,中间的某一个不对,整个规则就不会生效; 
- 而使用:is / :where伪类选择器,即使你将:hover写错,其他没有:hover的也会生效:    - 注意:
- 当检测:where伪类选择器的时候,需要先将传统方式的选择器注释掉,因为:where伪类选择器的优先级太低了,样式会被传统样式覆盖掉;
 
- 当检测
 
- 注意:
2.3.2 可以写一些逻辑表达式
- 示例展示:
<sytle> /* :is([id^="d_"][name$="_div"]) h1 { color: blue; } */ :where([id^="d_"][name$="_div"]) h1 { color: blue; } </style> <body> <div id="d_1" name="d1_div"> <h1>hello JavaScript</h1> </div> <div id="d2"> <h1>hello php</h1> </div> <div id="d_3" name="d3_div"> <h1>hello java</h1> </div> <div id="d4"> <h1>hello Python</h1> </div> <div id="d_5"> <h1>hello c++</h1> </div> </body> 
2.4 注意 - 权重问题

- 同样的写法,两个伪类选择器的优先级不一样,:is的优先级高于:where的优先级;
- :is:- 找选择其中权重最大的一个,做为整个伪类选择器的权重;
- 按照本小节的例子来说,会在:is(#d1, #d2, #d3, #d4)中选择一个权重最大的一个,再加上一个标签选择器的权重,组成最终的权重;
 
- :where:- 该伪类选择器是没有权重的,也就是它的权重为0;
- 按照本小节的例子来说,:where(#d1, #d2, #d3, #d4)的权重为0,此时最终的权重为标签选择器的权重;
 
2.5 示例展示
<style>
    div {
        font-size: 30px;
    }
    /*
        实现需求:
            选择前四个h1,并设置字体颜色
    */
    /* 普通做法 */
    /* 当 id 很多的时候,代码就显得很冗余 */
    #d1 h1,
    #d2 h1,
    #d3 h1,
    #d4 h1 {
        color: blue;
    }
    /* 使用 is 伪类选择器 */
    /* 查找 #d1, #d2, #d3, #d4 这四个id 下面的 h1 元素 */
    :is(#d1, #d2, #d3, #d4) h1 {
        color: #ff004c;
    }
    /* 使用 where 选择器 */
    /* 查找 #d1, #d2, #d3, #d4 这四个id 下面的 h1 元素 */
    :where(#d1, #d2, #d3, #d4) h1 {
        color: #ff004c;
    }
</style>
<body>
    <div id="d1">
        <h1>hello JavaScript</h1>
    </div>
    <div id="d2">
        <h1>hello php</h1>
    </div>
    <div id="d3">
        <h1>hello java</h1>
    </div>
    <div id="d4">
        <h1>hello Python</h1>
    </div>
    <div id="d5">
        <h1>hello c++</h1>
    </div>
</body>

转载自:https://juejin.cn/post/7285719262961418296




