AI CSS Animations

Frost Creep Text with Glint

Rime frost creeps across cold blue letters from left to right, a star glint catches the last letter, then it all thaws back. The frost is a noise texture clipped to the text and swept in by a mask.

Also known as: frost text effect, frozen text css, ice crystal text animation, frosty text.

Glacier

HTML

<div class="txt-frost-glint-text">
  <span class="txt-frost-glint-text-word">Glacier</span>
  <span class="txt-frost-glint-text-frost" aria-hidden="true">Glacier</span>
  <span class="txt-frost-glint-text-glint" aria-hidden="true"></span>
</div>

CSS

.txt-frost-glint-text {
  --c: var(--txt-color, #3b82f6);
  font-size: calc(var(--txt-size, 32px) * 1.7);
  font-family: system-ui, sans-serif;
  font-weight: 900;
  line-height: 1.2;
  position: relative;
  display: inline-grid;
  letter-spacing: 0.02em;
  filter: drop-shadow(0 0 0.012em color-mix(in srgb, var(--c) 60%, #082f49)) drop-shadow(0 0 0.006em color-mix(in srgb, var(--c) 60%, #082f49)) drop-shadow(0 0.03em 0.04em color-mix(in srgb, var(--c) 30%, rgb(12 74 110 / 0.35)));}
.txt-frost-glint-text > span {
  grid-area: 1 / 1;
}
.txt-frost-glint-text-word {
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 35%, #e0f2fe) 0%, color-mix(in srgb, var(--c) 70%, #38bdf8) 55%, color-mix(in srgb, var(--c) 60%, #0c4a6e) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.txt-frost-glint-text-frost {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 3.2 -1.3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 2.4em 2.4em,
    linear-gradient(180deg, #f5faff, color-mix(in srgb, var(--c) 30%, #cfe6fb));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  -webkit-mask: linear-gradient(100deg, #000 42%, transparent 58%) 100% 0 / 260% 100% no-repeat;
  mask: linear-gradient(100deg, #000 42%, transparent 58%) 100% 0 / 260% 100% no-repeat;
  animation: txt-frost-glint-text-creep 6s cubic-bezier(0.5, 0, 0.3, 1) infinite;
}
.txt-frost-glint-text-glint {
  justify-self: end;
  align-self: start;
  width: 0.55em;
  height: 0.55em;
  margin: -0.12em -0.18em 0 0;
  background: radial-gradient(circle, #fff 16%, color-mix(in srgb, var(--c) 75%, #fff) 55%);
  clip-path: polygon(50% 0, 57% 43%, 100% 50%, 57% 57%, 50% 100%, 43% 57%, 0 50%, 43% 43%);
  transform: scale(0) rotate(-45deg);
  animation: txt-frost-glint-text-glint 6s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
@keyframes txt-frost-glint-text-creep {
  0%, 6%    { -webkit-mask-position: 100% 0; mask-position: 100% 0; opacity: 1; }
  46%, 80%  { -webkit-mask-position: 0% 0; mask-position: 0% 0; opacity: 1; }
  94%, 100% { -webkit-mask-position: 0% 0; mask-position: 0% 0; opacity: 0; }
}
@keyframes txt-frost-glint-text-glint {
  0%, 44%   { transform: scale(0) rotate(-45deg); }
  52%       { transform: scale(1) rotate(0deg); }
  60%, 100% { transform: scale(0) rotate(30deg); }
}
@media (prefers-reduced-motion: reduce) {
  .txt-frost-glint-text-frost, .txt-frost-glint-text-glint { animation: none; }
  .txt-frost-glint-text-frost { -webkit-mask-position: 0% 0; mask-position: 0% 0; }
}

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