Brutaliste OKLCH

Laboratoire Pratique : Couleurs Brutes & Ombres Dures

Couleurs Acides & Calculs

Bon, pour le web design, je suis pas très fort, mais j'aime le brutaliste, on oublie les palettes douces. J'aime sortir de ce que font les gens, le contraste pur, c'est moins nian-nian. Mais même quand on veut faire un bordel visuel, il faut avoir une harmonie. Grâce à notre couleur de base :( --clr-brand ), on utilise calc() et from pour générer une palette agressive mais mathématiquement juste. Parce que bon, l'anarchie et le chaos, ne veut pas dire qu'il n'y a pas de règles. C'est l'ordre... moins le pouvoir.

Il faut donc s'organiser dans la composition du thème. en premier lieu on cherche la couleur dominante, la signature. On glisse le bouton sur la barre de l' hue à gauche et à droite. Mais j'aime bien le rose et le violet donc bon, je me suis arreté à 330 . On peut chercher 330.2 même, mais j'aime le simple.

On fait pareil avec --l-action et bien sur --c-neon . Mes valeurs sont pour la luminosité l: 85% et la teinte (gris fade ou couleur qui pète) c: 0.35 (sa pique les yeux). Donc mon token qui est ma couleur de marque c'est :

--clr-brand: oklch(var(--l-action) var(--c-neon) var(--h-brand));

J'ai choisi ce nom de variables comme ça, en explorant le web à gauche à droite, parce que j'aime bien ces termes, c'est pour moi évident. L'action pour tout ce qui va être bouton où il y a une action active et "neon", parce que c'est comme un néon qui clignote. Cela fait mal dans la figure le matin. Je peux donc ajouter d'autres termes si par exemple j'ai besoin de jouer sur la chroma. On peut imaginer avoir besoin d'un composant qui serait différent et moins sujet à attirer l'oeil. Je crée donc une variable
--c-neutral
C'est plus simple pour moi. A toi de t'organiser comme tu le souhaite. Coder doit être un plaisir .

D'autres personnes vont dire simplement --l et --c . Il y a même des thèmes qui définissent à l'avance les variations avec des variables de 0 à 100 pour --l .
Genre --l-100:100% . Pourquoi pas, cela donne une certaine lisibilité, mais moi j'aime pas trop, surtout que cela ne sert à rien de définir des variables qu'on ne va pas utiliser. C'est du bruit...

Donc voilà, je continue ma théorie. Pour moi, avec une luminosité de 85% et une teinte de 0.35, je déplace HUE de 45° à 55°. Donc je vais surtout utiliser calc(h +/- 45) . Je pourrais même faire :
--h-plus: (calc(var(--h-brand)) + 45)

C'est violent comme sa s'imbrique hein ? C'est pour les thèmes où on aurait plusieurs couleurs complémentaires. Bref, voilà ce que cela donne quand c'est pico bello simple (basique):
/* Couleur Analogue (Voisine) : On ajoute 45° */
background: oklch(from var(--clr-brand) l c calc(h + 45));
/* rappel : avec from on annonce le token, et on change QUE ce qu'on choisi

/* Couleur Complémentaire (Opposée) : On ajoute 180° */
background: oklch(from var(--clr-brand) l c calc(h + 180));
/*Avec OKLCH on peut calculer théoriquement la position des couleurs complémentaires et opposés*/
BASE
Token Origine h: var(--h-brand)
ANALOGUE
calc(h + 45) h: 375° (Foushia?)
COMPLÉMENT
calc(h + 180) h: 150° (Vert pomme?)
TRIADIQUE
calc(h - 120) h: 210° (Bleu Électrique?)

Alors, c'est là qu'il faut réfléchir quand on construit son thème. Parce que mon CSS, il est pas parfais, mais je l'aime comme ça. J'ai div avec deux class. L'une qui défine les formes la taille, les espacement etc... et l'autre qui a juste les valeurs des couleurs. Dans style.css les règles commencent à la ligne 177 avec
.swatch-base .

Change la valeur de --h-brand (actuellement 330) dans le CSS à la ligne 6. Tout le site s'adaptera mécaniquement à la nouvelle teinte dominante.

Ombres Solides & Stroboscope

J'aime le brutalisme parce qu' il n'y a pas de lueur (glow) . Le flou est interdit. Les ombres sont pleines, noires ou très sombres. On sait où on va et on sait pourquoi l'oeil est attiré à CET endroit... et pas au super flou gaussien qui lisse la bordure... Avec OKLCH pour récupérer la couleur de base, réduire violemment sa luminosité ( L ), on peut créer une ombre solide qui se décale mécaniquement.

Mécanique des ombres (Animation steps)

Pour l'ombre mécanique, au lieu d'une transition douce (ease), je préfère quand sa choque. Donc la fonction steps() dans l'animation CSS c'est pas mal. Le rendu est volontairement saccadé. OKLCH permet d'assombrir l'ombre parfaitement ( L=0.4 ) sans toucher au reste (ligne 229). On peut donc aussi utiliser from et calc() pour dériver les couleurs dans une animation. Et même les dériver sans les ajouter en dur dans une cascade de lignes, parce que l'élément enfant hérite de son parent. Donc on peut juste changer par exemple l sans devoir tout remettre.

@keyframes hard-pulse {
50% {
/* L'ombre devient la couleur de base assombrie (L=0.4) */
box-shadow: 10px 10px 0 oklch(from var(--clr-brand) 0.4 c h);
transform: translate(-4px, -4px);
}
}
.btn-mechanical {
/* steps(3) créer l'animation en 3 images brutes */
animation: hard-pulse 2s steps(3) infinite;
}

Le bouton Stroboscope (à droite) navigue sur la roue des couleurs en utilisant calc(h + 180) puis calc(h + 360) avec un délai très court, créant un effet hépileptique violent typique quand on veut pas que les gens fassent n'importe quoi :D. Avoue que t'es pas très bien là.

Transparence : Le coup de marqueur

C'est vrai, en brutalisme on déteste ce qui est à moitié. Pas de douceur, c'est crade, etc. Donc l'opacité "propre" à la apple et glassmorphisme on oublie.
MAIS on peut utiliser l'opacité comme truc du genre vieux coup de marqueur fluo sur du papier journal (?). Bon là, je suis pas sûr de mon coup, mais... j'ai un trick.

C'est le petit truc du / 0.1 caché dans les cards de couleurs plus haut ;). Avec oklch() et from , gérer le canal alpha (transparence / opacité) devient facile. Fini les variables rgba() illisibles. Tu prends n'importe quel token existant, tu ne changes ni L, ni C, ni H, et tu rajoutes un slash avec une valeur entre 0 et 1 (ou un %) :

/* On garde la même couleur, on met l'opacité à 40% (ou 0.4) */
background: oklch(from var(--clr-complementaire) l c h / 0.4 );

Cela fait un effet "erreur de calage d'imprimerie" ou glitch dégeu. On peut faire pas mal de truc avec l'opacité et en superposant deux blocs. Le bloc du dessus est transparent ( / 0.7 ) et il à un mix-blend-mode: multiply pour que les couleurs s'additionnent comme de la vraie encre :

ENCRE DE BASE
(Opaque)
SURCOUCHE CRADE
(/ 0.7 + multiply)

Et en plus... la couleur est liée. Donc on peut changer, sans trop de soucis les variables de départ (j'ai la flemme et je suis sur que j'aurai oublié de modifier la couleur du composant). Je te laisse imaginer avec une animation et step() qu'on a vu avant pour changer les couleurs et bouger les éléments. C'est pas mal non ?