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

上篇指路:详解16个CSS新特性(2021最新版-上)

CSS 等比缩放

CSS 等比缩放一般指的是 “容器高度按比例根据宽度改变”,很多时候也称为宽高比或纵宽比。

众所周知,我们开发 Web 页面要面对的终端更复杂的了,而这些终端的宽高比都不一样。常见的比例有:

特别是在做媒体相关开发的同学,比如视频、图像等,这方面的需求会更多,比如 Facebook 上的图片,视频展示:

CSS 在还没有 aspect-ratio 之前,常使用一些 Hacck 手段来实现实类似的效果,即使用 padding-top 或 padding-bottom 来实现:

<aspectratio-container> <aspectratio-content></aspectratio-content>
</aspectratio-container> <style>.aspectratio-container { width: 50vmin; /* 用户根据自己需要设置相应的值 */ /* 布局方案可以调整 */ display: flex; justify-content: center; align-items: center; } /* 用来撑开aspectratio-container高度 */ .aspectratio-container::after { content: ""; width: 1px; padding-bottom: 56.25%; /*元素的宽高比*/ margin: -1px; z-index: -1; }
</style>

有了 CSS 自定义属性之后,可以结合 calc() 函数来实现容器等比缩放的效果:

.container {--ratio: 16/9;height: calc(var(--width) * 1 / (var(--ratio)));width: 100%;
}

虽然比padding-top 这样的Hack 手段简单,但相比原生的aspect-ratio还是要复杂的多。即:

.container {width: 100%;aspect-ratio: 16 / 9;
}

下面这个示例演示了这三种不同方案实现宽比的效果:

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

还可以通过 @media  让元素在不同的终端上按不同的比例进行缩放:

.transition-it {aspect-ratio: 1/1;transition: aspect-ratio .5s ease;@media (orientation: landscape) { & {aspect-ratio: 16/9;}}
}

CSS 滚动捕捉

在 Web 布局中,时常会碰到内容溢出容器的现状,如果 overflow 设置为 auto 或 scroll 时容器会出现水平或垂直滚动条:

为了给用户提供更好的滚动体验,CSS 提供了一些优化滚动体验的 CSS 特性,其中滚动捕捉就是其中之一。CSS 的滚动捕捉有点类似于 Flexbox 和 Grid 布局的特性,分类可用于滚动容器的属性和滚动项目的属性:

有了滚动捕捉特性,我们要实现类似下图的效果就可以不需要依赖任何 JavaScript 库或脚本:

就是每次滚动时,图片的中心位置和容器中心位置对齐(想象一下 Swiper 的效果)。关键代码就下面这几行:

.container {scroll-behavior: smooth;overflow-x: auto;-webkit-overflow-scrolling: touch;scroll-snap-type: x mandatory;scroll-padding: 20px;
}img {scroll-snap-align: center;scroll-snap-stop: always;
}

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

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

要是再利用一点点JavaScript脚本,还可以实现沉浸式讲故事的交互效果:

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

CSS Gap(沟槽)

CSS 的 gap 属性的出现,帮助我们解决了以前一直比较麻烦的布局效果:

正如上图所示,设计师期望的一个效果是,紧邻容器边缘没有任何间距,但相邻项目之间(水平或垂直方向)都有一定的间距。在没有 gap 属性之前使用 margin 是很烦人的,特别是多行多列的时候更麻烦。有了 gap 仅需要一行代码即可。

CSS 的 gap 属性是一个简写属性,分为 row-gap 和 column-gap :

该属性 gap 到目前为止只能运用于多列布局,Flexbox布局和网格布局的容器上:

// 多列布局
.multi__column { gap: 5ch
} // Flexbox布局
.flexbox { display: flex; gap: 20px
} // Grid布局
.grid { display: grid; gap: 10vh 20%
}

gap 属性可以是一个值,也可以是两个值:

.gap { gap: 10px;
}
// 等同于
.gap { row-gap: 10px; column-gap: 10px
} .gap { gap: 20px 30px;
}
// 等同于
.gap { row-gap: 20px; column-gap: 30px;
}

如果 gap 仅有一个值时,表示 row-gap 和 column-gap 相同。

CSS 逻辑属性

国内大多数 Web 开发者面对的场景相对来说比较单一,这里所说的场景指的是书写模式或排版的阅读模式。一般都是 LTR (Left To Right)。但有开发过国际业务的,比如阿拉伯国家的业务,就会碰到 RTL (Right To Left) 的场景。比如你打开 Facebook ,查看中文和阿拉伯文两种语言下的 UI 效果:

在没见有逻辑属性之前,一般都会在 <html> 或 <body> 上设置 dir 属性,中文是 ltr ,阿拉伯语是 rtl ,然后针对不同的场景运用不同的 CSS 样式:

其实,阅读方式除了水平方向(ltr 或 trl)之外,还会有垂直方向的阅读方式:

为了让 Web 开发者能更好的针对不同的阅读模式提供不同的排版效果,在CSS新增逻辑属性。有了逻辑属性之后,以前很多概念都有所变化了。比如我们以前熟悉的坐标轴,x 轴和 y 轴就变成了 inline 轴 和 block 轴,而且这两个轴也会随着书写模式做出调整:

除此之外,我们熟悉的 CSS 盒模形也分物理盒模型和逻辑盒模型:

你可能感知到了,只要是以前带有 top、right 、bottom 和 left 方向的物理属性都有了相应的 inline-start 、 inline-end 、block-start 和 block-end 的逻辑属性:

我根据 W3C 规范,把物理属性和逻辑属性映射关系整了一份更详细的表:

回到实际生产中来:

如果不使用逻辑属性的话,要实现类似上图这样的效果,我们需要这样来编写 CSS:

.avatar {margin-right: 1rem;
}html[dir="rtl"] .avatar {margin-right: 0;margin-left: 1rem;
}

有了 CSS 逻辑属性之后,仅一行 CSS 代码即可实现:

.avatar {margin-inline-end: 1rem;
}

简单多了吧,特别是有国际化需求的开发者,简直就是一种福音。

CSS 媒体查询

CSS 媒体查询 又称为 CSS 条件查询。在 Level 5 版本中提供了一些新的媒体查询特性,可以查询到用户在设备上的喜好设置:

比如:

  • prefers-reduced-motion

  • prefers-contrast

  • prefers-reduced-transparency

  • prefers-color-scheme

  • inverted-colors

使用的方式和以往我们熟悉的是相似。比如 prefers-color-scheme 实现暗黑查式的皮肤切换效果:

// 代码源于:https://codepen.io/airen/full/ProgLL
// dark & light mode
:root {/* Light theme */--c-text: #333;--c-background: #fff;
}body {color: var(--c-text);background-color: var(--c-background);
}@media (prefers-color-scheme: dark) {:root {/* Dark theme */--c-text: #fff;--c-background: #333;}
}

还可以根据网格数据设置来控制资源的加载:

@media (prefers-reduced-data: reduce) {header {background-image: url(/grunge.avif);}
}@media (prefers-reduced-data: no-preference) {@font-face {font-family: 'Radness';src: url(megafile.woff2);}
}

其他的使用方式和效果就不一一演示了。不过在未来,CSS 的 @media 在编写方式上会变得更简单:

@media (width <= 320px) {body {padding-block: var(--sm-space);}
}@custom-media --motionOK (prefers-reduced-motion: no-preference);@media (--motionOK) {.card {transition: transform .2s ease;}
}.card {@media (--motionOK) { & {transition: transform .2s ease;}}
}@media (1024px >= width >= 320px) {body {padding-block: 1rem;}
}

特别声明,该示例代码来自于 @argyleink 的 PPT 。

自从折叠屏设备的出现,给 Web 开发者带来新的挑战:

值得庆幸的是,微软和三星的团队就针对折叠屏幕设备提供了不同的 媒体查询判断。

上图是带有物理分隔线的双屏幕设备:

main {display: grid;gap: env(fold-width);grid-template-columns: env(fold-left) 1fr;
}@media (spanning: single-fold-vertical) {aside {flex: 1 1 env(fold-left);}
}

无缝的折叠设备:

@media (screen-fold-posture: laptop){ body { display: flex; flex-flow: column nowrap; } .videocall-area, .videocall-controls { flex: 1 1 env(fold-bottom); }
}

CSS 比较函数

CSS 的比较函数是指 min() 、max()  和 clamp() ,我们可以给这几个函数传入值(多个)或表达式,它们会对传入的值进行比较,然后返回最合适的值。另外,这几个和我们熟悉的 calc() 类似,也可以帮助我们在 CSS 中做动态计算。

  min() 和 max()

先看 min() 和 max() ,它们之间的差异只是返回值的不同:

  • min() 函数会从多个参数(或表达式)中返回一个最小值作为CSS属性的值,即 使用 min() 设置最大值,等同于 max-width

  • max() 函数会从多个参数(或表达式)中返回一个最大值作为CSS属性的值,即 使用 max() 设置最小值,等同于 min-width

下图展示了 min(50vw, 500px) 在浏览器视窗宽度改变时,返回的值的变化:

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

把上面的示例的 min() 换成 max() 函数,即 max(50vw, 500px),它的返回值是:

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

  clamp()

clamp() 和 min() 以及 max() 略有不同,它将返回一个区间值,即 在定义的最小值和最大值之间的数值范围内的一个中间值。该函数接受三个参数:

  • 最小值(MIN)

  • 中间值(VAL),也称首选值

  • 最大值(MAX)

clamp(MIN, VAL, MAX),这三个值之间的关系(或者说取值的方式):

  • 如果 VAL 在 MIN 和 MAX 之间,则使用 VAL 作为函数的返回值

  • 如果 VAL 大于 MAX ,则使用 MAX 作为函数的返回值

  • 如果 VAL 小于 MIN ,则使用 MIN 作为函数的返回值

比如下面这个示例:

.element { /** * MIN = 100px * VAL = 50vw ➜ 根据视窗的宽度计算 * MAX = 500px **/ width: clamp(100px, 50vw, 500px);
}

就这个示例而言,clamp() 函数的计算会经历以下几个步骤:

.element { width: clamp(100px, 50vw, 500px); /* 50vw相当于视窗宽度的一半,如果视窗宽度是760px的话,那么50vw相当等于380px*/ width: clamp(100px, 380px, 500px); /* 用min()和max()描述*/ width: max(100px, min(380px, 500px)) /*min(380px, 500px)返回的值是380px*/ width: max(100px, 380px) /*max(100px, 380px)返回的值是380px*/ width: 380px;
}

示例效果如下:

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

简单地说,clamp() 、min() 和 max() 函数都可以随着浏览器视窗宽度的缩放对值进行调整,但它们的计算的值取决于上下文。

我们来看一个比较函数中 clamp() 的典型案例。假设我们需要在不同的屏幕(或者说终端场景)运用不同大小的 font-size :

在还没有 CSS 比较函数之前,使用了一个叫 CSS 锁(CSS Locks)的概念来实

现类似的效果:

需要做一些数学计算:

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

使用 clamp() 之后,只需要一行代码就可以实现:

/** minf: 20px (min font-size)* maxf: 40px (max font-size)* current vw: 100vw* minw: 320px (min viewport's width)* maxw: 960px (max viewport's width)
*/
h1 {font-size: clamp(20px, 1rem + 3vw, 40px);
}

使用这方面的技术,我们就可以轻易实现类似下图这样的效果:

注,上图来自《Use CSS Clamp to create a more flexible wrapper utility》一文。

CSS 内容可见性

CSS 内容可见性,说要是指 content-visibilit 和 contain-intrinsic-size 两个属性,目前隶属于 W3C 的 CSS Containment Module Level 2 模块,主要功能是可以用来提高页面的渲染性能。

一般来说,大多数Web应用都有复杂的UI元素,而且有的内容会在设备可视区域之外(内容超出了用户浏览器可视区域),比如下图中红色区域就在手机设备屏幕可视区域之外:

在这种场合下,我们可以使用CSS的 content-visibility 来跳过屏幕外的内容渲染。也就是说,如果你有大量的离屏内容(Off-screen Content),这将会大幅减少页面渲染时间。

Google Chrome 团队有工程师对 content-visibility 做过相关的测试:

使用了 CSS 的 content-visibility 属性,浏览器的渲染过程就变得更加容易。本质上,这个属性 改变了一个元素的可见性,并管理其渲染状态。

而 contain-intrinsic-size 属性控制由 content-visibility 指定的元素的自然尺寸。它的意思是,content-visibility 会将分配给它的元素的高度(height)视为 0,浏览器在渲染之前会将这个元素的高度变为 0,从而使我们的页面高度和滚动变得混乱。但如果已经为元素或其子元素显式设置了高度,那这种行为就会被覆盖。如果你的元素中没显式设置高度,并且因为显式设置 height可能会带来一定的副作用而没设置,那么我们可以使用contain-intrinsic-size来确保元素的正确渲染,同时也保留延迟渲染的好处。

换句话说,contain-intrinsic-size 和 content-visibility 是一般是形影不离的出现:

section {content-visibility: auto;contain-intrinsic-size: 1000px;
}

CSS 内在尺寸

如果你使用浏览器开发者工具审查代码时,将鼠标放到一个 <img> 标签上,你会看到类似下图这样的:

<img> 的 src 路径上浮出来的图片底下有一行对图像的尺寸的描述,即252 x 158 px (intrinsic: 800 x 533 px) ,其实现这表述图片尺寸中两个重要信息:

  • 外在尺寸:252 x 158 px ,开发者给 img 设置的尺寸

  • 内在尺寸:800 x 533 px ,图片原始尺寸

其实在 CSS 中给一个元素框设置大小时,有的是根据元素框内在的内容来决定,有的是根据上下文来决定的。根据该特性,CSS的尺寸也分为内部(内在)尺寸和外部(外在)尺寸。

  • 内部尺寸:指的是元素根据自身的内容(包括其后代元素)决定大小,而不需要考虑其上下文;而其中 min-content 、 max-content 和 fit-content 能根据元素内容来决定元素大小,因此它们统称为内部尺寸。

  • 外部尺寸:指的是元素不会考虑自身的内容,而是根据上下文来决定大小。最为典型的案例,就是 width 、min-width 、max-width 等属性使用了 % 单位的值。

通地一个简单的示例来向大家演示 CSS 内在尺寸的特性,即 min-content 、max-content 和 fit-content 的特性。

<h1>CSS is Awesome</h1><style>h1 {width: auto;}
</style>

先来看 h1 的 width 取值为 auto 和 min-content 的差异:

// 外在尺寸
h1 {width: auto; // 根据容器变化
}// 内在尺寸
h1 {width: min-content; // 根据内容变化
}

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

从上图中不难发现,width 取值为 min-content 时,h1 的宽度始终是单词“Awesome”长度(大约是144.52px)。它的宽度和容器宽度变化并无任何关系,但它受排版内相关的属性的影响,比如font-size、font-family 等。

再来看max-content :

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

当h1 的 width 取值为 max-content 时,它的宽度是h1 所在行所有内容的宽度。最后来看 fit-content :

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

相对而言,fit-content 要比 min-content 和 max-content 复杂地多:

h1 {width: fit-content;
}// 等同于
h1 {width: auto;min-width: min-content;max-width: max-content;
}

简单地说,fit-content 相当于 min-content 和 max-content,其 取值:

  • 如果元素的可用空间(Available)充足,fit-content 将使 用 max-content

  • 如果元素的可用空间(Available)不够充足,比 max-content 小点,那就是用可用空间的值,不会导致内容溢出

  • 如果元素的可用空间(Available)很小,比 min-content还小,那就使用 min-content

使用下图来描述它们之间的关系:

min-content、max-content 和 fit-content 被称之个内在尺寸,它可以运用于设置容器尺寸的属性上,比如width 、height 以及 inline-size 和 block-size 等。但有些属性上使用的话则会无效:

  • min-content、max-content 和 fit-content 用于 flex-basis 无效

  • fit-content 用于设置网格轨道尺寸的属性上无效

  • 网格项目或Flex项目上显式设置 width:fit-content也无效,因为它们的默认宽度是 min-content

  • 最好不要在 min-width 或 max-width 上使用 fit-content,易造成混乱,建议在 width 上使用 fit-content

在布局上使用 min-content 、max-content 或 fit-content 可以帮助我们设计内在布局,另外在构建一些自适应的布局也非常灵活。特别是和 CSS 的 Grid 和 Shapes 相关特性结合,还能构建一些具有创意的布局。

最后有一点需要特别声明,fit-content 和 fit-content()函数不是相同的两个东东,使用的时候需要区对待。

CSS 的display

display 对于大家而言并不陌生,主要用来格式化上下文,这里特别拿出来和大家说的是因为 display 也有一些变化。其中之一就是 display 未来可以支持多个值:

据最新的消息,Sarafi 浏览器已经把display 设置两个值已进入实验性属性。display 取两个值的含义大致如下:

另外单独要说的是,display 新增了 contennts 属性值, W3C规范是这样描述的:

大致意思是说:

设置了 display: contents 的元素自身将不会产生任何盒子,但是它的子元素能正常展示。

比如:

<div class="outer">I'm, some content<div class="inner">I'm some inner content </div>
</div><style>.outer {border: 2px solid lightcoral;background-color: lightpink;padding: 20px;}.innter {background-color: #ffdb3a;padding: 20px;}
</style>

上面这个简单地示例代码,你将看到的效果如下:

如果我们在.outer 元素上显式设置 display: contents ,该元素本身不会被渲染,但子元素能够正常渲染:

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

在某些布局中,特别是不希望调整 HTML 的结构的时候,我们就可以使用该特性。比如在 Flexbox 或 Grid 中,希望把其他后代元素变成网格项目或 Flex项目,那就可以这样做:

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

display: contents 在规范讨论阶段和 display: subgrid 的讨论中是非常的激烈,最终是 display:contents 获胜了。你现在在Grid的布局中,也没有单独的display: subgrid ,而是将subgrid 移入到 grid-template-columns 和 grid-template-rows 中。

另外还有一个比较大的争执就是 display: contents 和 Web 可访问性方面的。有关于这方面的讨论,你要是感兴趣的话,可以阅读:

  • More accessible markup with display: contents

  • Display: Contents Is Not a CSS Reset

CSS 的 @规则

CSS 中的 @ 规则有很多种,但大家比较熟悉的应该是 @import 、@media 和 @supports 之类的。今天给大家简单的提几个不常见的,比如:

  • 用于嵌套的 @nest 和 @apply

  • 用于注册自定义属性的 @property

  • 最近讨论比较多的容器查询 @container

  • @argyleink 在新分享的PPT提到的 @scope 和 @layer

  CSS 的嵌套

使用过 CSS 处理器的同学,应该用过嵌套来组织自己的代码,比如 SCSS:

// SCSS
foo {color: red;& bar {color: green;}
}

上面的代码经过编译之后:

// CSS
foo {color: red;
}foo bar {color: green;
}

庆幸的是,W3C 也在讨论和定义CSS中的嵌套规则。目前两种规则:

foo {color: red;@nest bar {color: green;}
}// 或者
foo {color: red;& bar {color: green;}
}// 都等同于
foo {color: red;
}foo bar {color: green;
}

也可以和媒体查询 @media 相互嵌套:

article {color: darkgray;& > a {color: var(--link-color);}
}code > pre {@media (hover) {&:hover {color: hotpink;}}
}code > pre {@media (hover) {@nest &:hover {color: hotpink;}}
}article {@nest section:focus-within > & {color: hotpink;}
}main {padding: var(--space-sm);@media (width >= 540px) { & {padding: var(--space-lg);}}
}

除了 @nest 之外还有 @apply 。你可能在一些前端的框架或构建器中看到过 @apply:

如果你在 Chrome  Canary 浏览器“实验性属性” 就可以直接体验 @apply :

简单地说,它有点类似于 SCSS 中的混合宏 @mixin 和 @extend :

:root {--brand-color: red;--heading-style: {color: var(--brand-color);font-family: cursive;font-weight: 700;}
}h1 {--brand-color: green;@apply --heading-style;
}

  CSS Houdini 变量 @property

@property 是用来注册一个变量的,该变量是一个 CSS Houdini 中的变量,但它的使用和 CSS 中的自定义属性(CSS变量)是一样的,不同的是注册方式:

// Chrome 78+
// 需要在 JavaScript脚本中注册
CSS.registerProperty({'name': '--custom-property-name','syntax': '<color>','initialValue': 'black','inherits': false
})// Chrome 85+
// 在CSS文件中注册
@property --custom-property-name {'syntax': '<color>','initialValue': 'black','inherits': false
}

他的最大特色之一就是可以指定已注册的 CSS 变量的类型、初始值,是否可继承:

上图截取于 Maxi 在推特上发的推文

虽然它的使用方式和 CSS 的自定义属性相似,但它要更强大,特别是在动效方面的使用,能增强 CSS 的动效能力,甚至实现一些以前 CSS 无法实现的动效。比如:

@property --hue {initial-value: 0;inherits: false;syntax: '<number>';
}@keyframes rainbow {to {--hue: 360;}
}
@property --milliseconds {syntax: '<integer>';initial-value: 0;inherits: false;
}
.counter {counter-reset: ms var(--milliseconds);animation: count 1s steps(100) infinite;
}@keyframes count { to {--milliseconds: 100;
}}

把它和 CSS Houdini 的 Paint API 结合起来,可做的事情更多:

更多这方向的效果可以在 houdini.how 网站上查阅:

  容器查询 @container 

Una Kravets 在 Google I/O 开发大会上就分享了容器查询 @container ,她把它称为新的响式布局所需特性之一:

那么容器查询 @container 可以做什么呢?假设你的设计师给你提供了一份像下图这样的设计稿:

你可能首先会想到的是 @media  (在没有容器查询之前,似乎也只有这样的方式),而有了@container 之后,就可以换过一种姿势:

这两张图上来自于 @shadeed9 的 《CSS Container Queries For Designers》一文,他的另一篇文章《Say Hello To CSS Container Queries》也是介绍容器查询的。

看上去非常强大,事实上也很强大,并且它的使用和 @meida 非常相似:

// Demo: https://codepen.io/una/pen/mdOgyVL
.product {contain: layout inline-size;
}@container (min-width: 350px) {.card-container {padding: 0.5rem 0 0;display: flex;}.card-container button {/* ... */}
}

Demo: https://codepen.io/una/pen/mdOgyVL

对于 @container 特性,有叫好的,也有不同的,比如 Kenton de Jong 在他的新博文《Why I am not a fan of  CSS container  queries》阐述了自己不喜欢该t特性:

就我个人而言,我是很喜欢这个特性,后面会花一定的时间深入了解和学习 @container。当然有讨论是一件好事,这样会让该特性更成熟。

  @layer  和 @scope

我以前只看到过 @scope 规则,主要是用来处理 CSS 中样式规则作用域相关的,但并没有深入了解过。Una Kravets 在 Google I/O 开发大会分享上再次看到了 @scope :

上图是 Miriam Suzanne 绘制的!

@scope 内的样式允许穿透和特定组件的样式,以避免命名冲突,许多框架和插件(如CSS模块)已经使我们能够在框架内做到这一点。现在,这个规范将允许我们为我们的组件编写具有可读性的CSS的本地封装样式,而不需要调整标记。

/* @scope (<root>#) [to (<boundary>#)]? { … } */@scope (.tabs) to (.panel) {:scope { /* targeting the scope root */ }.light-theme :scope .tab { /* contextual styles */ }
}

怎么看上去和 Web Componed中的 Scope 那么的相似呢?

对于 @layer ,我第一见:

@layer reset {* { box-sizing: border-box; }body { margin: 0; }
}
// ...
@layer reset { /* add more later */ }@import url(headings.css) layer(default);
@import url(links.css) layer(default);@layer default;
@layer theme;
@layer components;@import url(theme.css) layer(theme);@layer default, theme, components;@import url(theme.css) layer(theme);@layer framework.theme {p {color: rebeccapurple;}
}@layer framework {@layer theme {p { color: cyan; }}
}

上面代码表示啥意思,我也还没整明白,只知道 @layer 被称为层叠层(Cascade Layers)。该特性是 什么 W3C 层叠和继承规范 Level5 中新提出来的。

其他

在我分享结束没多久,正在整理这篇文章的时候,发现我的偶像 @argyleink 也分享了一个相似的话题《Hover:CSS! What's New in 2021?》,分享了 31 个 CSS 相关的特性,并且按风险级别分为高、中、低三档:

你会发现,和我整理的特性有很多稳合之处。如果你听过他去年在伦敦CSS大会分享的《London CSS: What‘s New in 2020?》,你会发现 2021 年的是 2020 年的升级版。

✿  拓展阅读

作者|大貘

编辑|橙子君

出品|阿里巴巴新零售淘系技术

详解16个CSS新特性(2021最新版-下)相关推荐

  1. HDFS(下):NameNode和SecondaryNameNode、HDFS工作机制、故障处理、集群安全模式、服役退役节点、集群黑白名单、DataNode多目录详解、HDFS2.x新特性

    接上篇,上篇文章传送门:HDFS(上):HDFS优缺点.HDFS操作.HDFS客户端操作.HDFS的API.HDFS数据流.HDFS的IO流.HDFS读写数据流程.HDFS文件处理详解.windows ...

  2. 万字详解,JDK1.8新特性的Lambda、Stream和日期的使用详解

    前言 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本. Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScr ...

  3. C++ map 使用详解(含C++20新特性)

    目录 访问元素 迭代器 容量 修改操作 查找 std::swap(std::map) std::erase_if (std::map) 简介 map 是一个关联容器,它提供一对一的数据处理能力(其中第 ...

  4. C++ string 使用详解(含C++20新特性)

    目录 元素访问 迭代器 容量 操作 查找 std::erase, std::erase_if (std::basic_string) std::basic_string 简介 basic_string ...

  5. C++ unordered_map 使用详解(含C++20新特性)

    目录 查找元素 迭代器 容量 修改操作 通接口 哈希策略 观察器 std::swap(std::unordered_map) std::erase_if (std::unordered_map) 简介 ...

  6. C++ std::thread 和 std::jthread 使用详解 (含C++20新特性)

    目录 std::thread std::thread 构造函数 观察器 操作 std::jthread std::jthread 构造函数 观察器 操作 停止记号处理 管理当前线程的函数 yield( ...

  7. mysql insert 不需要日志_详解MySQL|你不知道的新特性-8.0错误日志增强

    MySQL 8.0 重新定义了错误日志输出和过滤,改善了原来臃肿并且可读性很差的错误日志. 比如增加了 JSON 输出,在原来的日志后面以序号以及 JSON 后缀的方式展示. 比如我机器上的 MySQ ...

  8. 阿里巴巴淘系技术:超详|2020年你不应该错过的CSS新特性

    @argyleink在第四次的伦敦(LondonCSS 2020)CSS活动中分享了一个有关于CSS特性相关的话题.看了一下这个主题的PPT,里面有些新东西还是蛮有意思的.基于该PPT,我稍微整理近2 ...

  9. html盒子移动动画代码,详解盒子端CSS动画性能提升

    流畅动画的标准 理论上说,FPS 越高,动画会越流畅,目前大多数设备的屏幕刷新率为 60 次/秒,所以通常来讲 FPS 为 60frame/s 时动画效果最好,也就是每帧的消耗时间为 16.67ms. ...

最新文章

  1. [Silverlight入门系列]使用MVVM模式(6):使用Behavior
  2. 深入思考:算法工程师的落地能力具体指什么,如何提升自己的落地能力?
  3. 分布式ID业界解决方案
  4. XML文档注释(C#)
  5. Windows系统中使用SSH服务端和客户端
  6. Spark2 文件处理和jar包执行
  7. 7种方式实现3栏布局
  8. ubuntu20.04 LTS安装谷歌拼音输入法
  9. 三洋p6系列伺服电机说明书_兰州同步伺服电机维修-川其实业
  10. 图的遍历详解(广度优先和深度优先)
  11. 树莓派pythongpio编程_基于树莓派的python GPIO编程-常用函数综合整理
  12. c语言整型常量后加l或u,《软考程序员》整型常量
  13. 实现百度地图marker平滑移动
  14. 特斯拉 开源_开源与癌症作斗争,特斯拉采用Coreboot,Uber和Lyft发行开源机器学习...
  15. 编程浅谈-以一个初出茅庐的Java程序员视角
  16. STM32单片机直流电机PID速度控制正反转控制(霍尔磁铁测速)LCD1602
  17. Java基础Day01-Java基础语法
  18. Voyager的路由
  19. RFID珠宝防盗系统
  20. 计算机毕业设计SSM宠物领养系统【附源码数据库】

热门文章

  1. Javaweb-Servlet总结(概述、接口使用、配置、获取请求方式、路径操作、Request对象、Response对象)
  2. DELL EqualLogic PS6100存储硬盘坏道数据恢复
  3. SpringMVC学习笔记——视频补充2
  4. 微软老将Philip Su的离职信:回首12年职场生涯
  5. 360浏览器收藏夹的文件存放位置在哪
  6. LINUX编译OpenJDK 9
  7. 数字化转型新型能力体系建设指南
  8. python里import bs4是什么意思_from bs4 import BeautifulSoup 引入需要安装的文件和步骤...
  9. 荷兰商业银行调查显示,公众对加密货币的兴趣未来将翻倍
  10. HTML网页设计作业:文化网站设计——基于HTML古典中国风工艺美术网页设计(9页)...