Neon Orbit CSS Button Hover Effect
A modern interactive button with a rotating neon orbit border, dark hover transformation and smooth arrow movement.
<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>
/* =========================================
CODERIPPLE NEON ORBIT BUTTON
========================================= */
.cr-neon-orbit-demo {
min-height: 320px;
display: flex;
align-items: center;
justify-content: center;
padding: 40px 20px;
background:
radial-gradient(
circle at 50% 50%,
rgba(91, 33, 182, 0.08),
transparent 38%
),
#080b14;
overflow: hidden;
}
/* =========================================
BUTTON
========================================= */
.cr-neon-orbit-btn {
position: relative;
width: 230px;
height: 64px;
padding: 0;
border: 0;
border-radius: 999px;
background: transparent;
font-family: inherit;
cursor: pointer;
isolation: isolate;
transition: transform 0.3s ease;
}
/* =========================================
NEON TRACK
========================================= */
.cr-neon-orbit-btn__track {
position: absolute;
inset: -3px;
border-radius: 999px;
overflow: hidden;
opacity: 0;
background: #151822;
box-shadow:
0 0 0 rgba(34, 211, 238, 0),
0 0 0 rgba(168, 85, 247, 0);
transition:
opacity 0.3s ease,
box-shadow 0.3s ease;
pointer-events: none;
}
/* =========================================
ROTATING LIGHT SOURCE
========================================= */
.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;
pointer-events: none;
}
/* =========================================
BUTTON FACE
========================================= */
.cr-neon-orbit-btn__face {
position: absolute;
inset: 0;
z-index: 2;
border-radius: 999px;
background: #f5f2ea;
box-shadow:
0 10px 28px rgba(0, 0, 0, 0.28),
inset 0 1px 0 rgba(255, 255, 255, 0.95);
transition:
inset 0.3s ease,
background 0.3s ease,
box-shadow 0.3s ease;
}
/* =========================================
CONTENT
========================================= */
.cr-neon-orbit-btn__content {
position: relative;
z-index: 3;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 14px;
color: #090a0d;
font-size: 17px;
font-weight: 700;
line-height: 1;
transition: color 0.3s ease;
pointer-events: none;
}
.cr-neon-orbit-btn__label {
white-space: nowrap;
}
.cr-neon-orbit-btn__arrow {
display: inline-block;
font-size: 23px;
line-height: 1;
transition: transform 0.3s ease;
}
/* =========================================
HOVER STATE
========================================= */
.cr-neon-orbit-btn:hover {
transform: translateY(-2px);
}
.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);
}
.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);
}
.cr-neon-orbit-btn:hover
.cr-neon-orbit-btn__content {
color: #ffffff;
}
.cr-neon-orbit-btn:hover
.cr-neon-orbit-btn__arrow {
transform: translateX(5px);
}
/* =========================================
ROTATION
========================================= */
@keyframes cr-neon-orbit-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* =========================================
ACTIVE
========================================= */
.cr-neon-orbit-btn:active {
transform:
translateY(0)
scale(0.98);
}
/* =========================================
KEYBOARD FOCUS
========================================= */
.cr-neon-orbit-btn:focus-visible {
outline: 3px solid #22d3ee;
outline-offset: 7px;
}
/* =========================================
REDUCED MOTION
========================================= */
@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;
}
}
// No JavaScript required.
// The Neon Orbit Hover Button animation
// is powered entirely by CSS.
How This Neon Orbit CSS Button Hover Effect Works
The Neon Orbit CSS Button Hover Effect creates its animation entirely with HTML and CSS. The button uses several nested <span> elements to separate the animated border, button face, text, and arrow into independent visual layers. Although the component includes a JavaScript field, it contains only comments confirming that no JavaScript is required.
The main .cr-neon-orbit-btn element is a 230px by 64px pill-shaped button with a 999px border radius. It starts with a transparent background and uses position: relative so the decorative layers can be positioned inside it. A transform 0.3s ease transition controls the small movement applied during hover and active states.
The neon effect comes from .cr-neon-orbit-btn__track. This layer sits 3px outside the button using inset: -3px, but it starts with opacity: 0. Inside the track is a 320px square runner containing a conic-gradient(). Most of this gradient is transparent, while a relatively small section moves through cyan, blue, violet, and magenta colors. Because the runner is much larger than the button and the track uses overflow: hidden, only the relevant portion of the rotating gradient appears around the pill-shaped edge.
The cr-neon-orbit-spin keyframe animation continuously rotates this runner from 0deg to 360deg over 2.2 seconds with a linear timing function. This rotation creates the impression of a colored light traveling around the button rather than a static multicolor border. For more information about this technique, see the MDN conic-gradient documentation.
Above the track sits .cr-neon-orbit-btn__face. Its normal background is #f5f2ea, giving the button a light surface with a subtle inset highlight and dark drop shadow. When the user hovers over the button, the face changes to #05070c and its inset changes from 0 to 3px. That small reduction exposes the animated neon track underneath.
Hovering also changes the track opacity to 1 and adds three colored shadows based on cyan, violet, and magenta tones. At the same time, the entire button moves upward by 2px, the content becomes white, and the arrow moves 5px to the right. All of these transitions use a short 0.3-second duration, keeping the interaction coordinated.
The active state returns the vertical translation to zero and scales the button to 0.98, providing a small pressed response. Keyboard users get a 3px cyan :focus-visible outline with a 7px offset. The component also respects prefers-reduced-motion: transitions are disabled and the rotating runner stops when reduced motion is requested by the user’s system.
Customizing the Neon Orbit CSS Button Hover Effect
The component keeps its main visual settings in CSS, so its dimensions, colors, movement, and animation speed can be adjusted without changing the underlying structure.
- Change the button
width: 230pxandheight: 64pxto create a different button size. - Adjust the
#f5f2eaface color and#05070chover color to match your interface. - Modify the cyan, blue, violet, and magenta stops inside
conic-gradient()to create a different orbit palette. - Change the
2.2sanimation duration to make the neon light rotate faster or slower. - Adjust
translateY(-2px)to control how far the button rises on hover. - Change the arrow’s
translateX(5px)value to increase or reduce its horizontal movement. - Modify the three hover
box-shadowvalues to control the intensity and spread of the neon glow. - Replace the
Get Startedlabel and arrow character while retaining the existing layered button structure.
Where to Use This Neon Orbit CSS Button Hover Effect
This effect works particularly well when an interface needs a prominent action button that remains relatively simple at rest but gains a clear animated state when the user interacts with it.
- Hero-section call-to-action buttons on dark landing pages.
- Get started or signup actions for web applications.
- Product and service landing-page CTAs.
- Portfolio links that need a distinct interactive treatment.
- Feature-section buttons where a neon accent matches the visual theme.
- Promotional pages with dark, futuristic, or technology-focused layouts.
- Interfaces where a CSS-only hover animation is preferable to JavaScript-driven interaction.
For another button interaction that responds visually to pointer movement, the Magnetic Hover Button is a related CodeRipple component worth considering. The Neon Orbit button itself remains especially straightforward because the orbit, hover transition, active response, focus state, and reduced-motion handling are all implemented in CSS.
Frequently Asked Questions
Does the Neon Orbit CSS Button Hover Effect require JavaScript?
No. The published component uses HTML and CSS for the actual effect. The JavaScript section contains only comments stating that JavaScript is not required. Rotation is handled by the cr-neon-orbit-spin CSS keyframes.
How does the neon light move around the button?
A 320px by 320px element containing a conic-gradient() is centered inside the neon track. CSS rotates that element continuously through 360 degrees, while the track’s overflow: hidden and pill shape restrict what is visible around the button.
Why is the neon border hidden before hovering?
The track starts with opacity: 0. On :hover, its opacity changes to 1 and colored shadows are added. The button face also moves inward by 3px, exposing the rotating gradient around its edge.
Does the button support reduced-motion preferences?
Yes. A prefers-reduced-motion: reduce media query removes transitions from the relevant button elements and disables the runner’s animation. The component also provides a dedicated :focus-visible outline for keyboard navigation.
The Neon Orbit CSS Button Hover Effect combines a rotating conic gradient, layered button face, neon shadows, and small hover movements to produce an animated border without requiring JavaScript.
