The Glitched Goblet Logo

The Glitched Goblet

Where Magic Meets Technology

10 Fun Neon CSS Flourishes to Add Some Personality

April 28, 2025

Intro

I always love those CSS articles of various styles and cool effects. So for today, I'd like to contribute my own group of "The Glitched Goblet" styles. These are all made to work in modern browsers, and are all subtle enough to not be annoying.

This blog post is best experienced on a dark background, so if you’re reading this in light mode, switch to dark mode for the full effect. I may make another part 2 to this post for lighter backgrounds if there's enough interest.

1. Soft‑Glow Neon Text Shadow

It gives headings that arcade‑cabinet glow. Just be sure to use it sparingly. Too much and it’s like a glowing sun.

.cool-heading {
  color: #00e9ff;
  text-shadow: 0 0 2px #00e9ff, 0 0 20px #0088ff;
}

2. “Circuit Blink” Caret Animation

A skinny ::after bar that blips every 750 ms like a terminal cursor. Great for giving that “typing” feel.

.typey::after {
  content: '';
  display: inline-block;
  width: 0.6ch;
  height: 1em;
  margin-left: 0.1ch;
  background: currentColor;
  animation: blink 750ms steps(1) infinite;
}
@keyframes blink {
  50% {
    opacity: 0;
  }
}

Prefers‑reduced‑motion? Wrap the animation in:

@media (prefers-reduced-motion: reduce) {
  .typey::after {
    animation: none;
  }
}

3. Cyber‑Card Hover Lift

Cards levitate and crank the glow just a smidge.

Hover over the card below to see it in action!

.card {
  background: #111;
  border-radius: 1rem;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 4px 20px #00ffff55;
}

4. Glitch‑Edge Button Press

A button that's literally tilted. Everyone loves a good button interaction! And I get so bored of the darken on hover that we've grown used to. So why not make them a little more fun?

.button {
  position: relative;
  overflow: hidden;
  background: #4f46e5;
  color: #000;
  transition: transform 0.1s ease;
}
.button:hover {
  background: #3c36b2;
  transform: translate(1px, -1px) skewX(1deg) skewY(-1deg);
}
.button:active {
  transform: translate(-1px, 1px) skewX(-1deg) skewY(1deg);
}

5. Notification “Ping‑Ring”

Subtle-ish concentric ring that expands then fades. It's a great way for grabbing the users attention. Obviously this example is sped up for demo purposes, but could be made to remind the user that there is something to look at.

@keyframes pulseRing {
  0% {
    transform: scale(1);
    opacity: 0.6;
  }
  100% {
    transform: scale(1.8);
    opacity: 0;
  }
}

.pulsing-button-wrapper {
  position: relative;
  display: inline-block;
}

.pulsing-ring {
  position: absolute;
  inset: 0;
  border: 2px solid currentColor;
  border-radius: 9999px;
  animation: pulseRing 1.2s ease-out infinite;
  pointer-events: none;
}

.pulsing-button {
  position: relative;
  z-index: 10;
  padding: 0.5rem 1.5rem;
  background-color: #4f46e5;
  color: white;
  border-radius: 9999px;
  font-weight: bold;
  border: none;
}
<div class="pulsing-button-wrapper">
  <span class="pulsing-ring"></span>
  <button class="pulsing-button">Click Me</button>
</div>

6. RGB Gradient Scrollbar Track

Only shows in browsers that support it. That being Chrome and Edge. Firefox and Safari don’t support it yet. :'(

Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating... Repeating...

.dark::-webkit-scrollbar {
  width: 8px;
}
.dark::-webkit-scrollbar-thumb {
  background: linear-gradient(#00eaff, #ff00ff);
  border-radius: 4px;
}

7. “Breathing” Neon Box-Shadow

A card whose glow inhales and exhales every few seconds. I'm sorry, but also not. It does really create that "lived in" feeling. It’s a great way to add some life to your site.

Hover to pause the breath; keyboard focus shows the same effect.

🫁 You are now aware of your breathing. 🫁

/* container you want to glow */
.breathing-card {
  background: #111;
  color: #fafafa;
  padding: 1.5rem;
  border-radius: 1rem;
  box-shadow: 0 0 8px 2px #00ffc855; /* starting glow */
  animation: breathe 6s ease-in-out infinite;
  transition: box-shadow 0.2s;
}

/* pause motion on user intent */
.breathing-card:hover,
.breathing-card:focus-visible {
  animation-play-state: paused;
}

@keyframes breathe {
  0%,
  100% {
    box-shadow: 0 0 8px 2px #00ffc855;
  }
  50% {
    box-shadow: 0 0 20px 8px #00ffc8aa;
  }
}

/* motion-sensitive users */
@media (prefers-reduced-motion: reduce) {
  .breathing-card {
    animation: none;
  }
}

8. Glitch-Jitter Shadow on Click

A micro-glitch that fires only when the user clicks (or presses Enter/Space). The element pops a few offset shadows for ~120 ms, then settles back.

<button class="glitch-jitter-btn">Click Me</button>
.glitch-jitter-btn {
  position: relative;
  padding: 0.75rem 2rem;
  background: #0f0;
  color: #000;
  border: none;
  border-radius: 9999px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 0 6px 2px #00ff00aa;
  transition: transform 0.1s;
}

/* keyframes = sideways jerk + triple glow */
@keyframes jitter {
  0% {
    transform: translate(0, 0);
    box-shadow: 0 0 6px 2px #00ff00aa;
  }
  25% {
    transform: translate(-1px, 1px);
    box-shadow: 2px -2px 4px #00ff00aa, -2px 2px 4px #00ff00aa;
  }
  50% {
    transform: translate(1px, -1px);
    box-shadow: -2px 2px 4px #00ff00aa, 2px -2px 4px #00ff00aa;
  }
  75% {
    transform: translate(-1px, 1px);
    box-shadow: 2px 2px 4px #00ff00aa, -2px -2px 4px #00ff00aa;
  }
  100% {
    transform: translate(0, 0);
    box-shadow: 0 0 6px 2px #00ff00aa;
  }
}

/* JS toggles the helper class */
.glitch-fire {
  animation: jitter 0.12s steps(1) forwards;
}

/* accessibility: give keyboard users parity */
.glitch-jitter-btn:focus-visible {
  outline: 3px solid #00ff00aa;
}
document.addEventListener('click', (e) => {
  const btn = e.target.closest('.glitch-jitter-btn')
  if (!btn) return
  btn.classList.remove('glitch-fire')
  void btn.offsetWidth // force reflow
  btn.classList.add('glitch-fire')
})

9. Link Underline Reveal

Links start bare, then on focus/hover a thin neon underline zooms in from center.

Take me home!

a.glow-link {
  position: relative;
  color: #0ff;
  text-decoration: none;
}
a.glow-link::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: 0;
  height: 2px;
  background: currentColor;
  transition: width 0.25s ease, left 0.25s ease;
}
a.glow-link:hover::after,
a.glow-link:focus-visible::after {
  width: 100%;
  left: 0;
}

10. One‑Shot Flicker Effect

Call it once every N minutes. Again, this is repeated for demo purposes, but you can set it to a longer interval. It’s a one‑shot animation that makes the text flicker. It’s a bit of a gimmick, but it’s fun.

The Glitched Goblet

@keyframes flicker {
  0%,
  100% {
    clip-path: inset(0 0 0 0);
  }
  10% {
    clip-path: inset(20% 0 60% 0);
  }
  20% {
    clip-path: inset(40% 0 20% 0);
  }
  30% {
    clip-path: inset(10% 0 70% 0);
  }
}
.logo-glitch {
  animation: flicker 0.6s steps(1) forwards;
}

Wrapping Up

I hope you enjoyed this little list of CSS flourishes. I had a lot of fun making them and I hope you have fun trying them out. If you have any questions or suggestions for future posts, feel free to reach out to me on LinkedIn, BlueSky or in the comments on dev.to.