div 内 frame 有时候不加载_2020年你不应该错过的CSS新特性(完)

本文介绍了CSS中的contain和content-visibility属性如何提高Web性能,以及数据服务如何根据用户偏好节省网络数据。此外,还探讨了变量字体的使用和Web可访问性的新特性:focus-visible与:focus-within,帮助开发者优化用户体验。
摘要由CSDN通过智能技术生成

茫茫人海中与你相遇

5d7eea49faa42e0dec65f4d5477ac066.png

相信未来的你不会很差

作者:阿里巴巴淘系技术

来源:https://juejin.im/post/6886258269137043464

Web性能

contain 和 content-visibility

这两个属性是属于 CSS容器模块 的,其最大的特点应该是可以帮助Web开发者提高Web页面的性能:

当容器的内容发生变化时,浏览器考虑到其他元素可能也会发生变化,于是就会去检查页面中所有的元素。一直以来浏览器都是这么做的,大家都习以为常了。但从另一方面来说,开发者很清楚当前修改的元素是否独立、是否影响其他元素。因此如果开发者能把这个信息通过CSS告诉浏览器,那么浏览器就不需要再去考虑其他元素了,这就是非常完美的事情。而CSS容器模块中的contain属性就为我们提供了这种能力。

们来看@Manuel Rego Casasnovas在《An introduction to CSS Containment》文章中提供的一个示例:

假设一个页面有很多个元素,在这个示例中,我们有10000个这样的元素:

<div class="item">    <div>Lorem ipsum...div>div>

使用JavaScript的textContent这个API来动态更改div.item > div的内容:

const NUM_ITEMS = 10000; const NUM_REPETITIONS = 10; function log(text) {     let log = document.getElementById("log");     log.textContent += text; } function changeTargetContent() {     log("Change \"targetInner\" content...");     // Force layout.     document.body.offsetLeft;     let start = window.performance.now();     let targetInner = document.getElementById("targetInner");     targetInner.textContent = targetInner.textContent == "Hello World!" ? "BYE" : "Hello World!";     // Force layout.     document.body.offsetLeft;     let end = window.performance.now();     let time = window.performance.now() - start; log(" Time (ms): " + time + "\n");     return time; } function setup() {     for (let i = 0; i < NUM_ITEMS; i++) {         let item = document.createElement("div");         item.classList.add("item");         let inner = document.createElement("div");         inner.style.backgroundColor = "#" + Math.random().toString(16).slice(-6);         inner.textContent = "Lorem ipsum...";         item.appendChild(inner);         wrapper.appendChild(item);     } }

如果不使用contain,即使更改是在单个元素上,浏览器在布局上的渲染也会花费大量的时间,因为它会遍历整个DOM树(在本例中,DOM树很大,因为它有10000个DOM元素):

dde13ffd255061d3e08c166ca217cafc.png

在本例中,div的大小是固定的,我们在内部div中更改的内容不会溢出它。因此,我们可以将contain: strict应用到项目上,这样当项目内部发生变化时,浏览器就不需要访问其他节点,它可以停止检查该元素上的内容,并避免到外部去。

409fcc900dfe34ae71778caa49c86c89.png

CSS容器模块中的content-visibility属性会显著影响第一次下载和第一次渲染的速度。此外,你可以立即与新渲染的内容交互,而无需等待内容的其余部分加载。该属性强制用户代理跳过不在屏幕上的标记和绘制元素。实际上,它的工作方式类似于延迟加载,只是不加载资源,而是渲染资源。

简单地说,CSS的content-visibility属性 可跳过不在屏幕上的内容渲染,包括布局(Layout)和渲染(Paint),直到真正需要布局渲染的时候为止。所以利用它可以使用初始用户加载速度更快,还能与屏幕上的内容进行更快的交互。

4cbbba6f82a835fa5364b380c8972f49.png

上图来自于@Una Kravets和@Vladimir Levin的《content-visibility: the new CSS property that boosts your rendering performance(web.dev/content-vis…: auto属性可使分块的内容区域的初始加载性能提高7倍。

数据服务

数据服务指的是 Data Saver。啥意思呢?不做解释,直接用一段代码来描述:

@media (prefers-reduced-data: reduce) {    header {        background-image: url(/grunge.avif);    }}

我想大家对于@media (prefers-reduced-data: reduce)应该不会陌生吧。是的,它就是我们所说的CSS媒体查询。只不过稍有不同的是,这个媒体查询是根据用户在设备上的设置喜好来做条件判断。比如上面示例代码,当用户在设备上开启了“Low Data Mode”(低数据模式),会加载grunge.avif图像,可以帮助iPhone上的应用程序减少网络数据的使用:

15ed2f7c7492ed40555cffe09a278485.png

到目前为止,CSS媒体查询提供了多个媒体特性,可以以用户在设备上的喜好设置做为判断,比如iOS13+开始,iPhone提供的DarkMode模式(prefers-color-scheme):

a2e9f9bfd1025aca644e00dacb0253df.gif

比如,使用prefers-reduced-motion媒体查询用于检测用户的系统是否被开启了动画减弱功能:

995d06676aca1d40d5dabcf1ce104665.png

上面提到的这些媒体查询条件都是在

CSSMediaQueriesLevel 5(www.w3.org/TR/mediaque…) 模块中新增的。

除了上面提到的之外,还有一些我们平时很少见的媒体查询条件,比如:

@media (hover: hoveer) {}@media (hover: none) and (pointer: coarse) {}@media (hover: none) and (pointer: fine) {}@media print and (min-resolution: 300dpi) {}@media (scan: interlace) {}@media (update) {}@media(environment-blending: additive){}@media (color) {}

变量字体

变量字体是一个非常有意思的CSS特性,它也常被称为“可变字体”,先给大家展示一个Demo:

82673be15e9293fe2e8974f9bffb74cc.gif

变量字体的目标是让网站性能更好,同时给用户提供了更多选择和扩展。变量字体是类似矢量图形,允许为各种字体轴定义不同的值。变量字体设计中一般有五个注册轴,包括字体、字宽、斜体和光学尺寸。每个注册轴都有一个对应的四个字母的标记,可以映射到现有的CSS属性:

ec737714e6f2b38485b1d057749084bc.png

除了注册轴之外,字体设计器还可以包含自定义轴。自定义轴让可变字体变得更具创造性,因为不限制自定义轴的范围、定义或数量。与注册轴类似,自定义轴具有相应的四个字母标记。但是,自定义轴的字母标记必须是大写的。例如,你定义了一个注册轴是grade,其对应的字母标记是 GRAD。

比如上面示例效果对应的代码:

.text {    font-weight: 800;    font-style: italic;    font-variation-settings: "SSTR" 183, "INLN" 648, "TSHR" 460, "TRSB" 312, "TWRM" 638, "SINL" 557, "TOIL" 333, "TINL" 526, "WORM" 523;    transition: font-variation-settings .28s ease;}  .text:hover {    font-weight: 400;    font-style: normal;    font-variation-settings: "SSTR" 283, "INLN" 248, "TSHR" 160, "TRSB" 112, "TWRM" 338, "SINL" 257, "TOIL" 133, "TINL" 426, "WORM" 223;}

在Firefox浏览器中,我们还可以通过开发者工具中“字体”选项提供的相关可变字体注册轴的值调整:

64e46a8d59a6b176ca48649472f04a38.png

调整完之后,可以获得新代码:

p {    font-size: 60px;    line-height: 37px;    letter-spacing: 0.113em;    font-variation-settings: "SSTR" 450, "INLN" 741, "TSHR" 292, "TRSB" 497, "TWRM" 173, "SINL" 557, "TOIL" 728, "TINL" 526, "WORM" 523, "TFLR" 362, "TRND" 516, "SWRM" 536, "TSLB" 509;    font-weight: 491;}

对应效果如下:

10d5449f24933c232fc89158fd3e3f34.png

Web可访问性

:focus-visible 和 :focus-within

一直以来我很容易把:focus-within和:focus-visible混淆。其实:focus-within和:focus-visible都是CSS选择器 Level 4中用户操作类伪类选择器。早前在《初探CSS 选择器Level 4》中聊过:focus-within,但没有聊过:focus-visible。

另外,在《CSS :focus-within》教程中就提到过, :focus-within能非常方便处理获取焦点状态。当元素本身或其后代元素获得焦点时,:focus-within伪类的元素就会有效 。:focus-within伪类选择器的行为本质上是一种父选择器行为,子元素的状态会影响父元素的样式。由于这种“父选择器”行为需要借助用户的行为触发,属于“后渲染”,不会与现有的渲染机制相互冲突。

3d35009c69c6b8aa76c6dce362430f4a.png

如果上面的介绍让你感到困惑的话,可以看下面这个Demo。你会发现,当

的后代元素得到焦点时,会有一个放大的效果:

b9b9ac31eba679ba344eec214b967e77.gif

实现上图的效果代码非常的简单:

form:focus-within {    box-shadow: 0px 0.2em 2.5em #c4c4c4;    transform: scale(1.025); }

对于:focus-visible伪类来说,当元素匹配:focus伪类并且客户端(UA)的启发式引擎决定焦点应当可见时就会生效。这个选择器可以有效地根据用户的输入方式(鼠标 vs 键盘)展示不同形式的焦点。

简单点说,按键盘tab键和鼠标点击得到的焦点效果不同。比如:

/* 链接得到焦点时的样式 */ a:focus { }/* * 1\. 如果链接有焦点,但是浏览器通常不会显示默认的焦点样式,会覆盖上面的焦点样式 * 2\. 不是按键盘`tab`键让链接得到的焦点,比如说鼠标点击链接*/a:focus:not(:focus-visible) {}/* 按键盘tab键让链接得到焦点的样式 */ a:focus-visible { }

来看一个具体的案例。这个示例中分别用鼠标点击链链和按键盘tab键让链接得到焦点,它的样式是不一样的:

bb740e4fe15986cb7c499c86e7e3cdf5.gif

e9be97b1cbfc80bc72c24a56ca47c69e.png

我们在虚拟的空间与你相遇,期待可以碰撞出不一样的火花

a776f2bbba74ff4856b7f85ff1541c31.png b06b9886f9fb2d60d67aa25b1c21b998.png公众号ID:前端大联盟扫码关注最新动态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值