DistorsionGratuit

RGB Split

Un texte blanc doublé d'une copie rouge à gauche et d'une copie cyan à droite qui tremblent sans arrêt : le décalage de couleurs d'un signal vidéo qui saute, en CSS seul.

CSSGlitchText

Mis à jour le

GLITCH
Survolez ou cliquez la scène pour interagir

Cet effet est gratuit — la catégorie Distorsion en contient 31 au total, dont 5 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →

Exemples d'usage

État des services

Paiements ralentisDepuis 14:32 UTC

  • API publiqueOPÉRATIONNEL
  • Tableau de bordOPÉRATIONNEL
  • Paiements
    DÉGRADÉ
  • Stockage objetOPÉRATIONNEL
  • E-mails sortantsOPÉRATIONNEL
  • DNSOPÉRATIONNEL

① Page de statut d'un hébergeur — l'étiquette « Dégradé » d'un service en difficulté

QuandOrvalin affiche l'état de ses six services. Seule la ligne Paiements, ralentie depuis 14:32, porte l'étiquette « DÉGRADÉ » qui tremble ; les cinq autres restent « OPÉRATIONNEL », en vert et immobiles.
PourquoiLe tremblement rouge et cyan évoque une liaison qui décroche : on trouve la ligne en panne sans lire la liste. Réduit à un mot de 11 px, l'effet signale sans affoler, et le lecteur d'écran dit simplement « DÉGRADÉ ».
RéglagesSur la racine : --rgbs-size: 11px, --rgbs-shift: 1.5px (écart adapté à la petite taille), --rgbs-color: #b45309 (ambre lisible sur fond clair), --rgbs-bg: transparent, --rgbs-height: auto.
Point hebdo · équipe produit 4 personnes en attente
Vous
HORS LIGNE

Réseau instable · nouvelle tentative dans 5 s

② Appel vidéo — « Hors ligne » dans la vignette quand la connexion échoue

QuandDans Talvoria, l'utilisateur clique sur « Rejoindre » pour entrer dans le point hebdo ; le bouton affiche « Connexion… », puis sa vignette se couvre d'un voile sombre avec « HORS LIGNE » qui tremble et la mention « Réseau instable · nouvelle tentative dans 5 s ». La scène rejoue ce clic en boucle ; dans la page, vous pouvez cliquer vous-même.
PourquoiLe tremblement rouge et cyan est l'image même d'un signal vidéo qui lâche : l'échec se comprend avant d'être lu, à l'endroit où l'image aurait dû apparaître. L'effet ne sert que le temps de l'incident, il ne décore pas l'appel.
Réglages--rgbs-size: 46px (34px sur téléphone), --rgbs-bg: transparent, --rgbs-height: auto. Le passage par « Connexion… » et l'apparition du voile sont câblés dans la scène, pas dans l'effet.

Musiques électroniques · 3ᵉ édition

STATIKORA

12 → 14 juin 20273 scènes · 41 artistes

③ Festival de musiques électroniques — le nom en très grand en haut de page

QuandEn arrivant sur le site, le visiteur voit STATIKORA sur toute la largeur, avec les dates, le nombre de scènes et le bouton « Prendre un pass » dessous.
PourquoiPour une marque électro, l'image d'un signal qui saute fait partie de l'identité : le titre porte l'ambiance à lui seul. Entre 44 et 124 px, la surface qui clignote reste sous le seuil mesuré pour un mot de cette taille.
Réglages--rgbs-size: clamp(44px, 14.5cqw, 124px) (taille suivant la largeur du bloc, qui porte container-type: inline-size), --rgbs-bg: transparent, --rgbs-height: auto, justify-content: flex-start sur la racine. La classe rgbs-text est posée sur un <h1>.

Comment ça marche

Le mot est écrit deux fois dans le HTML : dans l'élément .rgbs-text et dans son attribut data-text. Les pseudo-éléments ::before et ::after recopient cet attribut avec content: attr(data-text), prennent exactement la place du texte (position: absolute, même largeur) et passent derrière lui avec z-index: -1 : on ne voit d'eux que les bords qui dépassent.

La copie rouge part de 3 px à gauche, la cyan de 3 px à droite. Toutes les 0,15 s, l'animation rgbsShiftR emmène la rouge à 5 px à gauche et 2 px plus bas, rgbsShiftC la cyan à 5 px à droite et 2 px plus haut, puis les ramène. Ces écarts sont calculés depuis --rgbs-shift (3 px) : une fois cette valeur, puis 5/3 et 2/3. Pas de JavaScript, pas d'interaction : le tremblement commence dès l'affichage.

La racine .fx-0251-root centre le mot dans un bloc de 280 px de haut sur fond rgb(10, 10, 15). Ces deux valeurs sont des variables : --rgbs-height: auto et --rgbs-bg: transparent posent le texte sur votre propre page, comme dans les trois exemples.

Accessibilité

  • Lecteurs d'écran : le mot n'est lu qu'une fois. Les copies utilisent content: attr(data-text) / "", un texte de remplacement vide qui les retire de la lecture (Chrome 77+, Firefox 128+, Safari 17.4+). Plus ancien, le navigateur garde la première déclaration et certains lecteurs peuvent annoncer le mot trois fois. Mesuré dans les trois moteurs : « GLITCH GLITCH GLITCH » avant réparation, « GLITCH » après.
  • Clignotement : les bords colorés changent environ 7 fois par seconde. Mesuré image par image (cases de 16 px, critère WCAG 2.3.1), la surface qui clignote plus de 3 fois par seconde reste sous le seuil de 21 824 px² à la taille par défaut et jusqu'à 12rem. Elle s'en rapproche si vous montez --rgbs-shift sur un grand titre (au-delà d'environ 6 px). Pour un texte plus grand ou un écart plus fort, passez --rgbs-speed à 0.34s : plus aucune case ne dépasse alors 3 changements par seconde (mesuré à 12rem).
  • Mouvement réduit : sous prefers-reduced-motion: reduce, les deux animations sont retirées ; les copies restent décalées de 3 px de chaque côté, immobiles. Le relief rouge et cyan demeure, sans aucun clignotement.
  • Contraste : le texte principal reste plein, les copies ne font que dépasser des bords. Sur fond clair, donnez à --rgbs-color une couleur foncée (la page de statut des exemples utilise #b45309).
  • Aucune interaction : l'élément n'est ni lien ni bouton et ne réagit pas au pointeur (l'ancien cursor: pointer, trompeur, a été retiré). Pour un titre cliquable, mettez .rgbs-text sur un vrai <a>.

Compatibilité navigateur

CSS seul (2,5 Ko), aucune dépendance. Variables CSS, calc() dans les images clés et pseudo-éléments. Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 : rendu identique au pixel à l'ancienne version à 0, 40, 75 et 500 ms, deux copies indépendantes, aucun débordement à 390 px, 0 erreur.

Chrome 49+✓ Complet (mesuré)
Firefox 31+✓ Complet (mesuré)
Safari 9.1+✓ Complet (moteur WebKit mesuré)
Edge 79+✓ Complet (moteur Chromium)
Mobile iOS 9.3+✓ Complet (moteur WebKit mesuré)
Android Chrome 49+✓ Complet (moteur Chromium)

Sans variables CSS, les règles qui les utilisent sont ignorées : le mot s'affiche seul, dans la couleur du texte de la page, sans copies. Sans texte de remplacement pour content, la seconde déclaration est écartée et les copies s'affichent quand même.

Le code

Copiez les deux blocs (HTML et CSS) dans votre page. Aucun JavaScript, aucune dépendance.

HTML
<div class="fx-0251-root">
  <div class="rgbs-text" data-text="GLITCH">GLITCH</div>
</div>
CSS
.fx-0251-root,
.fx-0251-root *,
.fx-0251-root *::before,
.fx-0251-root *::after {
  box-sizing: border-box
}

/* Réglages : changez-les sur .fx-0251-root (ou sur un parent) */
.fx-0251-root {
  --rgbs-size: 3rem;        /* taille du texte */
  --rgbs-color: #fff;       /* texte principal */
  --rgbs-red: #ff0000;      /* copie de gauche */
  --rgbs-cyan: #00ffff;     /* copie de droite */
  --rgbs-shift: 3px;        /* écart des copies (va de 1 à 1,67 fois cette valeur) */
  --rgbs-speed: 0.15s;      /* durée d'un tremblement */
  --rgbs-bg: rgb(10, 10, 15);
  --rgbs-height: 280px;     /* auto : la hauteur du texte */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: var(--rgbs-height);
  overflow: hidden;
  position: relative;
  background: var(--rgbs-bg);
  color: var(--rgbs-color);
  font-family: sans-serif;
}

.rgbs-text {
  font-size: var(--rgbs-size);
  font-weight: 900;
  position: relative;
  z-index: 0;
  color: var(--rgbs-color);
}

/* Copies colorées : décoratives, ignorées par les lecteurs d'écran (« / "" ») */
.rgbs-text::before,
.rgbs-text::after {
  content: attr(data-text);
  content: attr(data-text) / "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
}

.rgbs-text::before {
  color: var(--rgbs-red);
  transform: translate(calc(var(--rgbs-shift) * -1), 0);
  animation: rgbsShiftR var(--rgbs-speed) infinite;
}

.rgbs-text::after {
  color: var(--rgbs-cyan);
  transform: translate(var(--rgbs-shift), 0);
  animation: rgbsShiftC var(--rgbs-speed) infinite;
}

@keyframes rgbsShiftR {

  0%,
  100% {
    transform: translate(calc(var(--rgbs-shift) * -1), 0);
  }

  50% {
    transform: translate(calc(var(--rgbs-shift) * -5 / 3), calc(var(--rgbs-shift) * 2 / 3));
  }
}

@keyframes rgbsShiftC {

  0%,
  100% {
    transform: translate(var(--rgbs-shift), 0);
  }

  50% {
    transform: translate(calc(var(--rgbs-shift) * 5 / 3), calc(var(--rgbs-shift) * -2 / 3));
  }
}

/* Mouvement réduit : les copies restent décalées, immobiles (aucun clignotement) */
@media (prefers-reduced-motion: reduce) {
  .rgbs-text::before,
  .rgbs-text::after {
    animation: none;
  }
}
JavaScript

CSS pur — aucun JavaScript requis.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Texte (HTML — contenu de .rgbs-text et attribut data-text) GLITCH Écrivez le même texte aux deux endroits : le contenu est le mot lu et affiché en blanc, l'attribut nourrit les deux copies colorées.
--rgbs-size 3rem Taille du texte. Toute unité CSS convient, y compris clamp() ou cqw pour suivre la largeur du bloc.
--rgbs-color #fff Couleur du texte principal. Prenez une couleur foncée sur un fond clair.
--rgbs-red · --rgbs-cyan #ff0000 · #00ffff Couleurs des copies de gauche et de droite. Magenta et vert (#ff00ff · #00ff66) donnent un décalage plus « écran cathodique ».
--rgbs-shift 3px Écart de départ des copies ; elles vont jusqu'à 5/3 de cette valeur. 1 à 1,5 px pour un petit texte, 4 à 6 px pour un très grand titre.
--rgbs-speed 0.15s Durée d'un aller-retour. 0.34s ou plus garde moins de 3 changements par seconde, quelle que soit la taille.
--rgbs-bg · --rgbs-height rgb(10, 10, 15) · 280px Fond et hauteur de la racine. transparent et auto posent le texte dans votre mise en page.

FAQ

Pourquoi faut-il écrire le mot deux fois, dans la balise et dans data-text ?

Un pseudo-élément ne peut pas recopier le contenu de son élément : content: attr(data-text) ne lit qu'un attribut. Si les deux diffèrent, les copies montrent l'ancien mot derrière le nouveau. Quand un script change le texte, mettez l'attribut à jour dans la foulée : el.dataset.text = el.textContent.

Le texte peut-il passer sur plusieurs lignes ?

Oui. Les copies ont la largeur de l'élément et héritent de son alignement : elles se coupent aux mêmes endroits que le mot principal. Pour de longs titres sur plusieurs lignes très grandes, ralentissez --rgbs-speed (0.34s) afin de rester sous le seuil de clignotement.

Peut-on ne faire trembler le texte qu'au survol ?

Le code fourni tremble en continu. Pour réserver le mouvement au survol, ajoutez animation-play-state: paused aux deux pseudo-éléments, puis running dans une règle .rgbs-text:hover::before, .rgbs-text:hover::after ; ajoutez :focus-visible si le texte est un lien, pour le clavier.