A button with two corners cut off that tears into shifted cyan and magenta bands on hover, sticking out past its own edges between bursts. Two sliced copies of the face on stepped timing.
Also known as: glitch button css, cyberpunk button, clipped corner button.
<button class="btn-cyberpunk-glitch" data-text="Jack in">Jack in</button>
.btn-cyberpunk-glitch {
--c: var(--btn-color, #3b82f6);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5em;
font: 600 var(--btn-size, 18px)/1.2 system-ui, sans-serif;
cursor: pointer;
--notch: 0.5em;
position: relative;
padding: 0.85em 2.2em;
border: 0;
border-radius: 0;
background:
linear-gradient(135deg, transparent var(--notch), var(--c) 0) left / 51% 100% no-repeat,
linear-gradient(-45deg, transparent var(--notch), var(--c) 0) right / 51% 100% no-repeat;
color: #fff;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.14em;}
.btn-cyberpunk-glitch::before,
.btn-cyberpunk-glitch::after {
--tint: color-mix(in srgb, var(--c) 45%, #22d3ee);
content: attr(data-text);
content: attr(data-text) / "";
position: absolute;
inset: 0;
display: grid;
place-items: center;
background:
linear-gradient(135deg, transparent var(--notch), var(--tint) 0) left / 51% 100% no-repeat,
linear-gradient(-45deg, transparent var(--notch), var(--tint) 0) right / 51% 100% no-repeat;
clip-path: inset(50% 0 50% 0);
pointer-events: none;
}
.btn-cyberpunk-glitch::before { --tint: color-mix(in srgb, var(--c) 40%, #e879f9); }
.btn-cyberpunk-glitch:is(:hover, :focus-visible)::before {
animation: btn-cyberpunk-glitch-tear-a 1.2s steps(1, end) infinite;
}
.btn-cyberpunk-glitch:is(:hover, :focus-visible)::after {
animation: btn-cyberpunk-glitch-tear-b 0.9s steps(1, end) infinite;
}
@keyframes btn-cyberpunk-glitch-tear-a {
0% { clip-path: inset(10% 0 62% 0); transform: translateX(-0.5em); }
10% { clip-path: inset(58% 0 22% 0); transform: translateX(0.4em); }
20%, 55% { clip-path: inset(50% 0 50% 0); transform: none; }
65% { clip-path: inset(30% 0 48% 0); transform: translateX(0.6em); }
75%, 100% { clip-path: inset(50% 0 50% 0); transform: none; }
}
@keyframes btn-cyberpunk-glitch-tear-b {
0% { clip-path: inset(70% 0 8% 0); transform: translateX(0.45em); }
12% { clip-path: inset(22% 0 60% 0); transform: translateX(-0.35em); }
24% { clip-path: inset(44% 0 36% 0); transform: translateX(0.25em); }
36%, 100% { clip-path: inset(50% 0 50% 0); transform: none; }
}
@media (prefers-reduced-motion: reduce) {
.btn-cyberpunk-glitch, .btn-cyberpunk-glitch *, .btn-cyberpunk-glitch::before, .btn-cyberpunk-glitch::after, .btn-cyberpunk-glitch *::before, .btn-cyberpunk-glitch *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--btn-color on the element or a parent.
Currently previewing #3b82f6.--btn-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 18px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.