AI CSS Animations

Squeezed Text Animation

Two accent bars press in from the sides, the word squashes narrow and stretches tall, then let go and it springs back past its width before settling. One registered number drives word and bars.

Also known as: squash and stretch text, squeeze text css, squishy text animation.

Squeeze

HTML

<div class="txt-squeeze-text"><span>Squeeze</span></div>

CSS

@property --txt-squeeze-text-k {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}
.txt-squeeze-text {
  --c: var(--txt-color, #3b82f6);
  font-size: calc(var(--txt-size, 32px) * 2);
  font-family: system-ui, sans-serif;
  font-weight: 900;
  line-height: 1.2;
  position: relative;
  display: inline-block;
  letter-spacing: -0.02em;
  animation: txt-squeeze-text-press 3.4s infinite;}
.txt-squeeze-text span {
  display: inline-block;
  transform-origin: 50% 80%;
  transform: scale(var(--txt-squeeze-text-k), calc(1 + (1 - var(--txt-squeeze-text-k)) * 0.6));
}
/* the bars ride the word's edges: 50% from the middle times the squeeze */
.txt-squeeze-text::before,
.txt-squeeze-text::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 0.13em;
  height: 1.15em;
  border-radius: 0.1em;
  background: var(--c);
  box-shadow: 0 0.08em 0.25em color-mix(in srgb, var(--c) 35%, transparent);
  translate: 0 -50%;
}
.txt-squeeze-text::before { left: calc(50% - 50% * var(--txt-squeeze-text-k) - 0.26em); }
.txt-squeeze-text::after { right: calc(50% - 50% * var(--txt-squeeze-text-k) - 0.26em); }
@keyframes txt-squeeze-text-press {
  0%, 8%   { --txt-squeeze-text-k: 1; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  36%      { --txt-squeeze-text-k: 0.74; animation-timing-function: ease-in-out; }
  46%      { --txt-squeeze-text-k: 0.71; animation-timing-function: cubic-bezier(0.2, 0.9, 0.3, 1); }
  53%      { --txt-squeeze-text-k: 1.13; animation-timing-function: ease-in-out; }
  60%      { --txt-squeeze-text-k: 0.95; animation-timing-function: ease-in-out; }
  67%      { --txt-squeeze-text-k: 1.03; animation-timing-function: ease-in-out; }
  74%, 100% { --txt-squeeze-text-k: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .txt-squeeze-text { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .txt-squeeze-text, .txt-squeeze-text *, .txt-squeeze-text::before, .txt-squeeze-text::after, .txt-squeeze-text *::before, .txt-squeeze-text *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --txt-color on the element or a parent. Currently previewing #3b82f6.
  • Font size: set --txt-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 40px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar text animations