20 CSS Neon Text Effects12 / 20
Multi-Colour Neon Text Effect
A single headline split into independently-glowing colours — a cyan word beside a pink word beside an amber word — the 'how do I make each word a different neon' answer, with each tube keeping its own matching bloom.
Published
The code
<div class="cnt-12">
<h2 class="cnt-12__line">
<span class="cnt-12__w" style="--c:oklch(0.85 0.15 200);--i:0">STAY</span>
<span class="cnt-12__w" style="--c:oklch(0.72 0.24 340);--i:1">WEIRD</span>
<span class="cnt-12__w" style="--c:oklch(0.85 0.18 90);--i:2">TONIGHT</span>
</h2>
</div><div class="cnt-12">
<h2 class="cnt-12__line">
<span class="cnt-12__w" style="--c:oklch(0.85 0.15 200);--i:0">STAY</span>
<span class="cnt-12__w" style="--c:oklch(0.72 0.24 340);--i:1">WEIRD</span>
<span class="cnt-12__w" style="--c:oklch(0.85 0.18 90);--i:2">TONIGHT</span>
</h2>
</div>.cnt-12,
.cnt-12 *,
.cnt-12 *::before,
.cnt-12 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cnt-12 ::selection {
background: oklch(0.72 0.24 340);
color: #fff;
}
.cnt-12 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 60px 20px;
background: radial-gradient(120% 120% at 50% 25%,#100b12,#050406);
}
.cnt-12__line {
display: flex;
flex-wrap: wrap;
gap: .28em;
justify-content: center;
font-size: clamp(44px,11vw,104px);
font-weight: 900;
line-height: 1;
letter-spacing: .03em;
}
.cnt-12__w {
color: var(--c);
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
animation: cnt-12-on 1.4s ease both;
animation-delay: calc(var(--i) * .28s);
}
@keyframes cnt-12-on {
0% {
opacity: .2;
text-shadow: 0 0 4px color-mix(in oklch,var(--c) 40%,transparent);
}
60% {
opacity: 1;
text-shadow: 0 0 6px #fff,0 0 18px var(--c),0 0 42px var(--c);
}
100% {
opacity: 1;
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
}
}
@media (prefers-reduced-motion: reduce) {
.cnt-12__w {
animation: none;
opacity: 1;
}
}.cnt-12,
.cnt-12 *,
.cnt-12 *::before,
.cnt-12 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cnt-12 ::selection {
background: oklch(0.72 0.24 340);
color: #fff;
}
.cnt-12 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 60px 20px;
background: radial-gradient(120% 120% at 50% 25%,#100b12,#050406);
}
.cnt-12__line {
display: flex;
flex-wrap: wrap;
gap: .28em;
justify-content: center;
font-size: clamp(44px,11vw,104px);
font-weight: 900;
line-height: 1;
letter-spacing: .03em;
}
.cnt-12__w {
color: var(--c);
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
animation: cnt-12-on 1.4s ease both;
animation-delay: calc(var(--i) * .28s);
}
@keyframes cnt-12-on {
0% {
opacity: .2;
text-shadow: 0 0 4px color-mix(in oklch,var(--c) 40%,transparent);
}
60% {
opacity: 1;
text-shadow: 0 0 6px #fff,0 0 18px var(--c),0 0 42px var(--c);
}
100% {
opacity: 1;
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
}
}
@media (prefers-reduced-motion: reduce) {
.cnt-12__w {
animation: none;
opacity: 1;
}
}/* No JavaScript — one shared rule reads each word's --c to build its matching glow. */
/* No JavaScript — one shared rule reads each word's --c to build its matching glow. */Here's a working CSS Neon Text Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Multi-Colour Neon Text Effect
Source: https://codefronts.com/motion/css-neon-text-effect/multi-colour-neon-text-effect/
A single headline split into independently-glowing colours — a cyan word beside a pink word beside an amber word — the 'how do I make each word a different neon' answer, with each tube keeping its own matching bloom.
## HTML
```html
<div class="cnt-12">
<h2 class="cnt-12__line">
<span class="cnt-12__w" style="--c:oklch(0.85 0.15 200);--i:0">STAY</span>
<span class="cnt-12__w" style="--c:oklch(0.72 0.24 340);--i:1">WEIRD</span>
<span class="cnt-12__w" style="--c:oklch(0.85 0.18 90);--i:2">TONIGHT</span>
</h2>
</div>
```
## CSS
```css
.cnt-12,
.cnt-12 *,
.cnt-12 *::before,
.cnt-12 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cnt-12 ::selection {
background: oklch(0.72 0.24 340);
color: #fff;
}
.cnt-12 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 60px 20px;
background: radial-gradient(120% 120% at 50% 25%,#100b12,#050406);
}
.cnt-12__line {
display: flex;
flex-wrap: wrap;
gap: .28em;
justify-content: center;
font-size: clamp(44px,11vw,104px);
font-weight: 900;
line-height: 1;
letter-spacing: .03em;
}
.cnt-12__w {
color: var(--c);
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
animation: cnt-12-on 1.4s ease both;
animation-delay: calc(var(--i) * .28s);
}
@keyframes cnt-12-on {
0% {
opacity: .2;
text-shadow: 0 0 4px color-mix(in oklch,var(--c) 40%,transparent);
}
60% {
opacity: 1;
text-shadow: 0 0 6px #fff,0 0 18px var(--c),0 0 42px var(--c);
}
100% {
opacity: 1;
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
}
}
@media (prefers-reduced-motion: reduce) {
.cnt-12__w {
animation: none;
opacity: 1;
}
}
```
## JavaScript
```js
/* No JavaScript — one shared rule reads each word's --c to build its matching glow. */
```Here's a working CSS Neon Text Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Multi-Colour Neon Text Effect
Source: https://codefronts.com/motion/css-neon-text-effect/multi-colour-neon-text-effect/
A single headline split into independently-glowing colours — a cyan word beside a pink word beside an amber word — the 'how do I make each word a different neon' answer, with each tube keeping its own matching bloom.
## HTML
```html
<div class="cnt-12">
<h2 class="cnt-12__line">
<span class="cnt-12__w" style="--c:oklch(0.85 0.15 200);--i:0">STAY</span>
<span class="cnt-12__w" style="--c:oklch(0.72 0.24 340);--i:1">WEIRD</span>
<span class="cnt-12__w" style="--c:oklch(0.85 0.18 90);--i:2">TONIGHT</span>
</h2>
</div>
```
## CSS
```css
.cnt-12,
.cnt-12 *,
.cnt-12 *::before,
.cnt-12 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cnt-12 ::selection {
background: oklch(0.72 0.24 340);
color: #fff;
}
.cnt-12 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 60px 20px;
background: radial-gradient(120% 120% at 50% 25%,#100b12,#050406);
}
.cnt-12__line {
display: flex;
flex-wrap: wrap;
gap: .28em;
justify-content: center;
font-size: clamp(44px,11vw,104px);
font-weight: 900;
line-height: 1;
letter-spacing: .03em;
}
.cnt-12__w {
color: var(--c);
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
animation: cnt-12-on 1.4s ease both;
animation-delay: calc(var(--i) * .28s);
}
@keyframes cnt-12-on {
0% {
opacity: .2;
text-shadow: 0 0 4px color-mix(in oklch,var(--c) 40%,transparent);
}
60% {
opacity: 1;
text-shadow: 0 0 6px #fff,0 0 18px var(--c),0 0 42px var(--c);
}
100% {
opacity: 1;
text-shadow: 0 0 5px #fff,0 0 14px var(--c),0 0 32px var(--c),0 0 66px color-mix(in oklch,var(--c) 60%,transparent);
}
}
@media (prefers-reduced-motion: reduce) {
.cnt-12__w {
animation: none;
opacity: 1;
}
}
```
## JavaScript
```js
/* No JavaScript — one shared rule reads each word's --c to build its matching glow. */
```How this works
Each word is a <span> carrying its own --c custom property; a single shared rule reads --c to build that word's color and its four-layer text-shadow, so every word glows in its own hue with a bloom that matches — no repeated shadow declarations per colour.
Because the glow is derived from the per-span variable, adding a fourth colour is just another span with a new --c. A slow per-word animation-delay on a gentle brighten makes the colours ripple on in sequence.
Make it yours
- Set each word's hue inline via
style="--c:oklch(...)"— no new CSS per colour. - Keep hues at a common lightness/chroma (as here) so no single word blows out the others.
- Add or remove words freely; the shared rule scales to any count.
- Swap the sequential ripple for an all-at-once glow by removing the per-span delay.
Gotchas — read before shipping
- Too many saturated hues at once turns to mud — 2–4 colours reads as intentional, 7 reads as a ransom note.
- Keep the words real text in one heading for SEO and screen readers; don't split into images.
- Mixed-hue glows overlapping at the word gaps can muddy — add a little letter-spacing so blooms don't collide.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.2+ | 113+ | 111+ |
Floor set by oklch(), color-mix() as this demo is written. The core technique itself goes back further — Chrome 88+.
Per-element custom properties in text-shadow — universal; color-mix() for the derived layers needs Chrome 111+/Safari 16.2+.