特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)
今天在Twitter上看到@argyleink在伦敦(LondonCSS 2020)CSS第四次活动中分享的一个话题《What's new with CSS?》。看了一下这个主题的PPT,里面有些新东西还是蛮有意思的,稍微整理一下和大家一起分享。如果你感兴趣的话,请继续往下阅读。
主题PPT
这个主题是@argyleink大神分享的,对应的PPT可以扫下面这个二维码:
或者点击这里访问PPT:
这次活动除了这个话题还有另外两个话题:
- @Stephanie Eckles的STYLE STAGE AND MODERN CSS :Style Stage堪比现代版的CSS禅意花园(CSS Zen Garden),允许任何级别的CSS从业者重新设计基于相同HTML的样式,同时提高他们地现代CSS特性的熟悉程度
- @Cassie Evans的PAINTING WITH SVG :介绍了SVG的绘制相关的特性,而且@Cassie Evans有另一篇有关于SVG的文章,非常值得我们花时间去阅读:Making lil' me - part 1.
我们回到今天的主题:2020年CSS有哪些新特性。
动态模糊(Motion Blur)
Motion Blur(动态模糊),这个概念也是我第一次接触的。查了一些资料才明白,动态模糊是一种模糊效果,它只在特动移动的时候才会让物体模糊,通常这种模糊是在物体移动的方向上应用的,这就是当你试图在拍一个移动的物体的效果。
当你拍摄一个物体(或是一个人),就像下图,这个模糊就会发生,因为这个物体(人运动)移动的速度超过了相机拍摄所需的曝光时间,所以这个物体会在最终的照片中出现多次,因为它在关键时刻移动。
在我们平时制作动效的时候,很少会考虑(添加)动态模糊效果,另外在CSS和SVG动画中也缺少这方面的效果,因此大多数Web动画看起来很生硬。也就是说,如果我们给动画在运动过程中添加一些模糊效果,会让这种动效更贴近现实生活。
为此,@argyleink向W3C规范提出了有关于动态模糊相关的实现方案(建议),他为开发者(CSSer)推荐了一种方法,在CSS的animation
是新增了 motion-rendering
和 motion-shutter-angle
。
.animated-layer {
/* GPU加速动画 */
animation: rotate .5s linear infinite;
/* 向引擎请求动态模糊
* motion-rendering可以接受inherit | initial | auto | none | blur 值
*/
motion-rendering: blur;
/* 类似于相机的快门,指的是快门角度,用来控制模糊量或模糊强度
* motion-shutter-angle可受任意角度值 inherit | initial | auto = 180deg | [0deg, ..., 720deg]
*/
motion-shutter-angle: 180deg;
}
@keyframes rotate {
to {
transform: rotate(1turn);
}
}
来看一个简单的示例:
从效果上看似乎没看到动态模糊的效果。
这里还是用文档中提供的一个带有动效的图向大家展示动态模糊的效果:
虽然说, motion-rendering
和 motion-shutter-angle
还只是一个提案,离到TR阶段还需要很长的时间,但对于某些场景(动画场景),可以使用CSS的filter
来模拟,比如下面这个效果:
代码很简单:
.blur {
animation: blur 250ms;
}
@keyframes blur {
0% {
-webkit-filter: blur(0px);
}
50% {
-webkit-filter: blur(5px);
}
100% {
-webkit-filter: blur(0px);
}
}
另外,现在提供的 motion-rendering
和 motion-shutter-angle
还只是一个提议,在Github中讨论的评论中,也有建议将这两个属性换成:
filter: motion-blur(5px) motion-squash(2px)
// 或
transform-fiilter: motion-blur(180deg)
// 或
transition-filter: motion-blur(180deg)
也就是说,上面提供的CSS实现动态模糊的属性不是完全定下来的,随着后面的发展,CSS中实现动态模糊的属性,一切皆有可能。
再来看看SVG世界中,相对于CSS世界而言,SVG中要实现动态模拟效果要更容易一些,可以使用SVG中的滤镜来模拟动态模糊效果:
上图来自于@Lucas Bebber的《Motion Blur Effect with SVG》教程。
如果你对SVG中的滤镜相关的知识感兴趣的话,可以阅读:
有意思的是,@Michelle Barker在Codepen写了一个Demo,这个Demo是用CSS的box-shadow
模拟出有动态模拟的效果:
如果你真的想在项目中让自己的动画效果具有动态模糊效果(让动效看上去更真一点),而又担心CSS或SVG相关特性未得到主流浏览器支持而不敢使用,那么我在这里向大家推荐一个JavaScript库: MotionBlurJS:
来看使用MotionBlurJS实现的动态模糊效果:
@scroll-timeline
Web开发者时常会碰到使用滚动来触发某些元素的动画效果,比如说,页面滚动条滚动到某个位置,标题固定在顶部;页面顶部展示你页面进度(滚动指示器);还是一些我们所说的视差滚动效果等。以往实现这些效果,大都借助JavaScript来实现,可以通过DOM事件查看滚动位置,并根据该位置更改元素的样式。如果可以的话,最好使用IntersectionObserver
。有关于这方面的介绍可以阅读:
- Trust is Good, Observation is Better—Intersection Observer v2
- How to do scroll-linked animations the right way
不过,现在有一个关于这方面的CSS草案,即 Scroll-linked Animations。也就是说,在未来,我们可以直接使用CSS的@scroll-timeline
属性来实现前面提到的一些动画效果。
@scroll-timeline = @scroll-timeline <timeline-name> { <declaration-list> }
在规范中向大家提供了两个简单的示例,比如说,两个圆球的碰撞动效。这个动效由滚动位置来控制,简单地说,随着页面往下滚动,左右两个球慢慢向中间靠齐,直到他们两碰撞到一起,变成一个圆。反之,页面往上滚动时,中间的圆慢慢的会分离出左右两个圆。
CSS代码大致像下面这样:
@media (prefers-reduced-motion: no-preference) {
div.circle {
animation-duration: 1s;
animation-timing-function: linear;
animation-timeline: collision-timeline;
}
#left-circle {
animation-name: left-circle;
}
#right-circle {
animation-name: right-circle;
}
#union-circle {
animation-name: union-circle;
animation-fill-mode: forwards;
animation-timeline: union-timeline;
}
@scroll-timeline collision-timeline {
source: selector(#container);
orientation: block;
start: 200px;
end: 300px;
}
@scroll-timeline union-timeline {
source: selector(#container);
orientation: block;
start: 250px;
end: 300px;
}
@keyframes left-circle {
to { transform: translate(300px) }
}
@keyframes right-circle {
to { transform: translate(350px) }
}
@keyframes union-circle {
to { opacity: 1 }
}
}
如果是使用JavaScript的话,可以像下面这样:
if (window.matchMedia('(prefers-reduced-motion: no-preference)').matches) {
const scrollableElement = document.querySelector('#container');
const collisionTimeline = new ScrollTimeline({
source: scrollableElement,
start: CSS.px(200),
end: CSS.px(300)
});
const left = leftCircle.animate({ transform: 'translate(300px)' }, 1000);
left.timeline = collisionTimeline;
const right = leftCircle.animate({ transform: 'translate(350px)' }, 1000);
right.timeline = collisionTimeline;
const union = unionCircle.animate({ opacity: 1 }, { duration: 1000, fill: "forwards" });
union.timeline = new ScrollTimeline({
source: scrollableElement,
start: CSS.px(250),
end: CSS.px(300)
});
}
再来看一个滚动计时器的效果:
上面的示例,我们是使用渐变来模拟的一个效果,但有了@scroll-timeline
我们就可以像下面这样来实现:
@media (prefers-reduced-motion: no-preference) {
@scroll-timeline progress-timeline {
source: selector(#body);
start: 0;
end: 100%;
}
@keyframes progress {
to { width: 100%; }
}
#progress {
width: 0px;
height: 30px;
background: red;
animation: 1s linear forwards progress progress-timeline;
}
}
如果使用Web Animation API的话,可以像下面这样:
if (window.matchMedia('(prefers-reduced-motion: no-preference)').matches) {
var animation = div.animate({ width: '100%' }, { duration: 1000, fill: "forwards" });
animation.timeline = new ScrollTimeline(
{
start: 0,
end: CSS.percent(100)
}
);
}
@argyleink在他分享的PPT中也提供了一个简单的示例:
滚动页面的时候,你会发现两个数字之间的/
符会不断的旋转:
上面的示例效果是基于Web Animation API来实现@scroll-timeline
的效果,但是目前还需要其对应的Polyfill。
import 'https://flackr.github.io/scroll-timeline/dist/scroll-timeline.js'
const counter = document.querySelector('main')
const slashes = document.querySelectorAll('.slash')
slashes.forEach(slash => {
slash.animate({
transform: ['rotateZ(0)','rotateZ(4turn)']
},{
duration: 1000,
fill: 'both',
timeline: new ScrollTimeline({
scrollSource: counter,
fill: 'both',
}),
})
})
有关于
@scroll-timeline
更详细的介绍可以查阅 Scroll-linked Animations,另外,该规范目前还只是一个草案,在未来有可能还会有所变动。
leading-trim
和 text-edge
一直以来,在Web的排版中行高(line-height
)总是令Web开发者感到困惑和头痛,主要是因为l
如需转载,烦请注明出处:https://www.w3cplus.com/css/what-is-new-css-2020.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!