DEV Community

Cover image for How to Build a Neon Orbit CSS Button Hover Effect
CodeRipple
CodeRipple

Posted on

How to Build a Neon Orbit CSS Button Hover Effect

CSS hover effects can make a simple button feel much more interactive without adding JavaScript.

For this component, I wanted to create a button with a neon light that appears to travel around the border when the user hovers over it. The final effect uses only HTML and CSS.

What We're Building

The button starts with a clean light appearance. On hover:

  • The button face becomes dark
  • A cyan, blue, purple, and magenta light rotates around the border
  • A soft neon glow appears around the button
  • The arrow moves slightly to the right
  • The button lifts a few pixels

I also added keyboard focus styles and reduced-motion support.

HTML

The structure is intentionally small:

<div class="cr-neon-orbit-demo">

  <button class="cr-neon-orbit-btn" type="button">

    <span
      class="cr-neon-orbit-btn__track"
      aria-hidden="true">

      <span class="cr-neon-orbit-btn__runner"></span>

    </span>

    <span
      class="cr-neon-orbit-btn__face"
      aria-hidden="true">
    </span>

    <span class="cr-neon-orbit-btn__content">

      <span class="cr-neon-orbit-btn__label">
        Get Started
      </span>

      <span
        class="cr-neon-orbit-btn__arrow"
        aria-hidden="true"></span>

    </span>

  </button>

</div>
Enter fullscreen mode Exit fullscreen mode

The track contains the animated light source, while the face creates the actual button surface.

Creating the Neon Orbit

The main trick is a conic-gradient() placed inside an element larger than the button.

.cr-neon-orbit-btn__runner {
  position: absolute;

  width: 320px;
  height: 320px;

  top: 50%;
  left: 50%;

  margin-top: -160px;
  margin-left: -160px;

  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    transparent 255deg,
    #22d3ee 280deg,
    #38bdf8 295deg,
    #8b5cf6 315deg,
    #d946ef 332deg,
    transparent 350deg,
    transparent 360deg
  );

  animation: cr-neon-orbit-spin 2.2s linear infinite;
}
Enter fullscreen mode Exit fullscreen mode

Most of the gradient is transparent. Only a small section contains the neon colors.

When the large gradient rotates behind the rounded button face, that colored section appears to travel around the edge.

Rotation Animation

The animation itself is very simple:

@keyframes cr-neon-orbit-spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}
Enter fullscreen mode Exit fullscreen mode

The visual complexity comes mostly from the gradient rather than from complicated animation logic.

Hover Interaction

On hover, the neon track becomes visible:

.cr-neon-orbit-btn:hover
.cr-neon-orbit-btn__track {
  opacity: 1;

  box-shadow:
    0 0 12px rgba(34, 211, 238, 0.35),
    0 0 22px rgba(139, 92, 246, 0.28),
    0 0 32px rgba(217, 70, 239, 0.18);
}
Enter fullscreen mode Exit fullscreen mode

The inner face also shrinks slightly and changes from light to dark:

.cr-neon-orbit-btn:hover
.cr-neon-orbit-btn__face {
  inset: 3px;
  background: #05070c;

  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.035),
    0 12px 30px rgba(0, 0, 0, 0.4);
}
Enter fullscreen mode Exit fullscreen mode

That small inset exposes the animated neon layer underneath.

Arrow Movement

A subtle movement gives the button another layer of feedback:

.cr-neon-orbit-btn:hover
.cr-neon-orbit-btn__arrow {
  transform: translateX(5px);
}
Enter fullscreen mode Exit fullscreen mode

It's a small detail, but it makes the interaction feel more responsive.

Keyboard Accessibility

Hover shouldn't be the only visible interaction state.

The button also includes a keyboard focus indicator:

.cr-neon-orbit-btn:focus-visible {
  outline: 3px solid #22d3ee;
  outline-offset: 7px;
}
Enter fullscreen mode Exit fullscreen mode

Reduced Motion

For users who prefer reduced motion, the rotation can be disabled:

@media (prefers-reduced-motion: reduce) {

  .cr-neon-orbit-btn,
  .cr-neon-orbit-btn__face,
  .cr-neon-orbit-btn__content,
  .cr-neon-orbit-btn__arrow {
    transition: none;
  }

  .cr-neon-orbit-btn__runner {
    animation: none;
  }

}
Enter fullscreen mode Exit fullscreen mode

Live Demo

I also published the component on CodePen so you can test the hover effect directly and experiment with the code:

View the live CodePen demo

Full Source & Tutorial

The complete component, including the full CSS and a live preview, is available on CodeRipple:

Neon Orbit CSS Button Hover Effect

The component uses HTML and CSS only, so no JavaScript is required.

If you customize it, try changing the conic-gradient() colors and animation duration. A few small changes can produce a completely different orbit effect.

Top comments (0)