Two short buzzes and a pause, like a phone on a desk. The jitter is tiny, a fraction of an em with a degree of twist, so it reads as a vibration rather than a shake. Linear steps.
Also known as: css vibrate animation, phone vibration, buzz effect.
<div class="kfa-vibrate"><svg class="kfa-vibrate-icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="7.5" y="3" width="9" height="18" rx="2.2" /><path d="M11 17.5h2M4 9v6M20 9v6" /></svg></div>
.kfa-vibrate {
--c: var(--kfa-color, #3b82f6);
font-size: var(--kfa-size, 16px);
display: grid;
place-items: center;
width: 5.5em;
height: 5.5em;
border-radius: 1em;
background: var(--c);
color: #fff;
font-family: system-ui, sans-serif;
font-weight: 700;
box-shadow: 0 0.6em 1.4em -0.6em color-mix(in srgb, var(--c) 70%, transparent);
animation: kfa-vibrate-buzz 1.4s linear infinite;
}
.kfa-vibrate-icon {
width: 2.6em;
height: 2.6em;
fill: none;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
}
@keyframes kfa-vibrate-buzz {
0%, 30%, 38%, 68%, 100% { transform: translate(0, 0) rotate(0); }
3%, 9%, 15%, 21%, 27%, 41%, 47%, 53%, 59%, 65% { transform: translate(-0.14em, 0.05em) rotate(-1.5deg); }
6%, 12%, 18%, 24%, 44%, 50%, 56%, 62% { transform: translate(0.14em, -0.05em) rotate(1.5deg); }
}
@media (prefers-reduced-motion: reduce) {
.kfa-vibrate, .kfa-vibrate *, .kfa-vibrate::before, .kfa-vibrate::after, .kfa-vibrate *::before, .kfa-vibrate *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--kfa-color on the element or a parent.
Currently previewing #3b82f6.--kfa-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.