css design tutorial animation

CSS Neon Glow Effects — No Images, Just box-shadow

 //  Your Name

Real neon signs glow because gas plasma emits light in all directions. We can fake this with CSS using nothing but box-shadow — stacked at two radii with different opacities.

The Two-Layer Glow Formula

.neon-element {
  box-shadow:
    0 0 8px rgba(224, 64, 251, 0.6),   /* tight inner glow */
    0 0 24px rgba(224, 64, 251, 0.3);  /* wide outer halo */
}

The key insight: the inner layer (8px) is high opacity for crispness; the outer layer (24px) is low opacity for the soft halo. Together they read as a real neon bloom.

Animating the Glow

For hover transitions, always animate box-shadow between two defined states:

.btn {
  box-shadow:
    0 0 8px rgba(224, 64, 251, 0.4),
    0 0 20px rgba(224, 64, 251, 0.15);
  transition: box-shadow 0.2s ease;
}

.btn:hover {
  box-shadow:
    0 0 12px rgba(224, 64, 251, 0.9),
    0 0 40px rgba(224, 64, 251, 0.5);
}

Do NOT animate filter: drop-shadow — it triggers GPU compositing on every frame.

Text Glow

For text, use text-shadow:

.neon-title {
  color: #e040fb;
  text-shadow:
    0 0 8px rgba(224, 64, 251, 0.8),
    0 0 20px rgba(224, 64, 251, 0.4);
}

Keep text-shadow radius small (8–12px) — wide text glow looks muddy.

The Perspective Grid

The Neon Noir background grid is a CSS gradient with a directional mask:

body::before {
  background-image:
    linear-gradient(rgba(224, 64, 251, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(224, 64, 251, 0.07) 1px, transparent 1px);
  background-size: 60px 60px;

  /* Fade toward the top — floor perspective illusion */
  mask-image: linear-gradient(
    to top,
    rgba(0,0,0,0.6) 0%,
    rgba(0,0,0,0.1) 40%,
    transparent 70%
  );
}

The mask makes the grid dense near the “floor” and invisible at the “horizon” — no JavaScript required.

Glitch with clip-path

The glitch animation uses clip-path: polygon() to slice the element into horizontal strips:

@keyframes glitch {
  0%   { clip-path: polygon(0 0%, 100% 0%, 100% 30%, 0 30%); }
  50%  { clip-path: polygon(0 40%, 100% 40%, 100% 70%, 0 70%); }
  100% { clip-path: polygon(0 0%, 100% 0%, 100% 100%, 0 100%); }
}

.glitch::before {
  content: attr(data-text);
  color: cyan;
  animation: glitch 0.4s steps(1) forwards;
  transform: translateX(-2px);
}

Run at steps(1) — continuous easing looks wrong. Glitch should snap between frames.

Theme by csswitch · Remove attribution →