我们已经有了css3,那么什么时候有css4呢?你会希望有css4吗?不管是希望还是不希望,它都已经在成为标准的路上了。虽然css4 选择器目前还在工作草案阶段,但是已经有小部分的选择器已经被大部分主流浏览器所支持了。接下来我将介绍css 选择器 level 4 中的4组伪类选择器。
首先看一下css选择器所包含的所有内容。
1. :is() 和 :where()
这两个伪类选择器从字面上就可以看出它们的含义,就是对元素进行一个选择。这两个伪类的主要作用就是可以大大简化css选择器。特别是在做一些层次比较深的全排列时。
例如,下面👇例子,section、artice、aside、nav中的每一个都与其余三个组合了一下
在:is和:where出现前,我们可能要这么写,😭😭😭
/** Level 0 **/
h1 {
font-size: 30px;
}
/** Level 1 **/
section h1, article h1, aside h1, nav h1 {
font-size: 25px;
color: red;
}
/** Level 2 **/
section section h1,section article h1,section aside h1,section nav h1,article section h1,
article article h1,article aside h1,article nav h1,aside section h1,aside article h1,
aside aside h1,aside nav h1,nav section h1,nav article h1,nav aside h1,nav nav h1 {
font-size: 20px;
color: green;
}
使用:is后变得非常简单😄😄😄
/* Level 0 */
h1 {
font-size: 30px;
}
/* Level 1 */
:is(section, article, aside, nav) h1 {
font-size: 25px;
color: red;
}
/* Level 2 */
:is(section, article, aside, nav) :is(section, article, aside, nav) h1 {
font-size: 20px;
color: green;
}
/* 甚至还能Level 3 */
:is(section, article, aside, nav) :is(section, article, aside, nav) :is(section, article, aside, nav) h1 {
font-size: 15px;
}
:is和:where都接受【使用逗号分隔的列表】如(span, div) 作为它的参数,元素只要能匹配到该列表中的任何一条规则,就可以被选中:is和:where的区别在于选择器的优先级,:where()的优先级总是0,但是:is()的优先级是由它列表参数中优先级最高的选择器决定的
<style>
.header .p, .main .p {
color: green;
}
:is(.header, .main) .p {
color: purple;
}
:where(.header, .main) .p {
color: red;
}
.p {
color: blue;
}
</style>
<main class="main">
<p class="p">What is the text color?</p>
</main>
样式优先级计算
优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:
- 如果存在内联样式,那么 A = 1, 否则 A = 0;
- B 的值等于 ID选择器 出现的次数;
- C 的值等于 类选择器 和 属性选择器 和 伪类 出现的总次数;
- D 的值等于 标签选择器 和 伪元素 出现的总次数 。
:is的浏览器支持程度
:where的浏览器支持程度
2. :not() 和 :has()
或许大家在平时开发的时候,碰到过类似下图的需求,希望一个list的最后一项不要有margin-bottom
在:not出现之前,可能要像下面这样写
li + li {
margin-top: 20px;
}
/* 或者 */
li {
margin-bottom: 20px;
}
li:last-child {
margin-bottom: 0px;
}
使用:not选择器,可以语义清晰地解决这个问题
li:not(:last-child){
margin-bottom: 20px;
}
虽然 CSS 选择器已经非常强大了,但一直以来,在 CSS 中没有从子元素选到父元素的样的选择器(父选择器)。就是通过子元素来控制父元素的样式。
比如说我们有一个卡片:
- 如果卡片里面包含的是
span标签,我们希望给卡片边框加厚 - 如果卡片里面包含的是
img标签,我们希望卡片没有边框 - 如果卡片里面包含的是
a标签,我们希望卡片有背景色
像这种情况,可能要像下面这样写
.card1 {
border: black solid 8px;
}
.card2 {
border: none;
}
.card3 {
border: black solid 8px;
background-color: lightgrey;
}
使用:has选择器,可以这样写。语义变得更加清晰了,也不用绞尽脑汁地给card取名字
.card:has(span){
border: black solid 8px;
}
.card:has(img){
border: none;
}
.card:has(a){
border: black solid 8px;
background-color: lightgrey;
}
从1990年开始就有人提出要在css标准中加入这个选择器,一直到现在它也是呼声很高的选择器之一。
目前Igalia公司在替chrome实现这个选择器。他们最新的一次提交在今年的七月份,目前的实现版本支持下面这些情况。
- :has为终点
.a .b:has(.c) {...} - :has不为终点
.a:has(.b) .c {...} - 内嵌:has
.a:has(.b:has(.c)) {...} - 包含:is
.a:has(:is(.b .c))
:not的浏览器支持程度
:has的浏览器支持程度
3. :empty (css3选择器) 和 :blank
在现代 Web 的开发的过程中,总是无法避免数据吐出为空的情况,此时往往会给我们的 UI 带来额外的麻烦。比如说,在同一类的 UI 元件中编写了一定的样式规则,但数据为空,此时在页面上可能会出现这样的场景
CSS 的 :empty 和 :blank 两个伪类选择器可以帮助我们避免这种现象。这两个选择器可以给空元素添加样式,以及创建空的状态
那么什么是空元素呢?他们之间的差异又是什么?
先来回答第一个问题,何为空元素?空元素是指元素没有任何子元素或子节点,比如:
:empty 和 :blank 相比,:empty 只能选中没有子元素的元素。子元素只可以是元素节点或文本(包括空格)。:blank 要比 :empty 灵活地多,只要该元素中无任何子元素都能被识别。上面👆的三个示例都会被:blank认为是空的。目前还没有浏览器支持:blank,但是Mozilla有一个功能类似的伪类:moz-only-whitespace。下面👇的示例就是在火狐浏览器的结果。
不过 W3C 规范对该伪类选择器的定义更趋向于作用到表单控件中,比如用户没有在 input 或 textarea 中输入内容时,提交表单能被识别到。有点类似于表单验证的功能。
:empty的浏览器支持程度
:blank的浏览器支持程度
4. :focus-visible 和 :focus-within
大家对于 :focus 应该不会感到陌生,早期对于可聚焦元素可以使用 :focus 来给元素设置焦点状态下的 UI 风格,即焦点环样式:
Chrome 86 开始,另外引入了 :focus-visible 和 :focus-within 两种伪类选择器来帮助我们更好的控制 UI 焦点环的样式:
虽然 :focus 、:focus-within 和 :focus-visible 都可以用来设置焦点环的样式,但他们之间还是有一定的差异:
:focus:当用户使用鼠标点击焦点元素或使用键盘的Tab键(或快捷键)触发焦点元素焦点环的样式
:focus-visible:只有使用键盘的Tab键(或快捷键)触发焦点元素焦点环的样式。如果仅使用:focus-visible设置焦点环样式的话,那么用户使用鼠标点击焦点元素时不会触发焦点环样式
:focus-within:表示一个元素获得焦点,或该元素的后代元素获得焦点。这也意味着,它或它的后代获得焦点,都可以触发:focus-within
来简单的看一个示例:
codepen.io/amilelne/pe… 可以发现,分别使用鼠标点击按钮和按
Tab让按钮获得焦点时焦点环样式效果不同:
有没有人想问为什么要把鼠标点击和Tab键点击,做成不一样的焦点环样式呢?或者说,为什么要焦点环样式。对于正常使用鼠标点击的情况,完全不需要焦点环样式,像我们平时工作中,不会给这种按钮做焦点环样式,对于默认自带焦点环样式的,直接outline: 0。但是对于Tab键操作,焦点环样式是a11y所倡导的。
网络无障碍辅助功能(Accessibility,也被称为 a11y)是一种可以帮助所有人获得服务的设计和创造。无障碍辅助功能是使得辅助技术正确解读网页的必要条件。
当网页上有多个元素时,焦点环样式可以帮助用户突出显示哪些元素有键盘焦点。这有助于依赖键盘的用户导航,因为它显示了键盘将与哪些元素交互。注意力或短期记忆受限的用户也会从有关注意力所在的视觉线索中受益。
像react的官网就做得很好。
那么:focus-within又有什么用呢?个人认为它可能会给表单样式带来新的活力💪
:focus-visible的浏览器支持程度
:focus-within的浏览器支持程度