【问题标题】:Choppy and Jerky CSS3 animation in Firefox on new "page load"新“页面加载”时 Firefox 中的 Choppy 和 Jerky CSS3 动画
【发布时间】:2026-01-23 07:00:02
【问题描述】:

当我导航到我的一个子页面时,我试图将 CSS3 动画显示为加载器动画。 我在rotateY 上使用关键帧动画。 问题是在 Firefox 上,当导航到另一个页面时,动画确实可以工作,但它非常生涩和不稳定。

在 Chrome 和 Safari 上,相同的动画效果流畅而完美。

这是一个小提琴: http://jsfiddle.net/p6mgxpbo/

HTML:

<div class="gb-loading">
    <div id="animatedElem" class="pin-c">
        <div class='pin'></div>    
    </div>
    <div class="pin-mirror"></div>
    <div id="gb-lb" class="load-bounce"></div>
</div>

CSS:

.gb-loading {
        position: fixed;
        left: 0;
        right: 0;
        top: 50%;
        bottom: 0;
        width: 70px;
        height: 70px;
        margin: auto;
        z-index: 101;
        margin-top: -100px;
    }
    .pin-c {
        width: 70px;
        height: 70px;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 11;

        -webkit-animation: pulsate 1.5s linear infinite;
           -moz-animation: pulsate 1.5s linear infinite;
             -o-animation: pulsate 1.5s linear infinite;
                animation: pulsate 1.5s linear infinite;
    }
    .pin {
        width: 70px;
        height: 70px;
        background-color: #34baab;
        position: absolute;
        left: 0;
        top: 0;

      -webkit-border-radius: 50% 50% 50% 0;
              border-radius: 50% 50% 50% 0;

      -webkit-transform: rotate(-45deg);
         -moz-transform: rotate(-45deg);
           -o-transform: rotate(-45deg);
              transform: rotate(-45deg);
    }

    .pin-mirror {
        width: 70px;
        height: 70px;
        background-color: #003146;
        position: absolute;
        left: 0;
        bottom: -48px;
        z-index: -1;

      -webkit-border-radius: 50% 0 50% 50%;
              border-radius: 50% 0 50% 50%;

      -webkit-transform: rotate(-45deg);
         -moz-transform: rotate(-45deg);
           -o-transform: rotate(-45deg);
              transform: rotate(-45deg);
    }

    .pin:after {
        content: '';
        width: 25px;
        height: 25px;
        margin: 22px 0 0 22px;
        background-color: #003146;
        position: absolute;

        -webkit-border-radius: 50%;
                border-radius: 50%;
    }

    .load-bounce {
        width: 25px;
        height: 25px;
        position: absolute;

        left: 65px;
        background-color: #003146;
        -webkit-transform: translateZ(0.5);
           -moz-transform: translateZ(0.5);
                transform: translateZ(0.5);

        -webkit-border-radius: 50%;
                border-radius: 50%;

        -webkit-animation: bounce .5s linear infinite alternate;
           -moz-animation: bounce .5s linear infinite alternate;
             -o-animation: bounce .5s linear infinite alternate;
                animation: bounce .5s linear infinite alternate;
    }

    @-webkit-keyframes pulsate {
        0% {

            -webkit-transform: rotateY(0deg);
        }          
        100% {

            -webkit-transform: rotateY(360deg);
        }
    }

    @-moz-keyframes pulsate {
        0% {

            -moz-transform: rotateY(0deg);
        }
        100% {

            -moz-transform: rotateY(360deg);
        }
    }

    @keyframes pulsate {
        0% {

            transform: rotateY(0deg);
        }
        100% {

            transform: rotateY(360deg);
        }
    }

    @-webkit-keyframes bounce {
        0% {
            -webkit-transform: translateY(-10px);

        }
        100% {
            -webkit-transform: translateY(-40px);
        }
    }
    @keyframes bounce {
        0% {
            transform: translateY(-10px);

        }
        100% {
            transform: translateY(-40px);
        }
    }

    @-moz-keyframes bounce {
        0% {
            -moz-transform: translateY(-10px);

        }
        100% {
            -moz-transform: translateY(-40px);
        }
    }

只有当它出现在加载其他资源的页面上时才会出现。我正在尝试将此元素用作预加载动画。所以它在页面上,直到页面的其余部分正在加载。我在同一页面上也有谷歌地图。因此,当浏览器正在下载其他资源时,动画会出现抖动。您将看不到小提琴上的混蛋。

需要一些有关如何解决此问题的见解。 提前致谢!!

P.S:我确实在 * 上浏览了很多与此相关的答案,并尝试在 Google 上搜索,但无济于事。

【问题讨论】:

  • 你能分享你的代码吗?在没有看到它的情况下调试它几乎是……不可能的?
  • 您需要在问题本身中包含代码。否则它可能会被关闭。
  • 在这里工作非常顺利。
  • 我也是,我在 FF 和 chrome 中尝试过,没有混蛋。
  • @ShubhamSharma:问题是我们无法帮助解决我们看不到的问题。因此,如果您无法在小提琴上重现该行为,那么将很难找到答案。

标签: css firefox css-animations keyframe


【解决方案1】:

很遗憾,这是您无法通过浏览器修复、修改或控制的问题。您将不得不使用某种形式的 hack 来使其工作或混淆系统以执行您想要的操作,但从正常渲染来看,它不会工作。


您可以做的是为动画添加延迟。

-webkit-animation: pulsate 0.8s linear 10ms infinite;
-moz-animation: pulsate 0.8s linear 10ms infinite;
-o-animation: pulsate 0.8s linear 10ms infinite;
animation: pulsate 0.8s linear 10ms infinite;

JSFiddle Example

这会做的是让页面渲染、绘制和显示,然后它会在开始动画之前等待 100 毫秒(0.1 秒)。

如果这不起作用,则归结为 FF 没有像 Chrome 或其他一些浏览器那样干净地渲染动画,这只是一个浏览器问题,而且很难解决。


每个浏览器都有一个完全不同的树、渲染和绘制过程,用于在您的显示器上显示 HTML 和 CSS。 Gecko (FF) 和 WebKit (Chrome) 都使用完全不同的方法和流程来显示页面,遗憾的是,在制作动画时,Gecko 在启动动画时的延迟最小,这就是为什么你会看到一点点动画开始时的延迟/抖动。

Webkit 流程

壁虎流

从上面的流程可以看出,两个流程完全不同,DOM 的加载、渲染、绘制和显示方式也完全不同。

希望这有助于解决问题。

我添加了一篇关于浏览器渲染的最佳信息供您阅读。了解浏览器在前端工作时的工作原理总是好的。

【讨论】:

    【解决方案2】:

    我正在使用带有 box-shadow 的关键帧来创建动画。然后,我使用动画命令选择关键帧名称并定义动画的一些细节(持续时间、延迟等...)。

    #myanimation{
      animation: x 1s 1 ease-out ;
      -webkit-animation: x 1s 1 ;
      -webkit-backface-visibility: hidden;
      -moz-animation: x 1s 1;
      -o-animation: x 1s 1 ;
    }
    

    我不会发布我的关键帧,因为它很长。但是,即使我的动画持续时间只有 1 秒,我也遇到了延迟。 我尝试了一切来修复滞后,我添加了线性,缓入等。各种标签到动画commnad但不成功。

    最后,我只是

    停用插件

    (因为附加组件也会降低 Firefox 的性能,尤其是阻止附加组件的附加组件)。停用我所有的附加组件后,它运行良好。

    【讨论】:

      【解决方案3】:

      由于某种原因,当您使用 Skew(0.1deg) 进行动画处理时,它并不不稳定。 这是在 Firefox 91.0(64 位)上。

      .test {
          animation: breath2 0.8s linear 10ms infinite alternate;    
      }
      @keyframes breath2 { 
          0%  { transform: skewX(0.1deg) scaleX(1) translateY(-10px)}
          100% { transform: skewX(0.1deg) scaleX(0.95) translateY(10px)}
      }
      

      .button {
        border: 1px solid green;
        height: 50px;
        width: 150px;
        border-radius: var(--border-radius);
        position: relative;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-align: center;
            -ms-flex-align: center;
                align-items: center;
        -webkit-box-pack: center;
            -ms-flex-pack: center;
                justify-content: center;
        -webkit-transition: all 0.2s ease;
        transition: all 0.2s ease;
        font: 15px sans-serif;
        font-weight: 300;
        text-shadow: 0 0 20px #fff;
        text-transform: uppercase;
        -webkit-animation: breath2 0.8s linear 10ms infinite alternate;
                animation: breath2 0.8s linear 10ms infinite alternate;
        cursor: pointer;
        margin-top: 10px;
        text-decoration: none;
      }
      
      .button:before {
        content: "";
        display: block;
        width: calc(100% - 10px);
        height: calc(50px - 8px);
        left: 5px;
        top: 3px;
        position: absolute;
        background-color: transparent;
        border: 1px solid #fff;
        border-radius: var(--border-radius-before);
      }
      
      .button.fire {
        border-color: #ffeca8;
        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 138, 48, 0.6)), to(rgba(240, 96, 29, 0.6)));
        background-image: linear-gradient(to bottom, rgba(255, 138, 48, 0.6), rgba(240, 96, 29, 0.6));
        -webkit-box-shadow: 0 0 0px rgba(255, 138, 48, 0.6), 0 0px 3px rgba(240, 96, 29, 0.6), inset 0 1px #ffeca8, inset 0 -1px #ffeca8;
                box-shadow: 0 0 0px rgba(255, 138, 48, 0.6), 0 0px 3px rgba(240, 96, 29, 0.6), inset 0 1px #ffeca8, inset 0 -1px #ffeca8;
        color: #ffeca8;
      }
      
      .button.fire::before {
        -webkit-box-shadow: inset 0 0 20px #ffeca8;
                box-shadow: inset 0 0 20px #ffeca8;
      }
      
      .button.ice {
        border-color: #a8ecff;
        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(48, 138, 255, 0.6)), to(rgba(29, 96, 240, 0.6)));
        background-image: linear-gradient(to bottom, rgba(48, 138, 255, 0.6), rgba(29, 96, 240, 0.6));
        -webkit-box-shadow: 0 0 0px rgba(48, 138, 255, 0.6), 0 0px 3px rgba(29, 96, 240, 0.6), inset 0 1px #a8ecff, inset 0 -1px #a8ecff;
                box-shadow: 0 0 0px rgba(48, 138, 255, 0.6), 0 0px 3px rgba(29, 96, 240, 0.6), inset 0 1px #a8ecff, inset 0 -1px #a8ecff;
        color: #a8ecff;
      }
      
      .button.ice::before {
        -webkit-box-shadow: inset 0 0 20px #a8ecff;
                box-shadow: inset 0 0 20px #a8ecff;
      }
      
      .button.blaze {
        border-color: #ffa8a8;
        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(156, 20, 20, 0.6)), to(rgba(240, 29, 29, 0.6)));
        background-image: linear-gradient(to bottom, rgba(156, 20, 20, 0.6), rgba(240, 29, 29, 0.6));
        -webkit-box-shadow: 0 0 0px rgba(156, 20, 20, 0.6), 0 0px 3px rgba(240, 29, 29, 0.6), inset 0 1px #ffa8a8, inset 0 -1px #ffa8a8;
                box-shadow: 0 0 0px rgba(156, 20, 20, 0.6), 0 0px 3px rgba(240, 29, 29, 0.6), inset 0 1px #ffa8a8, inset 0 -1px #ffa8a8;
        color: #ffa8a8;
      }
      
      .button.blaze::before {
        -webkit-box-shadow: inset 0 0 20px #ffa8a8;
                box-shadow: inset 0 0 20px #ffa8a8;
      }
      
      .button.nature {
        border-color: #b7ffa8;
        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(9, 134, 15, 0.6)), to(rgba(36, 240, 29, 0.6)));
        background-image: linear-gradient(to bottom, rgba(9, 134, 15, 0.6), rgba(36, 240, 29, 0.6));
        -webkit-box-shadow: 0 0 0px rgba(9, 134, 15, 0.6), 0 0px 3px rgba(36, 240, 29, 0.6), inset 0 1px #b7ffa8, inset 0 -1px #b7ffa8;
                box-shadow: 0 0 0px rgba(9, 134, 15, 0.6), 0 0px 3px rgba(36, 240, 29, 0.6), inset 0 1px #b7ffa8, inset 0 -1px #b7ffa8;
        color: #b7ffa8;
      }
      
      .button.nature::before {
        -webkit-box-shadow: inset 0 0 20px #b7ffa8;
                box-shadow: inset 0 0 20px #b7ffa8;
      }
      
      .button:hover {
        text-decoration: none;
      }
      
      .button:hover.fire {
        -webkit-box-shadow: 0 0 10px rgba(255, 138, 48, 0.8), inset 0 1px #ffeca8, inset 0 -1px #ffeca8;
                box-shadow: 0 0 10px rgba(255, 138, 48, 0.8), inset 0 1px #ffeca8, inset 0 -1px #ffeca8;
      }
      
      .button:hover.fire:before {
        -webkit-box-shadow: inset 0 0 50px 0 #ffeca8;
                box-shadow: inset 0 0 50px 0 #ffeca8;
      }
      
      .button:hover.ice {
        -webkit-box-shadow: 0 0 10px rgba(48, 138, 255, 0.8), inset 0 1px #a8ecff, inset 0 -1px #a8ecff;
                box-shadow: 0 0 10px rgba(48, 138, 255, 0.8), inset 0 1px #a8ecff, inset 0 -1px #a8ecff;
      }
      
      .button:hover.ice:before {
        -webkit-box-shadow: inset 0 0 50px 0 #a8ecff;
                box-shadow: inset 0 0 50px 0 #a8ecff;
      }
      
      .button:hover.blaze {
        -webkit-box-shadow: 0 0 10px rgba(156, 20, 20, 0.8), inset 0 1px #ffa8a8, inset 0 -1px #ffa8a8;
                box-shadow: 0 0 10px rgba(156, 20, 20, 0.8), inset 0 1px #ffa8a8, inset 0 -1px #ffa8a8;
      }
      
      .button:hover.blaze:before {
        -webkit-box-shadow: inset 0 0 50px 0 #ffa8a8;
                box-shadow: inset 0 0 50px 0 #ffa8a8;
      }
      
      .button:hover.nature {
        -webkit-box-shadow: 0 0 10px rgba(9, 134, 15, 0.8), inset 0 1px #b7ffa8, inset 0 -1px #b7ffa8;
                box-shadow: 0 0 10px rgba(9, 134, 15, 0.8), inset 0 1px #b7ffa8, inset 0 -1px #b7ffa8;
      }
      
      .button:hover.nature:before {
        -webkit-box-shadow: inset 0 0 50px 0 #b7ffa8;
                box-shadow: inset 0 0 50px 0 #b7ffa8;
      }
      
      .button:hover + .button:hover {
        margin-top: 15px;
        -webkit-animation-delay: 0.3s;
                animation-delay: 0.3s;
      }
      
      .breathingMain {
        -webkit-animation: breath2 2s 0.5s infinite alternate;
                animation: breath2 2s 0.5s infinite alternate;
      }
      
      @-webkit-keyframes breath {
        0% {
          -webkit-transform: scaleX(1);
                  transform: scaleX(1);
        }
        100% {
          -webkit-transform: scaleX(0.95);
                  transform: scaleX(0.95);
        }
      }
      
      @keyframes breath {
        0% {
          -webkit-transform: scaleX(1);
                  transform: scaleX(1);
        }
        100% {
          -webkit-transform: scaleX(0.95);
                  transform: scaleX(0.95);
        }
      }
      
      .test {
        -webkit-animation: breath2 0.8s linear 10ms infinite alternate;
                animation: breath2 0.8s linear 10ms infinite alternate;
      }
      
      @-webkit-keyframes breath2 {
        0% {
          -webkit-transform: skewX(0.1deg) scaleX(1) translateY(-10px);
                  transform: skewX(0.1deg) scaleX(1) translateY(-10px);
        }
        100% {
          -webkit-transform: skewX(0.1deg) scaleX(0.95) translateY(10px);
                  transform: skewX(0.1deg) scaleX(0.95) translateY(10px);
        }
      }
      
      @keyframes breath2 {
        0% {
          -webkit-transform: skewX(0.1deg) scaleX(1) translateY(-10px);
                  transform: skewX(0.1deg) scaleX(1) translateY(-10px);
        }
        100% {
          -webkit-transform: skewX(0.1deg) scaleX(0.95) translateY(10px);
                  transform: skewX(0.1deg) scaleX(0.95) translateY(10px);
        }
      }
      
      @-webkit-keyframes breath2_orig {
        0% {
          -webkit-transform: skewX(-10deg) scaleX(1);
                  transform: skewX(-10deg) scaleX(1);
        }
        100% {
          -webkit-transform: skewX(-10deg) scaleX(0.95);
                  transform: skewX(-10deg) scaleX(0.95);
        }
      }
      
      @keyframes breath2_orig {
        0% {
          -webkit-transform: skewX(-10deg) scaleX(1);
                  transform: skewX(-10deg) scaleX(1);
        }
        100% {
          -webkit-transform: skewX(-10deg) scaleX(0.95);
                  transform: skewX(-10deg) scaleX(0.95);
        }
      }
      /*# sourceMappingURL=buttons.css.map */
      <div class="container">
        <button class="button ice">Button</button>
      </div>

      抱歉,sn-p 太长了(我的第一个贡献:))

      【讨论】:

        最近更新 更多