详解16个CSS新特性(2021最新版-上)

详解16个CSS新特性(2021最新版-上)_第1张图片

 2021 CSS 的新特性和之前两年的相比有相似也有不同,本文就带大家看看今年的 CSS 到底说了什么。


简介

如果您有关注过这两年的 CSS 发展状态报告(2019年和2020年)的话,不难发现,在报告中有专门关于 CSS 新特性一项的介绍。

详解16个CSS新特性(2021最新版-上)_第2张图片

图片by 2020 年 CSS 发展状态报告(https://2020.stateofcss.com/en-US/features/)

是不是有种似有相识的感觉,或者有一些又是那么的陌生。

对于我而言,这些都不陌生。不过我想说的是上图(或者报告)中提到的只是冰山一角,有很多是没有出现在调查问卷和报告中。

比如接下来内容中提到的伪类选择器,内容可见性,容器查询等等。

嗯!先从 CSS 选择器开始!(^_^)

CSS伪类选择器

CSS 选择发展到今日,可以说是一个庞大的体系了:

详解16个CSS新特性(2021最新版-上)_第3张图片

图片by  @linxz 的博客

现在描述 CSS 选择器的规范主要有 CSS (指的是 CSS 2.1),后面分为选择器 Level 3 和 Level 4。伪类选择器在这三部分规范中都有出现过,他们是一个递进的过程,特别是在 Level 3 和 Level 4,在原有的基础上新增了不少优秀的选择器。今天要提到的几个现代伪类选择器就是出于 Levele 4:

详解16个CSS新特性(2021最新版-上)_第4张图片

  :is() 和 :where()

先来看 :is() 和 :where() 。Elad Shechter 曾在推特上发了一个关于 :is() 和 :where() 选择器的测试题:

详解16个CSS新特性(2021最新版-上)_第5张图片

如果你是第一次看到这样的测试题,请先自测一下,如果是你,你会选择哪个答案(green,purple,red 还是 blue)?

如果你选择的是 purple ,那么要恭喜你,你答对了。 

详解16个CSS新特性(2021最新版-上)_第6张图片

Demo 地址:https://codepen.io/airen/full/ExWxbKe

示例中出现了 :is() 和 :where() 两个可能你从未接触过的伪类选择器:

:is(.header, .main) .p {  color: purple}:where(.header, .main) .p {  color: red;}

其实这两个选择器等同于:

.header .p,.main .p {  color: purple;}.header .p,.main .p {  color: red;}

他们唯一不同之处,就是选择器权重不同。:where() 的优先级总是为 0 ,但是 :is() 的优先级是由它的选择器列表中优先级最高的选择器决定的。那么上面的示例中,我们可以用下图来清晰的描述他们之间的关系:

详解16个CSS新特性(2021最新版-上)_第7张图片

图片by   twitter

即,下面三个选择器选中的相同的元素:

.header .p,
.main .p {
  // ...
}


:is(.header, .main) .p {
  // ...
}


:where(.header, .main) .p {
  // ...
}

不同的是他们的权重不同,其中:

.header .p,
.main .p {
  // ....
}


:is(.header, .main) .p {
  // ...
}

示例中的两种选择器具有相同的权重(即020);其中:

:where(.header, .main) .p {
  // ...
}


.p {
  // ...
}

上面示例代码中的选择器具有相同权重(即 010):

详解16个CSS新特性(2021最新版-上)_第8张图片

:is() 和 :where() 伪类选择器的出现,将会让我们的选择器变得更简洁,比如下成这个 :is() 的示例:

// Level 0
h1 {
  font-size: 30px;
}
//  Level 1 
p h1, article h1, aside h1, nav h1 {
  font-size: 25px;
}
// Level 2 
p p h1, p article h1, p aside h1, p nav h1,
article p h1, article article h1, article aside h1, article nav h1,
aside p h1, aside article h1, aside aside h1, aside nav h1,
nav p h1, nav article h1, nav aside h1, nav nav h1, {
  font-size: 20px;
}

使用 :is() 可以像下面这样来描述:

// Level 0
h1 {
  font-size: 30px;
}
// Level 1
:is(p, article, aside, nav) h1 {
  font-size: 25px;
}
// Level 2 
:is(p, article, aside, nav)
:is(p, article, aside, nav) h1 {
  font-size: 20px;
}

回过头来,请大家再看看下面这个测试题,请问 p 文本的颜色是什么?

What is the text color?

// CSS:where(.header, .main) .p { color: red;}.p { color: blue;}:is(.header, .main) .p { color: purple;}.header .p,.main .p { color: green;}

查看答案:https://codepen.io/airen/full/dyvyJmW

 :not() 和 :has()


或许大家平时在开发前端页面的时候,碰到类似下图这样的需求:

详解16个CSS新特性(2021最新版-上)_第9张图片

希望最后一张卡片没有margin-bottom (或第一张卡片没有 margin-top)。

针对于这样的场景,:not() 选择器就非常有优势。为什么这么说呢?

在没有 :not() 选择器的时候,你可能会想到下面这样的方式:

.card + .card {
  margin-top: 20px;
}  


// 或


.card {
  margin-bottom: 20px;
}


.card.card--last { // 也可能会使用 .card:last-child
  margin-bottom: 0;
}

如果换成 :not() 选择器,可以这要来实现:

.card:not(:last-child) {
  margin-bottom: 20px
}

效果如下:

详解16个CSS新特性(2021最新版-上)_第10张图片

Demo URL: https://codepen.io/airen/full/MPNLEo

虽然 CSS 选择器已经非常强大了,但一直以来,在 CSS 中没有从子元素选到父元素的样的选择器(父选择器):

详解16个CSS新特性(2021最新版-上)_第11张图片

有人提出希望有一个 :parents() 这样的选择器!

虽然直到目前为止还没有 :parents() 选择器,但庆幸的是,:has() 选择器即将到来,它可以用来选择父级元素。

目前 Igalia 公司正在为 Chrome 实现该选择器,其团队成员 Brian Kardell 新发表的《Can I :has()》文章中对 :has() 选择器进行了详细的阐述。

H1 Level Title

H2 Level Title

Text Paragraphs

/* CSS */ // 将匹配含有h1子元素的 p元素 p:has(h1) { border-color: blue; } // 将匹配含有h2子元素的 p元素 p:has(h2) { border-color: #09f; } // 将匹配含有p子元素的 p元素 p:has(p) { border-color: red; } // 将匹配除了含有p子元素的 p元素 p:not(:has(p)) { margin-bottom: 30px; }

在支持:has()的浏览器中,你将看到下图这样的效果:

详解16个CSS新特性(2021最新版-上)_第12张图片

示例中还演示了 :not() 和 :has() 组合在一起使用的,但两者组合在一起所达到的意思却完全不一样。

其中 :not(:has(selector)) 匹配不含有 selector 元素的父元素,而 :has(:not(selector)) 匹配含有的不是 selector 子元素的元素。

两者主要区别在于,:has(:not(selector)) 写法必须要含有一个子元素,而 :not(:has()) 可以不含有元素也会被匹配。

有意思的是,Github 中有一个 Issue 在讨论** **:has-child()** 选择器**,或许哪一天,我们在组件中就可以这样使用:

详解16个CSS新特性(2021最新版-上)_第13张图片

  :empty 和 :blank


在现代 Web 的开发的过程中,总是无法避免数据吐出为空的情况,此时往往会给我们的 UI 带来额外的麻烦。比如说,在同一类的 UI 元件中编写了一定的样式规则,但数据为空,此时在页面上可能会出现这样的场景:

详解16个CSS新特性(2021最新版-上)_第14张图片

CSS 的 :empty 和 :blank两个伪类选择器可以帮助我们避免这种现象。这两个选择器都很有用:

  • 给空元素添加样式

  • 创建空的状态

既然都是可以为空元素添加样式,那何为空元素,他们之间的差异又是什么?先来回答第一个问题,何为空元素?空元素是指元素没有任何子元素或子节点,比如:


:empty 和 :blank 相比,:empty 只能选中没有子元素的元素。子元素只可以是元素节点或文本(包括空格)。注释或处理指令都不会产生影响。

Demo: https://codepen.io/airen/full/yLMLKyo

注意,在空元素上即使使用伪元素 ::before 或 ::after 创建内容,也能被:empty 识别。

:blank 要比 :empty 灵活地多,只要该元素中无任何子元素都能被识别。

不过 W3C 规范对该伪类选择器的定义更趋向于作用到表单控件中,比如用户没有在 input 或 textarea 中输入内容时,提交表单能被识别到。有点类似于表单验证的功能。

早在 2018 年 Zell Liew 在推特上就针对 :empty 和 :blank 做过相关的讨论,并发表一了篇有关于这方面的博文《:empty and :blank》:

详解16个CSS新特性(2021最新版-上)_第15张图片

到目前为止,:empty 已得到主流浏览器支持,可以用于实际生产中,但 :blank 伪类选择器还是存在一定的争议的。

  :focus-visible 和 :focus-within


CSSer 对于 :focus 应该不会感到陌生,早期对于可聚焦元素可以使用 :focus 来给元素设置焦点状态下的 UI 风格,即焦点环样式:

详解16个CSS新特性(2021最新版-上)_第16张图片

Chrome 86 开始,另外引入了 :focus-visible 和 :focus-within 两种伪类选择器来帮助我们更好的控制 UI 焦点环的样式:

详解16个CSS新特性(2021最新版-上)_第17张图片

虽然 :focus 、:focus-within 和 :focus-visible 都可以用来设置焦点环的样式,但他们之间还是有一定的差异:

  • :focus :当用户使用鼠标点击焦点元素或使用键盘的 Tab 键(或快捷键)触发焦点元素焦点环的样式

  • :focus-visible :只有使用键盘的 Tab 键(或快捷键)触发焦点元素焦点环的样式。如果仅使用 :focus-visible 设置焦点环样式的话,那么用户使用鼠标点击焦点元素时不会触发焦点环样式

  • :focus-within:表示一个元素获得焦点,或该元素的后代元素获得焦点。这也意味着,它或它的后代获得焦点,都可以触发 :focus-within

来简单的看一个示例:

button:focus { 
  outline: 2px dotted #09f; 
  outline-offset: 2px; 
} 


button:focus-visible { 
  outline: 2px solid #f36; 
  outline-offset: 2px; 
}

你会发现,分别使用鼠标点击按钮和按Tab 让按钮获得焦点时焦点环样式效果不同: 

详解16个CSS新特性(2021最新版-上)_第18张图片

不过需要注意的是,:focus 和 :focus-visible 也会涉及到选择器权重的问题,就上面的示例来说,如果我们把 :focus 选择器对应的样式放置到 :focus-visible 之后:

button:focus-visible { 
  outline: 2px solid #f36; 
  outline-offset: 2px; 
}


button:focus { 
  outline: 2px dotted #09f; 
  outline-offset: 2px; 
}

这个时候,你会发现不管用户使用键盘 Tab 键还是鼠标让 

你可能感兴趣的:(java,css,人工智能,编程语言,javascript)