AI CSS Animations

Lightning Strike Text

A forked bolt cracks down onto the word, the letters flash white hot in your accent glow, then slowly cool until the next strike. The bolt is an SVG path drawn with stroke-dashoffset.

Also known as: css lightning effect, lightning text animation, thunder strike text, lightning bolt css.

THUNDER

HTML

<div class="txt-lightning-strike-text">
  <svg class="txt-lightning-strike-text-bolt" viewBox="0 0 40 50" aria-hidden="true">
    <path d="M23 0 L20 8 L24 11 L17 21 L22 23 L15 35 L19 37 L13 50" pathLength="1" />
    <path class="txt-lightning-strike-text-fork" d="M17 21 L11 25 L13 28 L7 34" pathLength="1" />
  </svg>
  <span class="txt-lightning-strike-text-word">THUNDER</span>
</div>

CSS

.txt-lightning-strike-text {
  --c: var(--txt-color, #3b82f6);
  font-size: calc(var(--txt-size, 32px) * 1.5);
  font-family: system-ui, sans-serif;
  font-weight: 900;
  line-height: 1.2;
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  letter-spacing: 0.1em;}
.txt-lightning-strike-text::before {
  content: "";
  position: absolute;
  inset: -0.4em -1em;
  z-index: -1;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--c) 30%, transparent), transparent);
  opacity: 0;
  animation: txt-lightning-strike-text-flash 3.6s linear infinite;
}
.txt-lightning-strike-text-bolt {
  width: 1.5em;
  height: 1.9em;
  margin-bottom: -0.25em;
  overflow: visible;
}
.txt-lightning-strike-text-bolt path {
  fill: none;
  stroke: color-mix(in srgb, var(--c) 55%, #fff);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  filter: drop-shadow(0 0 0.03em var(--c)) drop-shadow(0 0 0.12em var(--c));
  animation: txt-lightning-strike-text-bolt 3.6s linear infinite;
}
.txt-lightning-strike-text-bolt .txt-lightning-strike-text-fork {
  stroke-width: 1.5;
}
.txt-lightning-strike-text-word {
  color: color-mix(in srgb, var(--c) 55%, transparent);
  text-shadow: 0 0 0 transparent, 0 0 0 transparent;
  animation: txt-lightning-strike-text-charge 3.6s cubic-bezier(0.2, 0.7, 0.3, 1) infinite;
}
@keyframes txt-lightning-strike-text-bolt {
  0%   { stroke-dashoffset: 1; opacity: 1; }
  3%   { stroke-dashoffset: 0; opacity: 1; }
  5%   { opacity: 0.2; }
  7%   { opacity: 1; }
  14%  { stroke-dashoffset: 0; opacity: 0; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes txt-lightning-strike-text-charge {
  0%, 2% { color: color-mix(in srgb, var(--c) 55%, transparent); text-shadow: 0 0 0 transparent, 0 0 0 transparent; }
  4%     { color: #fff; text-shadow: 0 0 0.08em #fff, 0 0 0.5em var(--c); }
  6%     { color: color-mix(in srgb, var(--c) 40%, #fff); text-shadow: 0 0 0.04em var(--c), 0 0 0.2em var(--c); }
  8%     { color: #fff; text-shadow: 0 0 0.08em #fff, 0 0 0.55em var(--c); }
  40%    { color: color-mix(in srgb, var(--c) 70%, #fff); text-shadow: 0 0 0.04em var(--c), 0 0 0.25em color-mix(in srgb, var(--c) 60%, transparent); }
  100%   { color: color-mix(in srgb, var(--c) 55%, transparent); text-shadow: 0 0 0 transparent, 0 0 0 transparent; }
}
@keyframes txt-lightning-strike-text-flash {
  0%, 2%, 16%, 100% { opacity: 0; }
  4%, 8%            { opacity: 1; }
  6%                { opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
  .txt-lightning-strike-text::before, .txt-lightning-strike-text-bolt path, .txt-lightning-strike-text-word { animation: none; }
  .txt-lightning-strike-text-bolt path { stroke-dashoffset: 0; }
  .txt-lightning-strike-text-word { color: var(--c); }
}

@media (prefers-reduced-motion: reduce) {
  .txt-lightning-strike-text, .txt-lightning-strike-text *, .txt-lightning-strike-text::before, .txt-lightning-strike-text::after, .txt-lightning-strike-text *::before, .txt-lightning-strike-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