20 / 33
All 33 in 33 CSS Card Hover Effects
- 013D Tilt & Parallax Card Effects
- 02Glowing Gradient & Glassmorphic Borders
- 03Image Zoom with Content Reveal / Slide-Up
- 043D Flip Cards (Front to Back)
- 05Parent Blur / Sibling De-emphasis (Focus States)
- 06Minimalist Elevation & Dynamic Shadows
- 07Elastic Lift
- 08Gradient Border Draw
- 09Stacked Reveal
- 10Holographic Shimmer
- 11Curtain Reveal
- 12Corner Peel
- 13Neon Sign
- 14Scanline
- 15Depth Parallax
- 16Spotlight
- 173D Tilt
- 18Slide Up Content
- 19Flip Card
- 20Glitch Card
- 21Gradient Rotate
- 22Border Morph
- 23Magnetic Float
- 24Typewriter Reveal
- 25Overlay Slide
- 26Grain Texture
- 27Frosted Glass Intensify
- 28Blueprint Reveal
- 29Shockwave
- 30Color Burn
- 31Prismatic Sweep
- 32Book Open
- 33Aurora
Glitch Card
An event/music card with RGB channel-split text, datamosh slice bars, and stepped jitter animation on hover. Built for cyberpunk, electronic music, gaming, and edgy brands that want controlled digital chaos.
Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS
ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link
The code
<div class="card-20">
<article class="card-20__card">
<div class="card-20__bars"></div>
<div class="card-20__inner">
<span class="card-20__tag">// SIGNAL_LOST</span>
<h2 class="card-20__title">
<span class="card-20__ghost card-20__ghost-r" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__ghost card-20__ghost-c" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__real">NULL<br>CITY</span>
</h2>
<p class="card-20__desc">A cyberpunk audio-visual set. Corrupted frames, datamoshed visuals, bass you feel in your teeth.</p>
<span class="card-20__foot">FRI · WAREHOUSE 7 · 23:00</span>
</div>
</article>
</div><div class="card-20">
<article class="card-20__card">
<div class="card-20__bars"></div>
<div class="card-20__inner">
<span class="card-20__tag">// SIGNAL_LOST</span>
<h2 class="card-20__title">
<span class="card-20__ghost card-20__ghost-r" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__ghost card-20__ghost-c" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__real">NULL<br>CITY</span>
</h2>
<p class="card-20__desc">A cyberpunk audio-visual set. Corrupted frames, datamoshed visuals, bass you feel in your teeth.</p>
<span class="card-20__foot">FRI · WAREHOUSE 7 · 23:00</span>
</div>
</article>
</div>@import url('https://fonts.googleapis.com/css2?family=Anton&family=Space+Mono:wght@400;700&display=swap');
.card-20,
.card-20 *,
.card-20 *::before,
.card-20 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-20 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #08080a;
font-family: 'Space Mono', monospace;
padding: 2rem;
}
.card-20__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 4px;
background: #0f0f12;
cursor: pointer;
overflow: hidden;
border: 1px solid #1c1c22;
}
.card-20__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e8e8ee;
}
.card-20__tag {
font-size: 0.72rem;
letter-spacing: 0.25em;
color: #00e0ff;
}
.card-20__title {
font-family: 'Anton', sans-serif;
font-size: 4rem;
line-height: 0.85;
text-transform: uppercase;
position: relative;
color: #fff;
display: inline-block;
}
.card-20__ghost {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease;
}
.card-20__ghost.card-20__ghost-r {
color: #ff003c;
}
.card-20__ghost.card-20__ghost-c {
color: #00e0ff;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-r {
opacity: 0.85;
animation: card-20-shift-a 0.35s steps(2) infinite;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-c {
opacity: 0.85;
animation: card-20-shift-b 0.35s steps(2) infinite;
}
@keyframes card-20-shift-a {
0% {
transform: translate(0,0);
clip-path: inset(0 0 70% 0);
}
50% {
transform: translate(-4px,2px);
clip-path: inset(40% 0 20% 0);
}
100% {
transform: translate(3px,-2px);
clip-path: inset(70% 0 0 0);
}
}
@keyframes card-20-shift-b {
0% {
transform: translate(0,0);
clip-path: inset(60% 0 10% 0);
}
50% {
transform: translate(4px,-2px);
clip-path: inset(10% 0 60% 0);
}
100% {
transform: translate(-3px,2px);
clip-path: inset(30% 0 40% 0);
}
}
.card-20__real {
position: relative;
z-index: 1;
display: block;
}
.card-20__desc {
font-size: 0.82rem;
line-height: 1.6;
color: #888;
}
.card-20__foot {
font-size: 0.72rem;
letter-spacing: 0.15em;
color: #555;
}
.card-20__bars {
position: absolute;
inset: 0;
z-index: 3;
pointer-events: none;
opacity: 0;
}
.card-20__card:hover .card-20__bars {
opacity: 1;
animation: card-20-bars 0.4s steps(3) infinite;
}
.card-20__bars::before,
.card-20__bars::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 2px;
background: rgba(0,224,255,0.5);
}
.card-20__bars::before {
top: 32%;
}
.card-20__bars::after {
top: 68%;
background: rgba(255,0,60,0.5);
}
@keyframes card-20-bars {
0%,
100% {
transform: translateX(0);
}
50% {
transform: translateX(6px);
}
}
@media (prefers-reduced-motion: reduce) {
.card-20__ghost,
.card-20__bars {
animation: none !important;
}
}@import url('https://fonts.googleapis.com/css2?family=Anton&family=Space+Mono:wght@400;700&display=swap');
.card-20,
.card-20 *,
.card-20 *::before,
.card-20 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-20 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #08080a;
font-family: 'Space Mono', monospace;
padding: 2rem;
}
.card-20__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 4px;
background: #0f0f12;
cursor: pointer;
overflow: hidden;
border: 1px solid #1c1c22;
}
.card-20__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e8e8ee;
}
.card-20__tag {
font-size: 0.72rem;
letter-spacing: 0.25em;
color: #00e0ff;
}
.card-20__title {
font-family: 'Anton', sans-serif;
font-size: 4rem;
line-height: 0.85;
text-transform: uppercase;
position: relative;
color: #fff;
display: inline-block;
}
.card-20__ghost {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease;
}
.card-20__ghost.card-20__ghost-r {
color: #ff003c;
}
.card-20__ghost.card-20__ghost-c {
color: #00e0ff;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-r {
opacity: 0.85;
animation: card-20-shift-a 0.35s steps(2) infinite;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-c {
opacity: 0.85;
animation: card-20-shift-b 0.35s steps(2) infinite;
}
@keyframes card-20-shift-a {
0% {
transform: translate(0,0);
clip-path: inset(0 0 70% 0);
}
50% {
transform: translate(-4px,2px);
clip-path: inset(40% 0 20% 0);
}
100% {
transform: translate(3px,-2px);
clip-path: inset(70% 0 0 0);
}
}
@keyframes card-20-shift-b {
0% {
transform: translate(0,0);
clip-path: inset(60% 0 10% 0);
}
50% {
transform: translate(4px,-2px);
clip-path: inset(10% 0 60% 0);
}
100% {
transform: translate(-3px,2px);
clip-path: inset(30% 0 40% 0);
}
}
.card-20__real {
position: relative;
z-index: 1;
display: block;
}
.card-20__desc {
font-size: 0.82rem;
line-height: 1.6;
color: #888;
}
.card-20__foot {
font-size: 0.72rem;
letter-spacing: 0.15em;
color: #555;
}
.card-20__bars {
position: absolute;
inset: 0;
z-index: 3;
pointer-events: none;
opacity: 0;
}
.card-20__card:hover .card-20__bars {
opacity: 1;
animation: card-20-bars 0.4s steps(3) infinite;
}
.card-20__bars::before,
.card-20__bars::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 2px;
background: rgba(0,224,255,0.5);
}
.card-20__bars::before {
top: 32%;
}
.card-20__bars::after {
top: 68%;
background: rgba(255,0,60,0.5);
}
@keyframes card-20-bars {
0%,
100% {
transform: translateX(0);
}
50% {
transform: translateX(6px);
}
}
@media (prefers-reduced-motion: reduce) {
.card-20__ghost,
.card-20__bars {
animation: none !important;
}
}Here's a working CSS Card Hover 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: Glitch Card
Source: https://codefronts.com/motion/css-card-hover-effects/glitch-card/
An event/music card with RGB channel-split text, datamosh slice bars, and stepped jitter animation on hover. Built for cyberpunk, electronic music, gaming, and edgy brands that want controlled digital chaos.
## HTML
```html
<div class="card-20">
<article class="card-20__card">
<div class="card-20__bars"></div>
<div class="card-20__inner">
<span class="card-20__tag">// SIGNAL_LOST</span>
<h2 class="card-20__title">
<span class="card-20__ghost card-20__ghost-r" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__ghost card-20__ghost-c" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__real">NULL<br>CITY</span>
</h2>
<p class="card-20__desc">A cyberpunk audio-visual set. Corrupted frames, datamoshed visuals, bass you feel in your teeth.</p>
<span class="card-20__foot">FRI · WAREHOUSE 7 · 23:00</span>
</div>
</article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Anton&family=Space+Mono:wght@400;700&display=swap');
.card-20,
.card-20 *,
.card-20 *::before,
.card-20 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-20 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #08080a;
font-family: 'Space Mono', monospace;
padding: 2rem;
}
.card-20__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 4px;
background: #0f0f12;
cursor: pointer;
overflow: hidden;
border: 1px solid #1c1c22;
}
.card-20__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e8e8ee;
}
.card-20__tag {
font-size: 0.72rem;
letter-spacing: 0.25em;
color: #00e0ff;
}
.card-20__title {
font-family: 'Anton', sans-serif;
font-size: 4rem;
line-height: 0.85;
text-transform: uppercase;
position: relative;
color: #fff;
display: inline-block;
}
.card-20__ghost {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease;
}
.card-20__ghost.card-20__ghost-r {
color: #ff003c;
}
.card-20__ghost.card-20__ghost-c {
color: #00e0ff;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-r {
opacity: 0.85;
animation: card-20-shift-a 0.35s steps(2) infinite;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-c {
opacity: 0.85;
animation: card-20-shift-b 0.35s steps(2) infinite;
}
@keyframes card-20-shift-a {
0% {
transform: translate(0,0);
clip-path: inset(0 0 70% 0);
}
50% {
transform: translate(-4px,2px);
clip-path: inset(40% 0 20% 0);
}
100% {
transform: translate(3px,-2px);
clip-path: inset(70% 0 0 0);
}
}
@keyframes card-20-shift-b {
0% {
transform: translate(0,0);
clip-path: inset(60% 0 10% 0);
}
50% {
transform: translate(4px,-2px);
clip-path: inset(10% 0 60% 0);
}
100% {
transform: translate(-3px,2px);
clip-path: inset(30% 0 40% 0);
}
}
.card-20__real {
position: relative;
z-index: 1;
display: block;
}
.card-20__desc {
font-size: 0.82rem;
line-height: 1.6;
color: #888;
}
.card-20__foot {
font-size: 0.72rem;
letter-spacing: 0.15em;
color: #555;
}
.card-20__bars {
position: absolute;
inset: 0;
z-index: 3;
pointer-events: none;
opacity: 0;
}
.card-20__card:hover .card-20__bars {
opacity: 1;
animation: card-20-bars 0.4s steps(3) infinite;
}
.card-20__bars::before,
.card-20__bars::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 2px;
background: rgba(0,224,255,0.5);
}
.card-20__bars::before {
top: 32%;
}
.card-20__bars::after {
top: 68%;
background: rgba(255,0,60,0.5);
}
@keyframes card-20-bars {
0%,
100% {
transform: translateX(0);
}
50% {
transform: translateX(6px);
}
}
@media (prefers-reduced-motion: reduce) {
.card-20__ghost,
.card-20__bars {
animation: none !important;
}
}
```Here's a working CSS Card Hover 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: Glitch Card
Source: https://codefronts.com/motion/css-card-hover-effects/glitch-card/
An event/music card with RGB channel-split text, datamosh slice bars, and stepped jitter animation on hover. Built for cyberpunk, electronic music, gaming, and edgy brands that want controlled digital chaos.
## HTML
```html
<div class="card-20">
<article class="card-20__card">
<div class="card-20__bars"></div>
<div class="card-20__inner">
<span class="card-20__tag">// SIGNAL_LOST</span>
<h2 class="card-20__title">
<span class="card-20__ghost card-20__ghost-r" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__ghost card-20__ghost-c" aria-hidden="true">NULL<br>CITY</span>
<span class="card-20__real">NULL<br>CITY</span>
</h2>
<p class="card-20__desc">A cyberpunk audio-visual set. Corrupted frames, datamoshed visuals, bass you feel in your teeth.</p>
<span class="card-20__foot">FRI · WAREHOUSE 7 · 23:00</span>
</div>
</article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Anton&family=Space+Mono:wght@400;700&display=swap');
.card-20,
.card-20 *,
.card-20 *::before,
.card-20 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card-20 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: #08080a;
font-family: 'Space Mono', monospace;
padding: 2rem;
}
.card-20__card {
position: relative;
width: 340px;
height: 440px;
border-radius: 4px;
background: #0f0f12;
cursor: pointer;
overflow: hidden;
border: 1px solid #1c1c22;
}
.card-20__inner {
position: relative;
z-index: 2;
height: 100%;
padding: 2.4rem;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #e8e8ee;
}
.card-20__tag {
font-size: 0.72rem;
letter-spacing: 0.25em;
color: #00e0ff;
}
.card-20__title {
font-family: 'Anton', sans-serif;
font-size: 4rem;
line-height: 0.85;
text-transform: uppercase;
position: relative;
color: #fff;
display: inline-block;
}
.card-20__ghost {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease;
}
.card-20__ghost.card-20__ghost-r {
color: #ff003c;
}
.card-20__ghost.card-20__ghost-c {
color: #00e0ff;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-r {
opacity: 0.85;
animation: card-20-shift-a 0.35s steps(2) infinite;
}
.card-20__card:hover .card-20__ghost.card-20__ghost-c {
opacity: 0.85;
animation: card-20-shift-b 0.35s steps(2) infinite;
}
@keyframes card-20-shift-a {
0% {
transform: translate(0,0);
clip-path: inset(0 0 70% 0);
}
50% {
transform: translate(-4px,2px);
clip-path: inset(40% 0 20% 0);
}
100% {
transform: translate(3px,-2px);
clip-path: inset(70% 0 0 0);
}
}
@keyframes card-20-shift-b {
0% {
transform: translate(0,0);
clip-path: inset(60% 0 10% 0);
}
50% {
transform: translate(4px,-2px);
clip-path: inset(10% 0 60% 0);
}
100% {
transform: translate(-3px,2px);
clip-path: inset(30% 0 40% 0);
}
}
.card-20__real {
position: relative;
z-index: 1;
display: block;
}
.card-20__desc {
font-size: 0.82rem;
line-height: 1.6;
color: #888;
}
.card-20__foot {
font-size: 0.72rem;
letter-spacing: 0.15em;
color: #555;
}
.card-20__bars {
position: absolute;
inset: 0;
z-index: 3;
pointer-events: none;
opacity: 0;
}
.card-20__card:hover .card-20__bars {
opacity: 1;
animation: card-20-bars 0.4s steps(3) infinite;
}
.card-20__bars::before,
.card-20__bars::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 2px;
background: rgba(0,224,255,0.5);
}
.card-20__bars::before {
top: 32%;
}
.card-20__bars::after {
top: 68%;
background: rgba(255,0,60,0.5);
}
@keyframes card-20-bars {
0%,
100% {
transform: translateX(0);
}
50% {
transform: translateX(6px);
}
}
@media (prefers-reduced-motion: reduce) {
.card-20__ghost,
.card-20__bars {
animation: none !important;
}
}
```How this works
The card renders text with three layered copies at slightly offset positions — one shifted red channel, one shifted cyan channel, one clean white. At rest the offsets are zero; on :hover, the offsets shift outward and the layers desync briefly, producing the classic RGB-channel-split glitch.
A short keyframes animation adds intermittent horizontal jitter — 3-4 keyframes at random horizontal offsets — that runs only on hover. The randomness reads as digital noise, not a smooth motion.
The layering uses mix-blend-mode: screen so the three channels combine additively; where they overlap, they render white. Where they diverge, the channel tints leak through.
Make it yours
- Tune split intensity via keyframe offset values — 2px offsets read as subtle glitch, 8px reads as heavy corruption.
- Change channel colours from red/cyan default to any complementary pair — magenta/green, orange/blue.
- Slow keyframe timing for a rhythmic pulse or speed it up for chaotic bursts.
- Add a matching background flicker (a subtle
filter: brightness()oscillation) for full digital-corruption authenticity. - Constrain the glitch to just the title element by scoping the keyframes to
.card-20__titleinstead of the whole face.
Gotchas — read before shipping
- Random-offset keyframes must be wrapped in
@media (prefers-reduced-motion: reduce) { animation: none }— glitch effects are photosensitive-user triggers. mix-blend-mode: screenneeds the parent to have an explicit background; transparent parents show the raw layered text without the additive blend.- Test contrast — the split channels can drop the effective text contrast below WCAG 4.5:1; ensure the base white text remains readable.
- Cap the split duration to under 3 seconds — sustained glitch is fatiguing.
- Screen reader users should hear the clean text, not the layered copies — use one visible text element with aria-visible content, and hide the two channel copies with
aria-hidden="true".
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 45+ | 9+ | 16+ | 45+ |
CSS keyframes, transforms, and mix-blend-mode are universally supported. Blend behaviour is identical across Chromium, WebKit and Gecko.