Backgrounds✨ Premium

Relative Color Palette

Palette de dix teintes dérivées en cascade depuis une seule propriété CSS — luminosités et harmonies OKLCH se recalculent instantanément à chaque changement de teinte de base.

CSSJSOKLCH

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Backgrounds comprend 50 effets, dont 6 gratuits. Découvrir la catégorie →

3 exemples d'usage

Explorateur de palette marque — documentation design system — Relative Color Palette exemple 1

① Explorateur de palette marque — documentation design system

QuandUne page de charte graphique ou de design system présente les déclinaisons de la couleur brand et permet à l'équipe d'explorer des variantes de teinte.
PourquoiLe widget occupe une large surface et révèle d'un seul coup d'œil les dix teintes dérivées — luminosités et harmonies — depuis la couleur brand. Les développeurs identifient immédiatement les tokens à implémenter et comprennent visuellement les relations chromatiques.
Réglages--base-hue: 250 pour bleu-indigo brand, pastilles agrandies à 48 × 48 px en CSS, container à padding: 28px pour respirer.
Panneau de paramètres — sélecteur de couleur d'accent — Relative Color Palette exemple 2

② Panneau de paramètres — sélecteur de couleur d'accent

QuandUn SaaS propose à l'utilisateur de personnaliser la couleur d'accent de son espace de travail depuis les réglages du compte.
PourquoiLe widget condense toute une palette en un seul clic — l'utilisateur voit instantanément comment la teinte choisie se décline en tons clairs et foncés, sans ouvrir de sélecteur natif. La prévisualisation des harmonies aide à valider la cohérence avant d'appliquer.
Réglages--base-hue: 160 (vert-emeraude par défaut), pastilles à 32 × 32 px pour s'insérer dans une carte de paramètres, background: transparent sur le container.
Configurateur couleur produit — fiche article e-commerce — Relative Color Palette exemple 3

③ Configurateur couleur produit — fiche article e-commerce

QuandUn client choisit la couleur d'un vêtement ou accessoire depuis la fiche produit : le fond de la carte, le badge promotionnel, les pastilles de coloris et le bouton d'achat se redérivent tous depuis la même teinte OKLCH.
PourquoiL'acheteur voit instantanément comment son choix de couleur impacte l'ensemble de la présentation produit — fond, badge, bouton — sans un seul pixel incohérent. L'effet démontre qu'un seul <code>--base-hue</code> suffit à coordonner toute une interface non-technique, sans ligne JS supplémentaire.
Réglages--base-hue: 340 (rose-rouge pour vêtement), pastilles de coloris à 20 × 20 px arrondies pour un sélecteur compact, fond de carte à oklch(.09 .04 var(--base-hue)) pour tinter subtilement l'arrière-plan.

Comment ça marche

L'effet repose entièrement sur la propriété personnalisée --base-hue posée sur le container [data-relcolor]. Tous les descendants héritent de cette valeur via var(--base-hue) dans leurs déclarations oklch(). La première rangée décline cinq variantes de luminosité à chroma progressivement réduit : oklch(.85 .15 H) (très clair), .75 .20, .60 .25 (base), .45 .20, .30 .15 (très foncé). L'espace OKLCH étant perceptuellement uniforme, chaque saut de lightness paraît visuellement équivalent quelle que soit la teinte — ce qu'HSL ne garantit pas.

La deuxième rangée expose cinq harmonies chromatiques calculées par calc() sur la teinte : complément à H + 180, analogues à H ± 30, triadiques à H + 120 et H + 240. Le moteur CSS résout ces expressions nativement — zéro calcul JavaScript. Le chroma des harmonies est légèrement réduit (0.22 vs 0.25 pour la base) afin que les couleurs de relation restent distinctes sans saturation agressive.

Le JavaScript est intentionnellement minimal : querySelectorAll("[data-relcolor]") initialise chaque instance avec t = 250 (bleu-indigo) puis pose --base-hue via element.style.setProperty(). Au clic sur le container, t = (t + 47) % 360 fait avancer la teinte de 47° — un nombre premier qui parcourt les 360° sans jamais retomber sur des voisins proches avant d'avoir visité des angles très différents. Plusieurs instances sur la même page fonctionnent sans conflit car chaque itération forEach ferme sur son propre t.

Le hover des pastilles (transform: scale(1.2) translateY(-4px), transition 0,4 s) est la seule animation du composant. Sans JavaScript, la palette reste visible grâce aux valeurs oklch() calculées par CSS — seule la rotation de teinte au clic est inactive.

Accessibilité

  • prefers-reduced-motion absent du code. La seule animation est le hover scale(1.2) sur les pastilles (transition CSS 0,4 s) — mouvement léger et déclenché par l'utilisateur. Si ce point est critique dans votre contexte, ajoutez @media (prefers-reduced-motion: reduce) { .relcolor-swatch { transition: none } }.
  • Le container [data-relcolor] ne porte ni role ni aria-label natifs — il est traité comme décoratif. Si le composant joue un rôle fonctionnel (choix de thème), ajoutez role="group" et aria-label="Sélecteur de couleur de base".
  • Clavier : le container n'est pas focusable (pas de tabindex), la rotation de teinte au clic n'est pas accessible au clavier. Pour un accès complet, wrappez le déclencheur dans un <button> natif.
  • Contraste : les pastilles OKLCH à luminosité uniforme sont visuellement distinctes entre elles, mais le rapport de contraste texte/fond n'est pas calculé dynamiquement — à vérifier selon la teinte choisie avant usage dans un sélecteur fonctionnel.
  • Les attributs title HTML sur chaque pastille ("Lighter", "Light", "Base"…) fournissent un label de survol minimal accessible aux technologies d'assistance.

Compatibilité navigateur

Nécessite la fonction CSS oklch() et calc() sur des propriétés personnalisées — Baseline 2023, disponible dans tous les navigateurs modernes depuis mi-2023.

Chrome 111+✓ Complet
Firefox 113+✓ Complet
Safari 15.4+✓ Complet
Edge 111+✓ Complet
Mobile iOS 15.4+✓ Complet
Android Chrome✓ Complet

Sur les navigateurs antérieurs sans support <code>oklch()</code>, les pastilles affichent un fond transparent — aucune erreur JS, le layout reste intact. Ajoutez une déclaration <code>background: #888</code> avant chaque règle OKLCH pour un repli visible sur les UA anciens.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="relcolor-container" data-relcolor="" style="--base-hue: 250">
  <div class="relcolor-base-row">
    <div class="relcolor-base"></div>
    <span class="relcolor-base-label">Base</span>
  </div>
  <div class="relcolor-palette">
    <div class="relcolor-swatch sw-lighter" title="Lighter"></div>
    <div class="relcolor-swatch sw-light" title="Light"></div>
    <div class="relcolor-swatch sw-base" title="Base"></div>
    <div class="relcolor-swatch sw-dark" title="Dark"></div>
    <div class="relcolor-swatch sw-darker" title="Darker"></div>
  </div>
  <div class="relcolor-palette">
    <div class="relcolor-swatch sw-complement" title="Complement"></div>
    <div class="relcolor-swatch sw-analogous1" title="Analogous +30"></div>
    <div class="relcolor-swatch sw-analogous2" title="Analogous -30"></div>
    <div class="relcolor-swatch sw-triadic1" title="Triadic +120"></div>
    <div class="relcolor-swatch sw-triadic2" title="Triadic +240"></div>
  </div>
  <span class="relcolor-label">cliquez pour changer la couleur de base</span>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

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

Option / propriétéDéfautEffet
--base-hue (style inline) 250 Teinte de départ OKLCH (0–359). 0 = rouge, 120 = vert, 180 = cyan, 250 = bleu-indigo, 300 = violet. Modifiez la valeur inline ou via JS : el.style.setProperty('--base-hue', 160).
t + 47 (JS, 3e ligne) 47 Pas de rotation de teinte par clic. 47 = nombre premier qui évite les voisins proches. Essayez 30 (douzaines régulières) ou 60 (six couleurs espacées de 60° pour une roue complète en 6 clics).
.sw-base { background: oklch(.6 .25 …) } L=0.6, C=0.25 Lightness et chroma de la pastille de référence. Montez C jusqu'à 0.37 (max sRGB) pour plus de saturation, descendez L à 0.5 pour une base plus sombre.
.sw-lighter { background: oklch(.85 .15 …) } L=0.85, C=0.15 Variante la plus claire. Gardez C inférieure à la base pour rester dans le gamut sRGB à haute luminosité. Ajustez L entre 0.78 et 0.92 selon la clarté souhaitée.
.relcolor-swatch { width; height; border-radius } 36px, 36px, 8px Dimensions et forme des pastilles. Passez à 48 × 48 px pour un affichage documentation, ou 24 × 24 px pour un sélecteur compact en barre d'outils.
.relcolor-base { width; height; border-radius } 50px, 50px, 12px Taille de la pastille de base mise en avant. Augmentez à 64 × 64 px pour un affichage hero de la couleur de référence.
.relcolor-container { gap; padding; background } 16px, 20px, #0f0f1a Espacement entre rangées, marges internes et fond du widget. Passez background: transparent pour l'intégrer dans une carte existante.

FAQ

Pas nativement — l'effet attend un angle OKLCH (0–359) dans --base-hue. En JavaScript, convertissez votre hex en OKLCH avec une bibliothèque comme culori : const h = oklch(parse('#3b82f6')).h, puis injectez le résultat avant que le script s'exécute via el.style.setProperty('--base-hue', h).
Ajoutez deux <div class="relcolor-swatch"> dans la deuxième rangée avec des classes CSS dédiées : .sw-split1 { background: oklch(.58 .21 calc(var(--base-hue) + 150)) } et .sw-split2 { background: oklch(.58 .21 calc(var(--base-hue) + 210)) }. Aucune modification du JavaScript n'est nécessaire — les pastilles héritent automatiquement de --base-hue.
HSL n'est pas perceptuellement uniforme : un jaune à hsl(60 100% 50%) paraît bien plus lumineux qu'un bleu à hsl(240 100% 50%) à lightness identique. OKLCH garantit que oklch(.6 .25 60) et oklch(.6 .25 240) ont la même luminosité perçue — les palettes dérivées sont visuellement cohérentes quel que soit l'angle de teinte choisi.