CSS animation similar to Mac OS X 10.8 invalid password "shake"?

Kevin Hakanson picture Kevin Hakanson · Mar 31, 2013 · Viewed 14.2k times · Source

On the Mac OS X 10.8 "password" screen, if you enter an invalid password, it will "shake" back and forth (a.k.a. left and right). I am trying to achieve an similar effect for an HTML password input field using CSS animations.

I created a "Password Shake" jsfiddle that seems to emulate this behavior. However, it doesn't seem quite right. I'm not sure the explicit keyframes and the linear timing function are the right approach. This is my first attempt at a CSS animation, and I'm looking for feedback on the right way to achieve this.

HTML

<div class="box">
    <input type="password" id="demo-password" placeholder="password" autofocus />
</div>

JavaScript

$('#demo-password').on('keyup', function (e) {
    var $input = $(this);
    var val = $.trim($input.val());
    $input.removeClass("invalid");

    if (e.which !== 13 || !val) {
        return;
    }

    if (val != "password") {
        $input.select();   
        $input.addClass("invalid");
    }
});

CSS

#demo-password.invalid {
    outline-color: red;
    /* also need animation and -moz-animation */
    -webkit-animation: shake .6s linear;
}
/* also need keyframes and -moz-keyframes */
 @-webkit-keyframes shake {
    0% {
        left:-10px;
    }
    16% {
        left:9px;
    }
    33% {
        left:-6px;
    }
    50% {
        left:5px;
    }
    66% {
        left:-2px;
    }
    83% {
        left:1px;
    }
    100% {
        left: 0px;
    }
}

Edit

I did find Animate.css which has a shake animation. I've included the (non browser prefixed) CSS below. Instead of setting left is does a transform: translateX(), which likely has a better chance for hardware acceleration.

.animated {
    animation-duration: 1s;
    animation-fill-mode: both;
}

@keyframes shake {
    0%, 100% {transform: translateX(0);}
    10%, 30%, 50%, 70%, 90% {transform: translateX(-10px);}
    20%, 40%, 60%, 80% {transform: translateX(10px);}
}

.shake {
    animation-name: shake;
}

Answer

Kevin Hakanson picture Kevin Hakanson · Apr 13, 2013

I used my iPad camera to record the Mac pasword screen. It looks like it shakes 3 times each direction, with the first 2 going the full distance and the last 1 time a lesser distance.

#demo-password.invalid {
    outline-color: red;
    /* also need animation and -moz-animation */
    -webkit-animation: shake .5s linear;
}
/* also need keyframes and -moz-keyframes */
 @-webkit-keyframes shake {
    8%, 41% {
        -webkit-transform: translateX(-10px);
    }
    25%, 58% {
        -webkit-transform: translateX(10px);
    }
    75% {
        -webkit-transform: translateX(-5px);
    }
    92% {
        -webkit-transform: translateX(5px);
    }
    0%, 100% {
        -webkit-transform: translateX(0);
    }
}