时间:2019-08-06
编辑:网站制作公司
839
0
大多数用户界面动画分为两类:静态(即基于时间轴)和反应。反应动画是涉及基于事件的变化而不是基于固定时间线的动画。虽然许多基于Web的用户界面都使用静态动画,但是反应动画可以创建真正的交互式用户体验。
现在,在现代浏览器中广泛支持 CSS自定义属性(又称CSS变量),通过利用继承,相对单元和转换等CSS功能,可以轻松地将反应动画添加到用户界面。重庆网页设计
尽管它的名字很常见,但CSS变量不是真正的变量; 然而,他们肯定像他们一样。它们的全名 - CSS自定义属性 - 使其更加清晰:它们表现为属性,这些属性受级联,继承和媒体查询的影响。
通过在变量名前加两个破折号,在规则集中定义一个CSS变量:
css
:root {
--my-color: red;
--button-font-size: 16px;
}上面,我在:root选择器上设置CSS变量。然后可以使用var()函数在任何可以继承该自定义属性的选择器中引用其值,其中第一个参数是CSS变量的名称,第二个(可选)是默认值:
css
.ui-button {
background-color: var(--my-color, blue);
font-size: var(--button-font-size);
}现在,使这些CSS变量真正动态化的关键是通过JavaScript设置它们。这是通过.setProperty()元素.style属性上的方法完成的,如下所示:
js
const el = document.documentElement;
// set custom property
el.style.setProperty(
'--my-color', // custom property name, with dashes
'red' // custom property value, as a string or number
);
// get custom property
// (only if defined on element)
el.style.getPropertyValue('--my-color');
// => 'red'浏览器将自动从字符串值推断本机CSS值类型,例如红色'red'或15个像素'15px'。但是,这确实会产生一些开销。为了提高性能和灵活性,最好尽可能使用无单位数值来动态设置CSS变量:
js
// not unitless - incurs overhead
el.style.setProperty('--x', '30px');
// unitless
el.style.setProperty('--x', 30);无单位值可以通过calc()CSS中的单位转换为单位值:
css
.ui-button {
/* convert unitless --x value to pixels */
transform: translateX(calc(var(--x, 0) * 1px));
}通过使用calc(),我们可以通过组合它们,将它们与相对单位一起使用,以及更多来使用CSS变量。
在JavaScript中设置CSS变量允许动态样式,但是为了创建具有反应动画的交互式体验,应该设置它们以响应事件。在一般意义上,事件可以源自任何地方,例如来自诸如鼠标事件之类的用户交互,诸如音频输入之类的外部事件,或来自其他动画本身。
为了使这更容易,让我们创建一个在元素上设置CSS变量的实用程序函数:
js
const docEl = document.documentElement;
function styleVar(property, value, element = docEl) {
element.style.setProperty(property, value);
}例如,让我们从'mousemove'事件中读取值并将它们提供给CSS变量:
js
docEl.addEventListener('mousemove', (event) => {
styleVar('--mouse-x', event.clientX);
styleVar('--mouse-y', event.clientY);
});现在,只要鼠标在文档中移动,就会使用相应的整数值更新--mouse-x和--mouse-y自定义属性。您可以通过检查DOM并观察元素的style属性来见证这一点<html>。
我们可以直接在CSS中使用这些值,而不用担心值是如何到达那里的; 只是他们在场:
css
.ball {
transform:
translateX(calc(var(--mouse-x, 0) * 1px))
translateY(calc(var(--mouse-y, 0) * 1px));
}另一个应用是通过监听'scroll'事件并传递.scrollX或.scrollY事件属性来创建“视差”效果:
js
window.addEventListener('scroll', e => {
styleVar('--scroll-y', e.scrollY);
});CSS自定义属性的优点在于它们与CSS的自然继承和级联行为一起使用。这对性能和代码组织都有直接的好处,原因如下:
不必为每个受影响的元素直接更新样式值,只会影响单个样式值(自定义属性),并且元素会自动更新
无需跟踪添加和删除的DOM节点,因此将样式应用于动态布局的开销较小
动态样式变得简化为提供的值,而不是直接样式
但是,要记住的一件重要事情是,目前,CSS自定义属性始终是继承的。将自定义属性应用于元素时,必须重新计算元素及其所有后代的样式。对于大型DOM树,这可能会影响性能。
为了缓解这种情况,仅将自定义属性应用于受影响的最深父元素非常重要。例如,如果按钮依赖于动态应用的自定义属性,则.setProperty()尽可能直接使用该按钮而不是根元素。
使用requestAnimationFrame()自定义属性动态样式时,使用也可以防止抖动并提高性能。由于页面上的所有可视化都与动画帧同步呈现(理想情况下为每秒60帧),因此请注意可能以更快的速率发出事件的事件处理程序,例如滚动事件。
对于因各种原因(包括前庭紊乱)而不想看动画的人来说,减少或完全禁用静态或动态动画非常重要。这可以通过prefers-reduced-motion媒体查询完成:
css
/* No motion preferences specified */
@media screen and (prefers-reduced-motion: no-preference) {}
/* Reduced motion requested */
@media screen and (prefers-reduced-motion: reduce) {
*, *:before, *:after {
animation: none !important;
}
}但是,具有CSS自定义属性的反应动画不一定与动画相关联。值得庆幸的是,我们可以为这些自定义属性指定静态值,并强制使用这些值:
css
@media screen and (prefers-reduced-motion: reduce) {
:root {
--mouse-x: 0 !important;
--mouse-y: 0 !important;
}
}这将确保值不会改变并导致用户不必要的运动。
尽管所有现代浏览器都支持CSS自定义属性,但旧版浏览器(例如旧版本的IE)可能不支持它们。在这种情况下,可以将CSS自定义属性视为渐进增强,并且可以替换静态值:
css
.box {
color: green; /* will be used if custom properties are not supported */
color: var(--my-color, green);
}CSS自定义属性(也称为CSS变量)为CSS带来了全新的动态维度。您现在可以通过JavaScript将动态值分配给自定义属性,并在CSS中使用它们,而不是使用JavaScript直接设置元素样式。除了关注点分离和性能增强之外,通过这些自定义属性应用的样式可在Chrome,Firefox和Edge的开发工具中进行检查。确保仅将动态自定义属性应用于尽可能低的元素范围,并限制样式应用程序requestAnimationFrame()以限制不必要的restyles。
重庆网页设计
3
s后返回登录3
s后返回登录