特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)
2020年底@Una Kravets在CDS(Chrome Developer Summit 2020)分享了使用Houdini扩展CSS的话题,同时推出了 Houdini.how。让我们可以使用CSS Houdini的Paint API进行创作,并通过 CSS Paint Polyfill 让不支持CSS Houdini的Paint API的现代浏览器也能运行Paint API扩展的CSS能力。你或许和我一样,对此感到好奇是吧?如果是的话,请继续往下阅读。
什么是Houdini?
在开始了解CSS Paint API和Houdini.how之前,让我们先了解一下CSS Houdini。
Houdini是一组底层API,它们公开了CSS引擎的各个部分,从而使开发人员能够通过加入浏览器渲染引擎的样式和布局过程来扩展CSS。
在没有Houdini之前,我们仅限于通过JavaScript和CSSOM(CSS对象模型)的某些API进行交互,而有了Houdini之后,可以使用JavaScript方式来扩展CSS。
Houdini通过 Typed Object Model 实现了更多语义化的CSS,开发者可以通过 Properties and Value API 来定义高级CSS自定义属性,包括语法(syntax
)、默认值和继承。
Houdini API在这里与CSS解析器、CSSOM、级联、布局、绘画和合层阶段一起工作:
主要有两组Houdini API:CSS Properties and Value API 和 Worklets。而Worklets涵盖了渲染状态的访问,比如 布局(Layout)、绘制(Paint) 和 合层(Composiite);而Properties and Value API侧重于解析器扩展(Parser)、CSSOM 和 级联(Cascade)。
为了更好的理解上图,我们拆分成下面三个部分来理解,CSS Houdini出现前后CSS的工作。
CSS如何工作?
简单地说,CSS的工作如下:
- 浏览器加载Web页面,并接收HTML
- 浏览器将HTML转换为DOM,并存储在计算机的内存中
- 浏览器获取CSS等资源
- 浏览器对获取的CSS进行解析。根据它找到的选择器,将CSS规则应用于DOM中的对应节点上
- 创建一个渲染树
- 在屏幕上显示
渲染管道
渲染管道是一个承载Web基本结构的过程。其包括:
- 将HTML解析为DOM
- 创建渲染树(Render Tree)
- 渲染树的显示(布局)
- 绘制渲染树
在这个过程中有一个问题,即 如何在现有的渲染管道流程中应用一个钩子(Hooks)来修改常规流程?而这些Hooks就是CSS Houdini的API:
简单地说,我们在 浏览器加载CSS到解析CSS过程中引入Hooks(即 CSS Houdini相关的API):
虽然这样做,在技术上有了很多进步,但用户代理(比如浏览器)还是面临具大的挑战,比如说不能直接对默认的选择框进行主题化。如果要对它进行主题化,就需要基本的CSS代码和相应的Polyfill(用JavaScript编写的Polyfill)。这又引出另一个问题?
JavaScript编写的Polyfill和CSS Houdini的区别?
如果要使用CSS属性来美化元素,就需要使用JavaScript来编写相对应的Polyfill。它的工作原理:
浏览器会通过这个解析器来设置和读取DOM和CSSOM的级联(Cascade)、布局(Layout)、绘制(Paint)和合成(Composite)过程,然后使用JavaScript编写的Polyfill重新绘制一遍,再重新将Polyfill绘制的样式运用到元素上:
而CSS Houdini则不是这样。通过CSS Houdini,我们可以钩住CSS解析过程,并使用我们定义属性(自定义属性)应用样式:
引入CSS Houdini前后,浏览器渲染处理的一个流程对比就像下图这样:
CSS Houdini自定义属性和Worlets
了解了CSS Houdini是什么?以及它的一个基本工作过程之后,我们还需要理解CSS Houdini自定义属性和Worlets两个部分。不过在这里不会详细介绍他们。
CSS Houdini自定义属性
CSS Houdini自定义属性指的是CSS Properties and Value API。它和CSS原生的自定义属性非常的相似,同时它也常被称为CSS Houdini变量。
CSS Houdini自定义属性注册主要有两种方式,一种是使用 @property
,另外一种是使用 CSS.registerProperty()
:
对于注册好的自定义使用,也是使用var()
函数来调用:
@property --box-shadow-blur {
syntax: "<length>";
inherits: false;
initial-value: 0;
}
.el {
--box-shadow-blur: 3px;
box-shadow: 0 3px var(--box-shadow-blur) #000;
transition: --box-shadow-blur 0.45s;
}
.el:hover {
--box-shadow-blur: 10px;
}
有关于CSS Houdini的自定义属性更详细的介绍可以阅读:
理解CSS Houdini的Worklets
CSS Houdini的Worklets是其另一个API,是渲染引擎的一种扩展。从概念上讲,它与 Web Worker 类似,但有几个关键点例外:
- 它可以并行,每个Worklet必须有两个或更多的实例,任何一个实例都可以在调用时运行
- 仅限于不访问全局作用域的项目(除了Worklet的函数名)
- 扩展的渲染引擎会在需要的时候调用
CSS Houdini的Worklet也是JavaScript模块,通过调用Worklet的
addModule
函数来添加,它也是一个Promise。
简单地说,CSS Houdini Worklets是脱离主线程运行的浏览器指令,可以在需要时调用。Worklets使你能够使用JavaScript编写一个模块化的CSS来完成特定的任务,并且骂人要一行JavaScript来导入和注册。就像
如需转载,烦请注明出处:https://www.w3cplus.com/css/houdini-how-and-css-paint-api.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!