【问题标题】:CSS animation on focus reset焦点重置时的 CSS 动画
【发布时间】:2017-06-26 07:33:08
【问题描述】:

我正在为我的按钮制作材质风格的动画。本来想避开任何JS,所以来到了以下样式:

http://codepen.io/Deka87/pen/zNJyqg

// 动画

.btn {
    position: relative;

    &:after {
        content: '';
        position: absolute;
        top: 0; bottom: 0; left: -10%; right: -10%;
        border-top-left-radius: 2% 50%;
        border-bottom-left-radius: 2% 50%;
        border-top-right-radius: 2% 50%;
        border-bottom-right-radius: 2% 50%;
        background-color: fade(black,5%);
        transform: scale(0,1);
        opacity: 0;
    }

    &:focus {

        &:after {
            animation: click-animation .6s linear;
            animation-fill-mode: backwards;
        }
    }
}

@keyframes click-animation {
    0% {
        opacity: 0;
        transform: scale(0,1);
    }
    50% {
        opacity: 1;
        transform: scale(.5,1);
    }
    100% {
        opacity: 0;
        transform: scale(1,1);
    }
}

它的工作原理与预期的差不多(至少在 Chrome 上)。问题是如果您多次单击该按钮,动画只会触发一次。发生这种情况是因为按钮已经“聚焦”,所以它不会重复动画。单击按钮外的任意位置,然后再次单击该按钮可解决此问题。任何想法如何解决这个问题?

【问题讨论】:

  • 要重新启动动画,必须首先将其从元素中移除并重新附加。这是必需的,因为 UA 会跟踪迭代计数。因此,很可能需要通过 JS 删除 focus 或通过 JS 使动画属性的值无效(通过监听 animationend 事件)。也许有人可以用不同的方式重写整个事情并实现你想要的,但是用目前的方法,我认为不使用 JS 是不可能的。
  • 谢谢@Harry。是的,我见过那些带有隐藏单选按钮的例子,但那些看起来更丑。
  • @Harry &:focus:not(:active) { ... } 成功了!
  • 我想说的是聪明的黑客(不,我不会以任何方式贬低答案)。 :not(:active) 意味着当您第二次单击时,锚点为 :active,因此 UA 实际上正在刷新动画(因为它不再适用),然后立即应用 :not(:active)(如 @ 987654327@ 是一个非常短的跨度事件)。非常聪明!

标签: html css animation


【解决方案1】:

您可以将“&:focus”替换为“&:not(:active)”,并在页面加载期间隐藏按钮以处理第一个动画。更多解释在这里:https://www.screenfeed.fr/blog/css3-animation-on-click-without-js-0828/

【讨论】:

  • 哇,这是我可以使用的东西。从来没有想过这种方法。
  • 哈! &:focus:not(:active) { ... } 使这项工作按预期进行,而无需在页面加载时隐藏按钮!
  • @Deka87 这个解决方案显然是违反直觉的,但很有效,而且你的补充:)。
【解决方案2】:

Tyrian 建议使用&:focus:not(:active) 是一个不错的建议。但是,如果您希望在鼠标按下而不是鼠标向上时出现动画,则以下不完全理想的方法可能会有所帮助。

我的方法的问题是动画触发前有 30 毫秒的超时。删除setTimeout 会导致我测试的所有浏览器只播放一次动画。在 Firefox 上,将 30 毫秒超时更改为 10 毫秒似乎会导致竞争条件,从而导致动画无法始终播放。在较慢的浏览器上,延迟可能需要更长的时间。

<script>
function flashButton (elem) {

    "use strict";

    elem.classList.remove("animate");
    setTimeout(function() {
        elem.classList.add("animate");
    }, 30);
}
</script>

<style>
button.animate {
    animation-name: button-animation;
    animation-duration: 0.3s;
}
@keyframes button-animation {  
    from { background: #555555; }
    to   { background: #9F9F9F; }
}
</style>

<button onfocus="flashButton(this)" onmousedown="flashButton(this)">X</button>

代码的工作原理是删除动画类,然后立即重新添加它,以便动画几乎立即发生。

在点击后立即添加类,然后延迟移除它,如果点击的频率高于动画的持续时间,则效果不佳。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2021-11-16
    • 2013-04-09
    • 2011-04-15
    相关资源
    最近更新 更多