You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
关于houdini最近动态可点击这里
上次CSS大会知道了有Houdini的存在,那时候只有cssom,layout和paint api。前几天突然发现,Animation api也有了,不得不说,以后很可能是Houdini遍地开花的时代,现在得进一步了解一下了。一句话:这是css in js到js in css的转变
支持情况 点击这里查看
首先,看一下支持度,目前浏览器并没有完全稳定使用,所以需要跟着它的提示:Experimental Web Platform features” on chrome://flags,在chrome地址栏输入chrome://flags再找到Experimental Web Platform features并开启。
0. 前言
平时写CSS,感觉有很多多余的代码或者不好实现的方法,于是有了预处理器的解决方案,主旨是write less &do more。其实原生css中,用上css变量也不差,加上bem命名规则只要嵌套不深也能和less、sass的嵌套媲美。在一些动画或者炫酷的特效中,不用js的话可能是用了css动画、svg的animation、过渡,复杂动画实现用了js的话可能用了canvas、直接修改style属性。用js的,然后有没有想过一个问题:“要是canvas那套放在dom上就爽了”。因为复杂的动画频繁操作了dom,违背了倒背如流的“性能优化之一:尽量少操作dom”的规矩,嘴上说着不要,手倒是很诚实地
ele.style.prop = <newProp>
,可是要实现效果这又是无可奈何或者大大减小工作量的方法。我们都知道,浏览器渲染的流程:解析html和css(parse),样式计算(style calculate),布局(layout),绘制(paint),合并(composite),修改了样式,改的环节越深代价越大。js改变样式,首先是操作dom,整个渲染流程马上重新走,可能走到样式计算到合并环节之间,代价大,性能差。然后痛点就来了,浏览器有没有能直接操作前面这些环节的方法呢而不是依靠js?有没有方法不用js操作dom改变style或者切换class来改变样式呢?
于是就有CSS Houdini了,它是W3C和那几个顶级公司的工程师组成的小组,让开发者可以通过新api操作CSS引擎,带来更多的自由度,让整个渲染流程都可以被开发者控制。上面的问题,不用js就可以实现曾经需要js的效果,而且只在渲染过程中,就已经按照开发者的代码渲染出结果,而不是渲染完成了再重新用js强行走一遍流程。
1. CSS变量
如果你用less、sass只为了人家有变量和嵌套,那用原生css也是差不多的,因为原生css也有变量:
比如定义一个全局变量--color(css变量双横线开头)
使用的时候只要var一下
我们的html:
于是,红色的123就出来了。
css变量还和js变量一样,有作用域的:
html:
于是,是什么效果你应该也很容易就猜出来了:
css能搞变量的话,我们就可以做到修改一处牵动多处的变动。比如我们做一个像准星一样的四个方向用准线锁定鼠标位置的效果:
用css变量的话,比传统一个个元素设置style优雅多了:
那么,对于github的404页面这种内容和鼠标位置有关的页面,思路是不是一下子就出来了
2. CSS type OM
都有DOM了,那CSSOM也理所当然存在。我们平时改变css的时候,通常是直接修改style或者切换类,实际上就是操作DOM来间接操作CSSOM,而type om是一种把css的属性和值存在attributeStyleMap对象中,我们只要直接操作这个对象就可以做到之前的js改变css的操作。另外一个很重要的点,attributeStyleMap存的是css的数值而不是字符串,而且支持各种算数以及单位换算,比起操作字符串,性能明显更优。
2.1 单位
2.2 数学运算
自己在控制台输入CSSMath,可以看见的提示,就是数学运算
2.3 怎么用
既然是新的东西,那就有它的使用规则。
element.attributeStyleMap.get(attributeName)
,返回一个CSSUnitValue对象element.attributeStyleMap.set(attributeName, newValue)
,设置值,传入的值可以是css值字符串或者是CSSUnitValue对象当然,第一次get是返回null的,因为你都没有set过。“那我还是要用一下getComputedStyle再set咯,这还不是和之前的差不多吗?”
实际上,有一个类似的方法:
element.computedStyleMap
,返回的是CSSUnitValue对象,这就ok了。我们拿前面的第一部分CSS变量的代码测试一波3. paint API
paint、animation、layout API都是以worker的形式工作,具体有几个步骤:
主要的逻辑,全都写在传入registerPaint的class里面。paint API很像canvas那套,实际上可以当作自己画一个img。既然是img,那么在所有的能用到图片url的地方都适合用paint API,比如我们来自己画一个有点炫酷的背景(满屏随机颜色方块)。有空的话可以想一下js怎么做,再对比一下paint API的方案。
接着我们需要引入该worker:
最后我们在一个class为paint的div应用样式:
再想想用js+div,是不是要先动态生成n个,然后各种计算各种操作dom,想想就可怕。如果是canvas,这可是canvas背景,你又要在上面放一个div,而且还要定位一波。
4. 自定义属性
说到继承,我们回到前面的css变量,已经说了变量是区分作用域的,其实父作用域定义变量,子元素使用该变量实际上是继承的作用。如果
inherits: true
那就是我们看见的作用域的效果,如果不是true则不会被父作用域影响,而且取默认值。这个自定义属性,精辟在于,可以用永久循环的animation驱动一次性的transform。换句话说,我们如果用了css变量+transform,可以靠js改变这个变量达到花俏的效果。但是,现在不需要js,只要css内部消化,transform成为永动机。
然后写个样式
再来看看我们的动画,为了眼花缭乱,加了第二个改了一点数据的动画
html就两个div:
效果是什么呢,自己可以跑一遍看看,反正功能很强大,但是想象力限制了发挥。
最后
再啰嗦一次
The text was updated successfully, but these errors were encountered: