css 重叠
“Overlapping action” is one of the 12 celebrated Disney principles of animation, closely related to “follow through”. In this article I’m using the term “overlapping action” in a slightly different and expanded sense, one specific to writing CSS: how to create the impression of multiple independent actions from a single CSS animation directive.
“重叠动作”是迪士尼12条著名的动画原理之一,与“跟进”密切相关。 在本文中,我以略有不同和扩展的含义使用“重叠动作”一词,一种特定于编写CSS的方式:如何从单个CSS动画指令创建多个独立动作的印象。
一对一的危险 (The Perils of One-to-One)
Quite understandably, beginners often assume that independent animated elements on a page must be moved using different animations, even if their motions are very similar: it’s often assumed that motions like those shown in the demo above would require five separate animations.
完全可以理解的是,初学者通常认为页面上的独立动画元素必须使用不同的动画来移动,即使它们的动作非常相似:通常假设像上面演示中所示的动作需要五个单独的动画。
Inevitably this leads to a tremendous amount of code, repetition, and typing: the same problem we have when trying to write general CSS for related page components that are just a little bit different from each other.
不可避免地,这会导致大量的代码,重复和打字:这是我们试图为相关页面组件编写通用CSS时遇到的相同问题,彼此之间略有不同 。
分离的好处 (The Upside of Separation)
The solution is to create the correct animation for one element, then separate out the property that is different. For the animation we’re looking at above, the markup might look something like this:
解决方案是为一个元素创建正确的动画,然后分离出different属性 。 对于上面我们看的动画,标记可能看起来像这样:
<figure id="bouncy">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</figure>
And the initial CSS like this:
最初CSS像这样:
#bouncy {
color: #223;
min-height: 200px;
display: flex;
background: currentColor;
border: 10px solid;
align-items: flex-end;
justify-content: space-between;
}
#bouncy div {
width: 15%;
height: 10px;
background: red;
margin-right: .5rem;
transform-origin: center bottom;
}
A brief breakdown:
简要分类:
color
is used as a shortcut for both theborder
andbackground
(viacurrentColor
)color
用作border
和background
的快捷方式(通过currentColor
)The
<div>
elements are spaced apart with flexbox;align-items: flex-end
ensures that they start at the bottom of the#bouncy
container.<div>
元素与flexbox隔开;align-items: flex-end
确保它们从#bouncy
容器的底部开始。By default elements are transformed from their computed center; changing the value of
transform-origin
ensures that any transformation will occur from the bottom of the element.默认情况下,元素从其计算中心 转换 ; 更改
transform-origin
的值可确保从元素的底部进行任何转换。Vendor prefixes are not included for the sake of brevity and clarity.
为了简洁起见,不包括供应商前缀 。
添加动画 (Adding Animation)
To get one of the bars moving correctly, I’ll add an animation that will scale it upwards 20×:
为了使其中一个条正确移动,我将添加一个动画,将其向上缩放20倍:
@keyframes risenfall {
to { transform: scaleY(20); }
}
Calling on this animation, I’ll address the first <div>
element with an nth-child
selector:
调用此动画,我将使用nth-child
选择器处理第一个<div>
元素 :
#bouncy div:nth-child(1) {
animation: risenfall 1s infinite alternate cubic-bezier(.53,.14,.83,.67);
}
This will make the first <div>
scale up and down smoothly; I’ve added a custom cubic-bezier function to give the animation a little “snap”. alternate
ensures that the animation will “ping-pong” back and forth, while infinite
effectively cycles the animation forever.
这将使第一个<div>
平滑地缩放; 我添加了一个自定义的三次方贝塞尔函数,以使动画有点“捕捉”。 alternate
确保动画将来回“乒乓”,而infinite
有效地永久循环动画。
Applying this animation to all the <div>
elements would, unsurprisingly, make them all move the same way, at the same time:
毫不奇怪,将此动画应用于所有 <div>
元素将使它们同时以相同的方式移动:
#bouncy div {
animation: risenfall 1s infinite alternate cubic-bezier(.53,.14,.83,.67);
}
The result:
结果:
If we think about it, the only thing different about the motion of each of the bars in the final demo is that they start at a slight delay after each other. We have a property for that in CSS: animation-delay
. By applying that property to each bar individually, we can create the appearance of complex animation. The first bar is fine, so we’ll just address the second through fifth:
如果我们考虑一下,最终演示中每个小节的运动唯一不同的是它们彼此之间的延迟稍有延迟。 我们在CSS中有一个属性: animation-delay
。 通过单独应用该属性为每个栏,我们可以创建复杂的动画的外观。 第一个小节很好,所以我们只讨论第二个到第五个:
#bouncy div:nth-child(2) {
animation-delay: .3s;
}
#bouncy div:nth-child(3) {
animation-delay: .4s;
}
#bouncy div:nth-child(4) {
animation-delay: .5s;
}
#bouncy div:nth-child(5) {
animation-delay: .6s;
}
Each bar is still influenced by the overall animation, but the individual delays cause them to look as if they are independent.
每个小节仍然受整体动画的影响,但是各个延迟会导致它们看起来好像是独立的。
As the animation-delay
approaches the original duration of the animation-duration
(1 second, in this case), it will resemble the original animation more and more.
当animation-delay
接近animation-duration
的原始持续animation-duration
(在本例中为1秒)时,它将越来越类似于原始动画。
结论 (Conclusion)
The more elements you have to animate (and the more individualized their actions) the more code you have to write, bringing us back to the initial problem; eventually, you will probably want to use a CSS preprocessor such as Sass or scripting to automate this process. However you approach the problem, the principle remains the same: group appearances / animation together when possible, and separate out the exceptions as small style rules.
您需要制作动画的元素越多(动作的个性化越多),您必须编写的代码就越多,这使我们回到了最初的问题。 最终,您可能希望使用CSS预处理程序(例如Sass或脚本)来自动执行此过程。 无论您如何处理问题,原理都保持不变:在可能的情况下将 外观/动画组合在一起 ,并以小的样式规则将异常分开 。
翻译自: https://thenewcode.com/1058/Overlapping-Action-with-CSS-Animation
css 重叠