css动画即使在不同的时间开始一起结束

时间:2018-06-30 11:01:50

标签: css css3 css-animations delay

我有几个相同类型的元素,我希望它们共享相同的CSS动画,但是我希望它们在不同的时间开始/结束动画。

Codepen for the following code

html:

<div class="container">
    <div class="box hidden"></div>
</div>
<div class="container">
    <div class="box hidden"></div>
</div>
<div class="container">
    <div class="box hidden"></div>
</div>

css:

.container {
    width: 100px;
    height: 100px;
    margin-bottom: 20px;
}

.box {
    width: 100%;
    height: 100%;
}

.box.hidden {
    visibility: hidden;
}

.box {
    animation: growIn 1s;
    animation-timing-function: cubic-bezier(.46,.13,.99,.83);
    transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
    background-color: green;
}

.container:nth-child(2) .box {
    background-color: orange;
}

.container:nth-child(3) .box {
    background-color: red;
}

@keyframes growIn {
    from {
        transform: scale(0);
    }
    to {
        transform: scale(1);
    }
}

box元素开始时是隐藏的,然后使用javascript从不同的框中但在不同的时间删除了该类名:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
    setTimeout(() => box.classList.remove("hidden"), Math.random() * 1000);
});

发生的是,所有3个盒子都在同一时间结束动画。动画的确开始于不同的时间,但全部都结束了。

那是为什么?
如果我做同样的事情,但是添加了一个类名而不是删除它(以使动画开始),那么它的行为就像我想要的那样。
有任何想法吗?谢谢。

2 个答案:

答案 0 :(得分:2)

仅是因为所有动画均已已同时开始。使用visibility:hidden不会阻止动画开始,并且使动画在元素可见时稍后开始。例如,不透明度也会发生同样的事情:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => box.classList.remove("hidden"), Math.random() * 5000);
});
.container {
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}

.box {
  width: 100%;
  height: 100%;
}

.box.hidden {
  opacity: 0.1;
}

.box {
  animation: growIn 5s;
  animation-timing-function: cubic-bezier(.46, .13, .99, .83);
  transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
  background-color: green;
}

.container:nth-child(2) .box {
  background-color: orange;
}

.container:nth-child(3) .box {
  background-color: red;
}

@keyframes growIn {
  from {
    transform: scale(0);
  }
  to {
    transform: scale(1);
  }
}
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>

如果您改用display属性,则可以看到所需的行为:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => box.classList.remove("hidden"), Math.random() * 3000);
});
.container {
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}

.box {
  width: 100%;
  height: 100%;
}

.box.hidden {
  display:none;
}

.box {
  animation: growIn 1s;
  animation-timing-function: cubic-bezier(.46, .13, .99, .83);
  transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
  background-color: green;
}

.container:nth-child(2) .box {
  background-color: orange;
}

.container:nth-child(3) .box {
  background-color: red;
}

@keyframes growIn {
  from {
    transform: scale(0);
  }
  to {
    transform: scale(1);
  }
}
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>


来自specification

  

“可见性”属性指定是否由   元素已呈现

     

不可见的框仍会影响布局(设置   将“显示”属性设置为“无”,以完全禁止生成框)。

因此,与使用visibility相比,使用display时会始终生成框。

如果我们检查与动画有关的specification,我们会发现:

  

将display属性设置为none将终止任何运行   应用于元素及其后代的动画。如果一个元素   无显示,将显示更新为无值   将以动画名称开始应用于元素的所有动画   属性,以及应用于带有   不显示任何内容。

答案 1 :(得分:1)

问题是您的box元素以.box类(动画类)开头。这意味着动画从加载元素的那一刻开始,无论是否隐藏。这意味着,当您删除“隐藏”类时,它们只会在动画过程中的某个时刻展现自己。

您要做的是重命名动画类,例如“ grower”

.grower {
    animation: growIn 1s;
    animation-timing-function: cubic-bezier(.46,.13,.99,.83);
    transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

然后在javascript循环中添加它:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => {
    box.classList.remove("hidden");
    box.classList.add("grower"); }, Math.random() * 1000);
});

下面是一个演示它的片段:

const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
  setTimeout(() => {
    box.classList.remove("hidden");
    box.classList.add("grower"); }, Math.random() * 1000);
});
.container {
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}

.box {
  width: 100%;
  height: 100%;
}

.box.hidden {
  visibility: hidden;
}

.grower {
	animation: growIn 1s;
	animation-timing-function: cubic-bezier(.46,.13,.99,.83);
	transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

.container:first-child .box {
  background-color: green;
}

.container:nth-child(2) .box {
  background-color: orange;
}

.container:nth-child(3) .box {
  background-color: red;
}

@keyframes growIn {
  from {
		transform: scale(0);
  }
  to {
		transform: scale(1);
  }
}
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>
<div class="container">
  <div class="box hidden"></div>
</div>