css – Animate转换只有一个属性(scale)覆盖其他(translate)

前端之家收集整理的这篇文章主要介绍了css – Animate转换只有一个属性(scale)覆盖其他(translate)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题是转换属性的值有多个部分,如translate,scale等.

这是一个关于元素的理论问题,让我们的.loader有变换:translate(10px,10px),在动画中我想要为scale属性设置动画.在这种情况下,浏览器不会进行转换:translate(10px,10px)并且仅采用比例.

我正在寻找解决这个问题的方法.

这是这个问题的一个例子.请注意,我不是在寻找这个特定示例的答案(比如:包装元素或将translate值添加到动画定义中),而是一个通用的解决方案(当然,如果存在的话).

  1. .loading {
  2. position: relative;
  3. width: 100px;
  4. height: 100px;
  5. background: #eee;
  6. }
  7. .loading:before,.loading:after {
  8. content: "";
  9. width: 50%;
  10. height: 50%;
  11. -moz-border-radius: 50%;
  12. -webkit-border-radius: 50%;
  13. border-radius: 50%;
  14. background-color: #fff;
  15. opacity: 0.6;
  16. position: absolute;
  17. top: 0;
  18. left: 0;
  19. /* the broswer doesn't take this */
  20. transform: translate(100px,300px);
  21. -webkit-animation: bounce 2s infinite ease-in-out;
  22. animation: bounce 2s infinite ease-in-out;
  23. }
  24. .loading:after {
  25. -webkit-animation-delay: -1s;
  26. animation-delay: -1s;
  27. }
  28. @keyframes bounce {
  29. 0%,100% {
  30. transform: scale(0);
  31. -webkit-transform: scale(0);
  32. }
  33. 50% {
  34. transform: scale(1);
  35. -webkit-transform: scale(1);
  36. }
  37. }
  1. <div class="loading"></div>

解决方法

通常,当您添加对transform属性进行更改的动画时,也应该继承基本元素中指定的变换以在动画的关键帧中出现.也就是说,新变换(动画的一部分)应该添加到现有变换之上,而不是覆盖它.以下是应该如何做的.
  1. .loading {
  2. position: relative;
  3. width: 200px;
  4. height: 200px;
  5. background: #eee;
  6. }
  7. .loading:before,.loading:after {
  8. content: "";
  9. width: 50%;
  10. height: 50%;
  11. border-radius: 50%;
  12. background-color: #fff;
  13. opacity: 0.6;
  14. position: absolute;
  15. top: 0;
  16. left: 0;
  17. transform: translate(100px,300px);
  18. animation: bounce 2s infinite ease-in-out;
  19. }
  20. .loading:after {
  21. animation-delay: -1s;
  22. }
  23. @keyframes bounce {
  24. 0%,100% {
  25. transform: scale(0) translate(100px,300px);
  26. }
  27. 50% {
  28. transform: scale(1) translate(100px,300px);
  29. }
  30. }
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
  2. <div class="loading"></div>

我写了一个类似的答案here,关于在一个元素上添加多个动画的问题,每个动画修改转换属性的值独立于另一个.我在这里链接它只是为了参考,不认为它们是重复的.

如上所述,当您尝试创建动画库或尝试将每个动画拆分为单独的类时,将原始变换添加到每个动画的kefyrames是不可能的.比如说,您想要将相同的反弹动画添加到多个元素,并且每个元素都有不同的初始变换设置,那么就无法将其添加到动画的关键帧中.

在这种情况下,您仍然可以使用CSS实现所需的输出,但在我看来,使用单个元素完成它将非常困难(几乎不可能).

你有什么选择?好吧,一个选项是你在包装元素上添加动画.

  1. .loading-wrapper {
  2. position: relative;
  3. width: 200px;
  4. height: 200px;
  5. background: #eee;
  6. }
  7. .loading-before,.loading-after {
  8. position: absolute;
  9. width: 50%;
  10. height: 50%;
  11. top: 0px;
  12. left: 0px;
  13. animation: bounce 2s infinite ease-in-out;
  14. }
  15. .loading-before:before,.loading-after:before {
  16. content: "";
  17. width: 100%;
  18. height: 100%;
  19. border-radius: 50%;
  20. background-color: #fff;
  21. opacity: 0.6;
  22. position: absolute;
  23. top: 0;
  24. left: 0;
  25. transform: translate(100px,300px);
  26. }
  27. .loading-after {
  28. animation-delay: -1s;
  29. }
  30. @keyframes bounce {
  31. 0%,100% {
  32. transform: scale(0);
  33. }
  34. 50% {
  35. transform: scale(1);
  36. }
  37. }
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
  2. <div class="loading-wrapper">
  3. <div class="loading-before"></div>
  4. <div class="loading-after"></div>
  5. </div>

解决方案非常通用,您可以将它应用于几乎所有这些情况.缺点是,如果你想要堆叠多个这样的转换,那么你最终可能会遇到多个这样的包装器.除了在动画的关键帧中添加原始变换之外,没有纯CSS方式.

下面的代码片段是另一个示例.

  1. .move-n-scale {
  2. position: relative;
  3. height: 100px;
  4. width: 100px;
  5. background: sandybrown;
  6. border: 1px solid chocolate;
  7. transform: scale(0.5);
  8. animation: move 1s linear infinite alternate-reverse;
  9. }
  10. .move {
  11. position: relative;
  12. display: inline-block;
  13. animation: move-only 1s linear infinite alternate-reverse;
  14. }
  15. .scale {
  16. position: absolute;
  17. height: 100px;
  18. width: 100px;
  19. top: 0px;
  20. left: 0px;
  21. background: sandybrown;
  22. border: 1px solid chocolate;
  23. transform: scale(0.5);
  24. }
  25. @keyframes move {
  26. from {
  27. transform: translateX(0px) scale(0.5);
  28. }
  29. to {
  30. transform: translateX(300px) scale(0.5);
  31. }
  32. }
  33. @keyframes move-only {
  34. from {
  35. transform: translateX(0px);
  36. }
  37. to {
  38. transform: translateX(300px);
  39. }
  40. }
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
  2. <div class='move-n-scale'></div>
  3. <div class='move'>
  4. <div class='scale'></div>
  5. </div>

Note: Just to clarify,I did notice that you had mentioned about not wanting a solution which is very specific to this problem like wrap it etc. But,I had still added this solution as an answer because it is the only generic solution which I am aware of. I had added the second snippet only to show that is is indeed generic.

猜你在找的CSS相关文章