一个冒号开头的叫伪类(Pseudo-class),作用是一个修饰元素的where条件,例如:h1:hover是指被hover的h1元素;两个冒号叫伪元素(Pseudo-element),本质是一个真实存在的元素,例如:h1::before是h1的内容部分最前面添加一个元素,他没有真正的dom标签,但是是确实存在的元素。
伪类
伪类目前已经超过60个了,参考mdn,这里列出最常使用的,和一些好用新加的伪类。
使用率最高的伪类
:activea或button被鼠标按下的时候。:checkedradio/checkbox/select被选中的时候。:focus获得焦点的时候。:focus-within焦点元素是自己或自己的子元素。:disabled/:enabled被禁用、启用的元素。:hover鼠标悬停:first-child/:last-child/:nth-child()自己是作为长子、小儿子、第x个儿子。:only-child自己是独子。
功能强大的组合伪类
:is()满足一些条件的元素,可以实现代码的简化,is(div h1) is(span h2)是四种组合。:where()与is的不同就是where所有选择器优先级(特异性)是0,最低优先级,适用于需要应用样式但不想增加优先级的场景。:not()不满足一些条件的元素。:has()新特性中介绍
使用率不高但很有用的伪类
:in-rangeinput中如果定义了min/max属性,并且值在这个范围内的时候。:invalidinput中输入了无效值的时候,例如上面range不符合的时候,再比如email type中非email格式文本。:requiredinput有required属性的时候。:empty没有children的元素。:link没有visit过的a元素。
新特性
:dir([ltr | rtl])元素的文本方向,ltr是从左到右,rtl是从右到左。:has(selector)在元素内部有符合selecor条件的子元素时,该父元素的样式,通俗讲就是根据子元素选择父元素。
组合使用
not is where has等这些本身就是函数,可以和其他css选择器组合使用,这里有个理解的关键:伪类也是一些where条件,但是要先满足前面的样式的情况下,再满足伪类才行。
.item:first-child需要元素首先得具有item样式,然后再满足是父元素下的首个元素:first-child;
.item :first-child这个代空格的就不一样他其实是指item下的子元素,这个子元素必须是首个元素,而这个元素不需要有item样式;
下面展示了基本的用法,这个例子中有个重要的应用场景,就是用一个元素的状态div2被hover的时候,会导致fixed元素的隐藏和展示,这是之前需要用js才能实现的效果,现在css就可以胜任了。has not这两个伪类给css带来了新的可能。
伪元素
伪元素有20来个,但是很多都是试验性阶段,最常见的其实就是两个::before和::after,用来在元素前后添加元素,实现一些标记的功能。简单说几个可能会用到的其他伪类:
::file-selector-button上传文件的按钮的样式用这个。::first-letter首字母的样式用这个。::first-line首行样式用这个。::selection选中文本的样式用这个。::backdrop一般用于模态窗口,背景的样式用这个。::-webkit-scrollbar仅适用于webkit内核的浏览器,firefox不可用,滚动条的样式用这个。
after/before的妙用
1 可以在元素前后添加元素,实现一些标记的功能,比如下拉下拉菜单的箭头,下面的例子中用hover和click两种方式的纯css实现了dropdown的效果,其中click方式有很多借鉴意义,他是巧妙使用了label + checkbox的checked状态,来实现了点击触发的逻辑。
2 一些装饰性的元素,例如camel-ui中下拉框右上角有个烟囱的形状,就是使用:before伪元素充当的。

代码如下
.select-container .listbox::before {
content: '';
position: absolute;
top: -13px;
right: 35px;
width: 30px;
height: 16px;
background-color: white;
border-left: 3px solid var(--w-indigo-dark);
border-right: 3px solid var(--w-indigo-dark);
border-radius: 1px;
}
小结
介绍了伪类和伪元素,大多数是比较常用的,这里着重学习is has not的用法,会让开发事半功倍。