先看看这个样例的效果
🍉
🍊
🍈
🍇
🥝
🍋
🍌
🍍
🥭
🍎
🍏
🍐
🍑
🍒
🍓
🫐
🍅
🫒
:has()
伪类与属性选择器
我们通过下边这个小案例来了解一下这俩选择器
属性选择器
我是
我是
1
2
3
4
5
6
7
|
<!-- 鼠标摸在它们上边会被添加伪元素 -->
<div linkto='box1'>我是</div>
<div linkto='box2'>我是</div>
<style>
div[linkto='box1']:hover::after{content:'box1'}
div[linkto='box2']:hover::after{content:'box2'}
</style>
|
在这个例子中,两个div没有任何类名,不过都被赋予了一个自定义属性linkto
。我们可以借此通过[linkto='box1']
来选中他们,赋予伪元素。
如何使用
除了这个例子中的完全匹配某个属性值,属性选择器还有很多其它用法:
匹配属性名称
img[alt]
这个选择器会选择所有拥有alt属性的img元素,无论alt内容是什么。
完全匹配属性
img[hidden="true"]
这个选择器会选择所有拥有hidden属性并且属性值为true的img元素,我们为这个选择器添加display:none
样式就能方便的隐藏元素了。
匹配存在某个属性值
img[tag~="hd"]
这个选择器能找到所有拥有tag属性且存在hd这个属性值的img元素,例如上边这个选择器能选中<img tag="hd cover"/>
、<img tag="sport football hd"/>
这些元素。
匹配拥有某个前缀的属性值
匹配前缀有两种方式:
span[lang|="zh"]
这个选择器能选择所有lang属性值以’zh-‘开头的span元素,例如<span lang="zh-TW">
、<span lang="zh-CN">
。
img[type^="low"]
这个选择器可以选择所有type属性以’low’开头的img元素,例如<img type="lowPower"/>
、<img type="lowLevel"/>
。它与上边的区别是可以匹配不使用’-‘来分割的单词。
匹配拥有某个后缀的属性值
img[type$="ball"]
这个选择器可以选择所有type属性以’ball’结尾的img元素,例如<img type="football"/>
、<img type="basketball"/>
。
匹配含有某个字符串的属性值
img[type*="0"]
这个选择器可以选择所有type属性包含'0’的img元素,例如<img type="110"/>
、<img type="4008208820"/>
。
:has()
伪类
1
2
3
4
5
6
7
8
9
10
|
<div class="cont-box">
<!-- 摸在这些盒子上,下边的disply-box将会显示伪元素 -->
<div linkto='box3'>我是</div>
<div linkto='box4'>我是</div>
</div>
<div class="disply-box"></div>
<style>
.cont-box:has(>[linkto="box3"]:hover) + .disply-box::after{content:'box3'}
.cont-box:has(>[linkto="box4"]:hover) + .disply-box::after{content:'box4'}
</style>
|
因为被hover的元素被cont-box包裹了,直接通过后续兄弟选择器无法选择到父亲的兄弟。我们可以通过给父亲:has()
伪类来间接选择。
关于:has()
选择器
当括号内的选择器成立时,该伪类就会生效。
h1:has(+ p)
这个例子中,将相邻兄弟选择器放入。当某个h1标签后边紧跟着一个p标签,那么这个伪类就会生效。这样你可以给p标签前边的h1标签赋予样式而其它h1标签不受影响。
.cont-box:has(>[linkto="box4"]:hover)
我们解读一下例子里的选择器;括号里的内容是>[linkto="box4"]:hover
,意思是存在某个子元素,这个子元素的linkto属性值为box4,并且正在被鼠标摸着。再搭配:has()伪类,就是找到存在这么个子元素的.cont-box,为其赋予样式。
完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
<div class="filter">
<input checked type="radio" name="filter" id="all"/>
<label for="all">所有</label>
<input type="radio" name="filter" id="yellow"/>
<label for="yellow">黄色</label>
<input type="radio" name="filter" id="red"/>
<label for="red">红色</label>
<input type="radio" name="filter" id="green"/>
<label for="green">绿色</label>
<input type="radio" name="filter" id="purple"/>
<label for="purple">紫色</label>
</div>
<div class="fruit-cont">
<div c="r">🍉</div><div c="y">🍊</div><div c="g">🍈</div>
<div c="p">🍇</div><div c="g">🥝</div><div c="y">🍋</div>
<div c="y">🍌</div><div c="y">🍍</div><div c="y">🥭</div>
<div c="r">🍎</div><div c="g">🍏</div><div c="g">🍐</div>
<div c="r">🍑</div><div c="r">🍒</div><div c="r">🍓</div>
<div c="p">🫐</div><div c="r">🍅</div><div c="g">🫒</div>
</div>
<style>
.filter{display: flex;cursor: pointer;user-select: none;}
.filter label{
width: calc(25% - 12px);
box-sizing: border-box;
margin: 6px;
height: 40px;
line-height: 36px;
text-align: center;
border-radius: 8px;
border: 2px solid;
}
.filter input{display: none;}
.fruit-cont{display: flex;flex-wrap: wrap;}
.fruit-cont div{
display: none;
width: calc(25% - 12px);
box-sizing: border-box;
margin: 6px;
height: 60px;
line-height: 60px;
text-align: center;
font-size: 30px;
text-shadow: 0 0 6px white;
border-radius: 8px;
}
.filter:has(>#yellow:checked) ~ .fruit-cont div[c="y"]{display: block}
.filter:has(>#green:checked) ~ .fruit-cont div[c="g"]{display: block}
.filter:has(>#red:checked) ~ .fruit-cont div[c="r"]{display: block}
.filter:has(>#purple:checked) ~ .fruit-cont div[c="p"]{display: block}
.filter:has(>#all:checked) ~ .fruit-cont div{display: block}
.fruit-cont div[c="r"]{background-color: #e74c3c}
.fruit-cont div[c="g"]{background-color: #2ecc71}
.fruit-cont div[c="p"]{background-color: #9b59b6}
.fruit-cont div[c="y"]{background-color: #f39c12 }
.filter label[for="red"]{border-color: #e74c3c;color: #e74c3c;}
.filter label[for="green"]{border-color: #2ecc71;color: #2ecc71;}
.filter label[for="purple"]{border-color: #9b59b6;color: #9b59b6;}
.filter label[for="yellow"]{border-color: #f39c12 ;color: #f39c12 ;}
.filter label[for="all"]{border-color: black;color: black ;}
.filter input:checked + label[for="red"]{background-color: #e74c3c;color: white;}
.filter input:checked + label[for="green"]{background-color: #2ecc71;color: white;}
.filter input:checked + label[for="purple"]{background-color: #9b59b6;color: white;}
.filter input:checked + label[for="yellow"]{background-color: #f39c12 ;color: white;}
.filter input:checked + label[for="all"]{background-color: black ;color: white;}
</style>
|
相关知识
:has()伪类
属性选择器