选择器的优先级
各等级选择器
-
0级
-
通配符
-
选择符:+ > ~ || 空格
-
逻辑组合伪类::not() :is() :where()
-
1级
-
标签选择器
-
2级
-
类选择器
-
属性选择器:.box[data-type="wuhu"]{color:#666}
-
伪类:.box:hover
-
3级
-
ID选择器
-
4级
-
内联属性
-
5级
-
!important
选择器优先级的计算规则
业界流传甚广的数值计算法
body.foo:not([foo]){color:white}
// body 标签选择器 +1
// .foo 类选择器 +10
// :not 逻辑伪类 +1
// [foo] 属性选择器 +10
// 21
不同等级之间的选择器是无法跨越优先级的,也就是说,11个类选择器也无法覆盖掉一个ID选择器的样式
CSS选择器最佳实践
命名建议全部小写
.box
.class-name
.header-nav
不要使用ID选择器
实在是想用的话,可以属性选择器替代,它的优先级和类选择器一样。如[id="someId"]{}
以为ID选择器的优先级实在是太高了。
不要使用嵌套选择器
如:
1、.nav .li div {}
2、.box .pic .icon {}
如今使用的sass less使得嵌套程度更深
缺点如下:
- 渲染性能差
- 优先级混乱
- 样式布局脆弱
有两方面对渲染性能造成影响,1是标签选择器,2是过深的嵌套。
选择器性能
- ID选择器
- 类选择器
- 标签选择器
- 通配符
- 属性选择器
- 部分伪类::checked
其中ID选择器性能最好,与类选择器相差无几
.box>div{color:white}
这么看似乎不错的用法,其实很糟糕。
因为css选择器是从右往左进行匹配渲染的,也就是说会先匹配所有的div元素,再匹配.box类,如果页面都是div一把梭的话,会带来明显的渲染性能问题。
不过如果页面相对简单的话,其实可以不用太过于考虑这方面的问题,影响微乎其微。但复杂且元素多的话,就需要考虑了。
正确的选择器用法
使用无嵌套的纯类名选择器
<nav class="cs-nav">
<li class="cs-nav-li"></li>
<li class="cs-nav-li"></li>
</nav>
.cs-nav{}
.cs-nav-li{}
而不是像这种
<div class="box">
<figure class="pic"><img src="./example.png” alt="示例图片">
<figcaption><i class="icon"></i>图片标题</figcaption>
</figure>
</div>
.box {}
.box .pic {}
.box .pic .icon {}
可以考虑使用tailwindcss和unocss
选择符
-
后代选择符(空格)
-
子选择符 >
-
相邻兄弟选择符 +
-
随后兄弟选择符 ~
-
双管道选择符 ||
后代选择符: ul li{color:white} 匹配ul下的所有li
子选择符: ul > li{color:red} 匹配ul下的第一层li,深层嵌套不匹配
相邻兄弟选择符: h1 + h2 {color:red} 同一层下匹配h1后面的第一个h2
随后兄弟选择符 h1 ~ h2{color:pink} 同一层下匹配h1后面的所有h2
双管道选择符 主要用于table
后代选择符 子选择符 相邻兄弟选择符 随后兄弟选择符 示例 .foo .bar {l .foo > .bar {) .foo + .bar {) .foo ~ .bar {y col.brother || td{color:red} .border占表格的两列,也就是匹配这两列的所有td
属性选择器
-
[attr="val"]
-
[attr~="val"]
-
[attr|="val"]
-
[attr^="val"]
-
[attr$="val"]
-
[attr*="val"]
12345[name="1 2"]{color:pink} 匹配name="1 2"的元素[name~="1"]{color:red} 匹配name的值里含有1的元素
[name|="val"]{color:blue} 匹配name的值以val为开头的元素,它的值要么是val要么是val- 也就是说name="value"是不会被匹配到的
以下三个可以加i来无视大小写 [name^="val" i] 匹配以val开头的所有元素 val val-1 value都会匹配到
[name$="val" i] 匹配以val结尾的所有元素
[name*="val" i] 匹配包含字符val的所有元素,像是JS正则test的用法
各种伪类
:hover
在鼠标移动到元素时触发,以下代码为鼠标移入元素时背景色变为pink
// html
<div></div>
// style
div{
width:100px;
height:100px;
border:solid 1px black;
}
div:hover{
background:pink
}
:active
当鼠标主键按下时,则触发active。如下代码,当主键按下时,div的背景色将会变为pink
// html
<div></div>
// style
...其它样式
div:active{
background:pink
}
:focus
一般使用在可输入的元素下使用的伪类,如:input textarea,或是contenteditable设置为true的div元素。
// html
<input type="type"/>
// style
...其它样式
input:focus{
background:pink
}
如果普通的div也想要有focus的话,可以设置一个属性tabindex="0"或者tabindex="-1"
0和-1的区别就是-1不能被tab触发,0可以。
:focus-within
和focus仅在当前元素聚焦时匹配不同,focus-within会在当前元素或其子元素聚焦时都会匹配
<div tabindex="0" class="box">
<div tabindex="0" class="box-s"></div>
</div>
.box:focus-within{
background:pink
}
:visited
用于a标签,匹配已访问过的链接
<a href="https://www.bilibili.com">BLBL</a>
a:visited{
color:red
}
:target
可以匹配锚点,就是那个用于定位的锚点。例子如下:
// 这是一个链接:https://www.bilibili.com/#box
// html
<div id="box"></div>
// css
div:target{
background:pink
}
上述代码被定位到的那个元素,会触发:target样式。
:enabled和:disabled
主要用于button和input元素,与元素属性enabled(启用)和disabled(禁用)并用。enabled可以不设置,因为默认就是启用状态
<button disabled></button>
<button></button>
// style
button:disabled{
background:pink
}
button:enabled{
background:red
}
:read-only和:read-write
只作用于input和textarea,默认就是read-write,可不做额外设置。
<textarea readonly></textarea>
<textarea></textarea>
// style
textarea:read-only{
...样式
}
textarea:read-write{
...样式
}
:placeholder-shown
当输入框的placeholder内容显示的时候,触发该伪类。可用于空值判断
<input type="text" placeholder="请输入"/>
// style
input:placeholder-shown{
...
}
:checked
匹配表单控件中设置了checked的元素。
<input type="radio" checked />
// style
input[type=radio]:checked{
...
}
:valid和:invalid
匹配验证通过(valid)或验证不通过(invalid)的表单。如下输入框,只允许输入3位英文字母。
<input type="text" pattern="[a-zA-Z]{3}" />
// style
// 输入通过
input:valid{
color:green
}
// 输入不通过
input:invalid{
color:red
}
:in-range和out-of-range
主要应用于<input type="number" />和<input type="range" />控件,且需要设置min和max属性。顾名思义,:in-range伪类就是匹配输入的值在范围内的控件,:out-of-range反之。
:not()和:is()和:where()
<div></div>
<div wuhu></div>
// style
div:not([wuhu]){
background:pink
}
div:is([wuhu]){
background:red
}
很语义化的伪类,:not([wuhu])的意思就是,当div的属性没有wuhu这个属性时匹配样式。再比如:not(li),这一段指的就是当元素不为li时匹配样式。is反之。:where作用与:is相同,不同为:where优先级为0
:has()
是个很强大的伪类。但是兼容性不太好,FF不支持。Chrome和EDGE的版本得105往上,在safari中则很早开始支持了。
<div>
<p></p>
</div>
// style
div:has(p){
background:pink
}
上述代码指的是当div里有p标签时,则会将background设为pink
大致上就是这些,其他不经常用到的或者经常用到的就不做介绍了。可以自行去MDN查看