Cet article est dans la série consacrée au développement de la bibliothèque cpu-audio.js et documente les affres de sa version 6.

  1. Mettre de l'audio dans le web n'a pas été simple
  2. Reconstruire son lecteur audio pour le web (sur la version 5)
  3. Retravailler un lecteur web audio dans les petites largeurs
  4. Le blues du Web Share (english version)
  5. Deux couleurs bizarres en CSS
  6. cpu-audio.js enfin en 7.0
  7. Tout-terrain WebVTT pour de l'audio
  8. Dichotomie entre podcast et web sur l'audience

Je vous remets le player, dans la dernière version de dev. Sinon, ⇓ sautez ⇓ directement ⇓ au chapitre suivant ⇓

Pour lire ce billet, il est conseiller d'aller sur mon site dascritch.net. Si vous lisez ce texte, c'est que probablement vous n'y êtes pas.

Comment replacer un sujet tiers rien à voir avec le billet sous prétexte d'illustration d'exemple…

La Couleur tombée du DOM

Je vais parler non pas de couleurs interdites (quel nom de film d'horreur génial !) comme le Rouge Surbrillant, le Jaune Bleuté, ou l'Orange Hyperbolique, mais de deux définitions volontairement manquantes dans les CSS. Or, comme mon player a un aspect totalement paramétrable par les utilisateurs via la CSS, lesdits utilisateurs pourraient tenter de faire un effet qui sera systématiquement en échec.

Allez, cadeau ! trois couleurs interdites (impossibles, ou plutôt chimériques).
Observez le point de gauche, votre regard fixé sur le × sans bouger pendant trente secondes,
puis sautez au carré du milieu et restez sur sa ×.
Auteur : Zowie CC-BY-SA pour Wikipédia.

D'autres parlent bien mieux que moi des couleurs en CSS, donc je ne ferais pas l'affront d'en faire un résumé imparfait, mais je sauterais direct au nœud du problème : J'ai deux manques dans la norme, mais qui sont totalement justifiés. Et des effets de bords qui pourraient surprendre des intégrateurs non prévenus.

transparent

Cette couleur existe principalement en valeur de la propriété background : transparent. On a trouve aussi pour border-color ou encore dans l'attribut fill="transparent" d'une balise SVG.

En fait, transparent n'est pas un alias vers une couleur pleine, mais d'une couleur quelconque rendue avec une opacité de 0%.

Sauf qu'il y a une méprise : il n'est pas possible de s'en servir pour la propriété css color dans l'idée d'avoir le rendu derrière le fond du tag courant. Une couleur transparente fera que le texte est virtuellement non affiché mais présent par ses dimensions.

Et c'est normal, car cela voudrait dire que le navigateur devrait être capable d'utiliser la forme des lettres pour découper le fond de l'élément support. C'est pas impossible, mais totalement tordu en terme de pensée, alors que vous pouvez preeeesque facilement le faire en SVG. Bon, dans les faits, je ne vous le conseille absolument pas ! Et ceci pour des raisons de performances de rendu, votre site va commencer à ramer sévère si vous vous lâchez.

currentColor

Cette magnifique couleur définie en CSS3 n'existe qu'en couleur de pinceau : currentColor

currentColor est immensément pratique, car elle fait référence à la couleur de pinceau héritée. Et si cette couleur héritée renvoie par exemple à une variable css au nom à coucher dehors (hello var(--cpu-playing-color)) , sur de nombreux rappels, on gagne de très nombreux octets... Exemple :

main {
    color : var(--cpu-color);
}
main.act-playing {
    color : var(--cpu-playing-color);
}
a, button (je vous la fait courte) {
     color : currentColor;
}
svg {
     fill : currentColor;
}

Bien plus pratique que color : inherit, car pouvant s'appliquer sur d'autres propriétés.
À chaque coup, je gagne.

currentColor est une Valeur Magique en css. Magique dans le sens Noble du terme, au sens que justement, ce n'est pas une constante arbitraire (par rapport au sens commun en informatique, et qui tient de l'insulte) mais qu'elle fait référence à son contexte et elle permet de gagner un temps fou.

Sauf que, hélas, et je ne suis pas seul à m'en plaindre, on n'a pas de currentBackground

Et c'est tout à fait normal : background a été discuté jusqu'ici dans ce billet en tant qu'écriture raccourcie de la propriété background-color. La propriété background est en fait composite, très complexe : On peut créer des arc-en-ciels, étirer une image, mettre des motifs svg embarqués. Retenez que background-color est la dernière composante définissant le fond d'un élément à être interprétée, lequel fond est défini par le standard comme ayant de multiples couches de rendus.

Alors quel est le problème ?

Et ben tout simplement, je ne peux pas inverser la couleur et le fond hérités.

Ainsi

button:hover {
    background : currentColor;
    color : currentBackground;
}

ça marche pas, puisque la propriété n'existe pas.

Et

button:hover {
    color : var(--cpu-background);
    background : var(--cpu-color);
}
.act-playing button:hover {
    color : var(--cpu-playing-background);
    background : var(--cpu-playing-color);
}

Si vous aviez voulu mettre une des variables de couleur de fond à transparent... ça marchera pas non plus, vous vous retrouverez avec des boutons avec du texte totalement transparent qui ne se distinguera pas du fond. blanc, noir, rose, bleu schtroumpf, qu'importe la valeur que vous avez choisi ça sera illisible !

Et si la couleur de texte est transparente et que la couleur de fond est fixée sur la couleur courante pour le même bloc, vous aurez une superbe disparition !
(pourtour ajouté pour voir le bloc)

Essayez vous-même !

Pour lire ce billet, il est conseiller d'aller sur mon site dascritch.net. Si vous lisez ce texte, c'est que probablement vous n'y êtes pas et donc vous ne pouvez expérimenter avec l'édition interactive.

Le bloc de code CSS ci-dessous est éditable, et il impacte directement le lecteur au-dessus. Sur le détail des variables CSS du lecteur, je vous renvoie à la doc.

Évidemment, y'en a qui vont me dire ça marche pas sur mon appli de news, donc voici une capture d'écran de ce que vous devriez voir :

Le rendu du player en attente à gauche, lors d'un survol souris ou d'un clic sur le bouton de lecture à droite,
lequel devient malencontreusement invisible.

Où tu rêves d'une licorne rose invisible

Alors il y aurait une bonne astuce : au lieu d'utiliser transparent, spécifier une couleur de fond avec une transparence totale genre #ff777700 (le fameux rose invisible de la légendaire licorne, qui est même enseignée en Zététique), et pouvoir mettre la transparence à opacité totale quand je tente d'utiliser cette couleur en guise de couleur de police/remplissage.

La fameuse licorne dans une représentation improbable de sa couleur impossible.
CC-BY Bingo Pajama Bee via Wikipedia, loués soient-ils

Mais là, il me manque (au choix) :

  • soit une propriété css background-opacity (et son pendant color-opacity),
  • soit un transformateur standard de valeur css que s'appelerio plain-color() qui me rabote une couleur avec opacité en couleur sans opacité,
  • soit des billes car ça existe peut-être déjà (j'ai pas dit que je connaissais à fond les CSS).

Tentative 1 : CSS pure, rgba() et deux variables

J'ai bien trouvé une solution amusante avec la fonction css rgba() sous la forme
background : rgba(var(--background-color), var(--background-opacity))
mais comme cette astuce joue sur le fait que var() ne fait que restituer une chaine de caractère sans l'avoir interprété, elle induit :

  • que toutes les couleurs (encre et fond) paramétrées par l'intégrateur soient totalement opaques,
  • que je doive introduire une propriété de plus à part pour la gestion d'opacité du fond,
  • que la syntaxe de couleur suive strictement la syntaxe rrrgggbbb, ce qui multiplie les risques d'erreurs,
  • que l'intégrateur/utilisateur ne peut donc pas utiliser la syntaxe hsl()/hsla() que nombre de graphistes et intégrateurs trouvent extrêmement pratique,
  • ni les couleurs nommées prédéfinies comme rebecca purple (version audio du billet),
  • et seraient aussi bloqués ceux qui auraient voulu mettre un motif plutôt qu'une couleur unie.

Pour toutes ces raisons, ce hack me semble limite pour l'Inspecteur Hacky, donc pour l'instant ⇒ c'est non.

Tentative 2 : Polyfill javascript pour déduire une couleur totalement opaque

Certains m'ont suggéré d'utiliser/créer un polyfill en javascript pour extraite la couleur opaque en surveillant les modifications sur la variable d'environnement, et en définissant une autre variable d'environnement à la volée avec le canal alpha complètement opaque. L'idée semblait être une bonne idée, puisque les variables CSS peuvent changer suivant les contextes (position de l'élément dans le DOM, taille de la fenêtre, :hover , :focus, etc...). Les innocents…

Évidemment, il faut convertir la couleur CSS qui peut être retournée en n'importe quelle notation valide vers un format RGBA ou HLSA (peu importe, tant qu'on peut avoir la valeur alpha à part). J'ai vérifié avec la méthode window.getComputedStyle() en l'appliquant sur un élément de référence, seul moyen de résoudre les contextes comme currentColor. Outre que créer un élément de référence uniquement dans ce but est une méthode qui pue un peu, la fonction que j'appelle retourne à peu près le format qu'elle veut, selon l'envie du navigateur, l'historique de la propriété et le système derrière. Ainsi, on peut tout à fait imaginer qu'un écran passif travaille en HLS, ou qu'une évolution prochaine du standard passe d'un rendu de 8 à 16 bits par canal couleur. De petites fonctions pèteront le webcomponent à la gueule des utilisateurs sans que vous ne voyiez rien venir.

Donc il nous faut une regex convertisseur magique qui n'existe pas en standard en pariant très fort que les navigateurs ne retournent que du rgb() ou du rgba().
Là aussi, j'ai tenté, j'ai abandonné : beaucoup trop de taf pour un résultat incertain et un usage marginal.

Si néanmoins vous vous le sentez, tentez de le faire : j'aurais toute une liste de cas d'usages à vous faire tester, vous allez en suer et vous finirez par écrire un billet technique sur le côté complexe et vain de cet exercice. Une bien maigre compensation, mais qui vous permettra de proposer une conf à un devfest.

J'ai même réfléchi à faire un filter : invert(100%); plutôt qu'inverser les variables de couleurs, mais le rendu n'était pas plaisant dans nombre de cas.

Et là, tu peux plus voir cette exception en peinture

Mais tu sais que c'est normal et tu dois l'accepter. Je dois être un genre de fou à la Van Gogh. LIBÉREZ LA PALETTE CHROMATIQUE !

Alors évidemment, il y aura toujours des personnes qui vous diront « Ahlalalala ! Mais il suffisait simplement de passer par un pré-processeur CSS pour obtenir cet effet ». Sauf que

  1. Ces personnes n'ont pas lu l'ensemble de cet article ;
  2. Ni le chapitre d'un article précédant expliquant les contraintes d'écriture d'un web-component réutilisable ;
  3. Que je veux que ma bibliothèque javascript soit utilisable directement en insérant le script et en ajoutant la balise <cpu-audio>,
  4. Qu'elle soit configurable même par des gens qui n'ont qu'un minimum de bagage HTML avec une bête page statique,
  5. Qu'elle utilise en priorité les standards du web et en évitant les rustines,
  6. Et sans avoir à installer une suite d'intégration complexe, genre NPM.js je-te-télécharge-internet-pour-changer-une-couleur.

Donc nous sommes dans un cas limite qui est actuellement bloqué, et qu'on ne tentera pas de palier dans l'immédiat car elle n'impacte qu'un cas de paramétrage d'aspect très marginal, et qui est compensable.

Désolé Larcenet*, on s'est parfois engueulés ensemble, mais j'ai pas pu m'empêcher de citer dans mon billet technique le dos de la couverture du deuxième tome de tes fabuleuses «  Aventure rocambolesque », celui avec Vincent Van Gogh. C'est chez Dargaud. Achetez-le !

Eh mais, du coup, je peux clore ce ticket #29 : Some css vars settings won't be useful, non ?

Non :

La couleur tombée du Ciel

J'ai écrit cet article en Avril 2019.
Entretemps, un nouveau groupe d'API natifs commence à arriver dans les navigateurs : CSS Houdini.

Et ce groupe est tellement stupéfiant qu'on dirait une nouvelle de Lovecraft adaptée part Richard Stanley (Personal message : If you read me, I salute you, by the way. You're welcome for a craft beer.).

L'idée est d'étendre les variables CSS pour leur faire porter une partie d'attributs, via l'API accessible en javscript : CSS.registerProperty.
Ce qui permet d'étendre les possibilités des propriété css background.

L'idée est géniale, audacieuse, mais je ne la mettrais pas dans ma bibliothèque, car elle relève plus de la coquetterie de chaque site que de réellement la responsabilité de mon web-component. De plu, il est probable que les performances de rendu navigateur impactent l'expérience utilisateur si vous êtes trop gourmands.
Néanmoins, l'usage des variables CSS dans mon code en laisse la possibilité à tout intégrateur aventureux.

La prochaine fois, on va s'amuser avec des objets DOM incongrus, des méthodes javascripts et des fichiers de sous-titrage. Et croyez-moi, c'est à la fois instructif et éclairant quand une norme a des limites pour rester dans son intention.