CSS-lab · Knoppen
Glitch-knop
Een rauwe knop waarvan het label bij hover openscheurt in cyaan en magenta lagen, met clip-path keyframes en zonder JavaScript.
- Gevorderd
- Pure CSS
- MIT-licentie
::before/::afterattr()clip-path: inset()@keyframessteps()
<button type="button" class="gk-btn">
<span class="gk-label" data-text="Hack de status quo">Hack de status quo</span>
</button>/* Glitch-knop - prefix .gk- */
.gk-btn {
--ink: #0C0C0D;
--paper: #F9F8F6;
--c1: #00E5FF;
--c2: #FF2BD6;
--accent: #C6FF3D;
--speed: 0.8s;
padding: 20px 36px;
font: 900 1.1rem/1 "Arial Black", "Helvetica Neue", Impact, system-ui, sans-serif;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--paper);
background: var(--ink);
border: 2px solid var(--paper);
cursor: pointer;
transition: box-shadow 0.2s;
}
.gk-label {
position: relative;
display: inline-block;
}
/* Twee kopie-lagen uit data-text, leeg voor schermlezers */
.gk-label::before,
.gk-label::after {
content: attr(data-text);
content: attr(data-text) / "";
position: absolute;
inset: 0;
mix-blend-mode: screen;
pointer-events: none;
opacity: 0;
animation: gk-idle 4s steps(1) infinite;
}
.gk-label::before {
color: var(--c1);
}
.gk-label::after {
color: var(--c2);
animation-delay: 0.08s;
}
/* Hover en focus: volledige glitch */
.gk-btn:hover,
.gk-btn:focus-visible {
box-shadow: -4px 0 0 var(--c1), 4px 0 0 var(--c2);
}
.gk-btn:hover .gk-label::before,
.gk-btn:focus-visible .gk-label::before {
animation: gk-a var(--speed) steps(1) infinite;
}
.gk-btn:hover .gk-label::after,
.gk-btn:focus-visible .gk-label::after {
animation: gk-b calc(var(--speed) * 0.9) steps(1) infinite;
}
.gk-btn:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 6px;
}
/* Korte tik in rust, aan het eind van de cyclus */
@keyframes gk-idle {
0%, 90%, 97%, 100% { opacity: 0; }
91% { opacity: 1; clip-path: inset(20% 0 50% 0); transform: translate(-3px, 0); }
94% { opacity: 1; clip-path: inset(60% 0 10% 0); transform: translate(3px, 0); }
}
/* Stroken knippen en verschuiven */
@keyframes gk-a {
0% { opacity: 1; clip-path: inset(0 0 65% 0); transform: translate(-3px, 0); }
20% { opacity: 1; clip-path: inset(40% 0 35% 0); transform: translate(3px, -1px); }
40% { opacity: 1; clip-path: inset(75% 0 5% 0); transform: translate(-2px, 1px); }
60% { opacity: 1; clip-path: inset(15% 0 60% 0); transform: translate(4px, 0); }
80% { opacity: 1; clip-path: inset(55% 0 20% 0); transform: translate(-4px, 0); }
100% { opacity: 1; clip-path: inset(0 0 65% 0); transform: translate(-3px, 0); }
}
@keyframes gk-b {
0% { opacity: 1; clip-path: inset(70% 0 0 0); transform: translate(3px, 0); }
25% { opacity: 1; clip-path: inset(10% 0 70% 0); transform: translate(-4px, 1px); }
50% { opacity: 1; clip-path: inset(45% 0 30% 0); transform: translate(2px, 0); }
75% { opacity: 1; clip-path: inset(85% 0 2% 0); transform: translate(-3px, -1px); }
100% { opacity: 1; clip-path: inset(70% 0 0 0); transform: translate(3px, 0); }
}
@media (prefers-reduced-motion: reduce) {
.gk-label::before,
.gk-label::after,
.gk-btn:hover .gk-label::before,
.gk-btn:hover .gk-label::after,
.gk-btn:focus-visible .gk-label::before,
.gk-btn:focus-visible .gk-label::after {
animation: none;
}
/* Statische, licht verschoven lagen bij hover */
.gk-btn:hover .gk-label::before,
.gk-btn:focus-visible .gk-label::before {
opacity: 0.8;
transform: translate(-2px, 0);
}
.gk-btn:hover .gk-label::after,
.gk-btn:focus-visible .gk-label::after {
opacity: 0.8;
transform: translate(2px, 0);
}
}Wat het is en waar je het gebruikt
De glitch-knop ziet eruit als een signaal dat even hapert. In rust is het een strakke zwarte knop met een witte rand en vette hoofdletters. Om de paar seconden zie je een korte tik. Bij hover of focus scheurt het label open in een cyaan en een magenta laag, die schokkerig over elkaar heen schuiven alsof de beeldbuis het even niet meer weet.
Het effect past bij tech- en gamingmerken, muziek, events en elke donkere interface met een ruw randje. Omdat het flink opvalt, werkt het het best voor één duidelijke actie per scherm.
Zo werkt het
- Het label heeft een
data-text-attribuut met dezelfde tekst..gk-label::beforeen::aftertonen die tekst viacontent: attr(data-text)als twee extra lagen precies boven het origineel. - Elke laag krijgt een eigen kleur (
--c1en--c2) enmix-blend-mode: screen, zodat overlappende delen oplichten zoals bij een RGB-split. - De keyframes
gk-aengk-bknippen metclip-path: inset()telkens een andere horizontale strook uit en verschuiven die mettransform: translate(). Door de timingsteps(1)springen de lagen van stand naar stand, zonder vloeiende overgang. Dat maakt het digitaal. - In rust draait
gk-idle. Die laat de lagen bijna de hele cyclus onzichtbaar en geeft alleen aan het eind een korte tik. Zo zie je ook in een stilstaande preview dat er iets gebeurt. - Bij hover krijgt de knop zelf een gekleurde
box-shadowlinks en rechts, als echo van de split.
Aanpassen
Op .gk-btn staan --c1 en --c2 voor de twee glitch-kleuren, --ink en --paper voor achtergrond en tekst, en --accent voor de focus-ring. Met --speed bepaal je hoe snel de glitch bij hover loopt. Lager is heftiger. Wil je meer chaos, voeg dan extra stappen toe aan de keyframes met andere inset()-waarden. Vergeet niet om het data-text-attribuut aan te passen als je het label verandert.
Toegankelijkheid en browsersupport
Het is een echte <button> met gewone tekst. De extra lagen zijn gegenereerde content. Met de syntax content: attr(data-text) / "" geef je ze een lege alternatieve tekst, zodat schermlezers het label niet drie keer voorlezen. Browsers die dat nog niet kennen, gebruiken de regel ervoor als fallback. Er is een duidelijke :focus-visible-outline. Bij prefers-reduced-motion staan alle animaties uit en blijft er een statische, licht verschoven kleurlaag over. Het effect flitst niet en blijft binnen de knop. clip-path: inset() en mix-blend-mode werken in alle actuele browsers.
Verder lezen
Meer over knoppen die opvallen lees je in CSS-knoppen met hover-effecten. Benieuwd hoe zulke effecten in een complete site passen? Bekijk onze aanpak voor interactief webdesign en animaties.
Meer knoppen
