3 Pure CSS4 with JSPublished 2026-10-05Free · no sign-up
Seven shakes with a purpose: a sign-in card that shakes on a wrong password, a ringing notification bell, a call to action that wiggles now and then, nods for yes and shakes for no, icons that jiggle in edit mode, a phone that buzzes and one configurable shake at three strengths.
The whole sign-in card shakes when the password is wrong, a familiar signal borrowed from phone lock screens. The error is also written below the field and announced through an alert region, so the shake is never the only feedback.
var f = document.querySelector('.sk1'), m = f.querySelector('p');
f.addEventListener('submit', function (e) { e.preventDefault(); f.classList.remove('no'); void f.offsetWidth; f.classList.add('no'); m.textContent = 'That password is not right. This demo never accepts one.'; f.querySelector('input').select(); });
02. Ringing Notification Bell
ShakeIcon
A bell icon swings from its top when a new notification arrives: a rotate animation with transform-origin at the top centre, damped over five swings. The button's label includes the unread count, which is what assistive technology relies on.
A call-to-action wiggles briefly every few seconds to catch the eye, then rests: the keyframes do their movement in the first 15 percent and stay still for the rest of a five-second loop. Hovering or focusing stops it, since the person has already found it.
View code
<button class="sk3">Claim your free month</button>
Two emoji-free faces: one nods vertically for yes and one shakes horizontally for no, the same body language people use. Press each button to replay, and the result is announced in text beside them.
var p = document.querySelector('.sk4 p');
document.querySelectorAll('.sk4 button').forEach(function (b) { b.onclick = function () { b.classList.remove('go'); void b.offsetWidth; b.classList.add('go'); p.textContent = b.classList.contains('y') ? 'Yes, that is right.' : 'No, try again.'; }; });
05. Edit Mode Icon Jiggle
ShakeEdit
App icons jiggle while in edit mode, as on phone home screens. Each icon has a slightly different animation delay so they do not move in unison, and the Edit button is a toggle with aria-pressed that turns the whole mode on and off.
var w = document.querySelector('.sk5'), b = w.querySelector('button');
b.onclick = function () { var on = w.classList.toggle('edit'); b.setAttribute('aria-pressed', on); b.textContent = on ? 'Done' : 'Edit'; };
06. Incoming Call Buzz
ShakeIcon
A phone icon buzzes in short bursts, combining a small rotation with a sideways shift so it reads as vibration rather than swinging. The answer and decline buttons below it are labelled, coloured and have text, because a call screen must be clear.
View code
<div class="sk6"><span class="ic" aria-hidden="true">📞</span><p>Mum is calling</p><div><button class="no">Decline</button><button class="ok">Answer</button></div></div>
Subtle, medium and strong shakes side by side, so you can pick the intensity that suits the message. They share one set of keyframes that read the distance from a custom property, which shows how to make one animation configurable.
A sideways shake reads as a refusal, so use it for errors and wrong answers, and a vertical nod for success. Pair it with a written message every time; the motion alone tells a screen reader user nothing.
Replay with a reflow
To run the same animation again, remove the class, force a reflow by reading offsetWidth, then add the class back. Without the reflow the browser sees no change and does nothing.
Keep it short
Error shakes should last about 300 to 500ms with small distances, around 4 to 10 pixels. Anything longer feels like the page is broken.
Attention without nagging
A looping wiggle should spend most of its cycle at rest and stop on hover or focus. Under prefers-reduced-motion every shake here is switched off and the colour or text change remains.
Frequently asked questions
Can I change the shake distance?
Yes. The last demo reads it from a custom property, so one keyframe set serves all three strengths.
Will a shake trigger motion sickness?
Short, small shakes rarely do, but they are still disabled for people who ask for reduced motion.
Do I need a library?
No. Each shake is a few lines of @keyframes with transform.