CSS: aventures au pays de la translucidité

Récemment, on m'a demandé de corriger une page de destination. Parmi ce que j'ai trouvé dans son code, il y avait une image au-dessus de laquelle se trouvaient deux éléments translucides qui le chevauchaient. Les deux ont les mêmes valeurs de couleur RVB dans la propriété background-color. Cela ressemblait à ceci:

<img src='myImage.jpg'/>
<div class='over1'></div>
<div class='over2'></div>

Il n'était pas nécessaire d'utiliser deux de ces éléments. Cela pourrait être nécessaire, sauf si un seul de ces éléments ne teintait pas suffisamment l'image. Pour une raison quelconque, l'auteur de la page a décidé qu'il était préférable d'ajouter un autre élément translucide superposé à l'image que d'augmenter la valeur du opacitypremier paramètre . En conséquence, j'ai décidé de me débarrasser de l'un des calques et de définir le paramètre du reste afin que l'image externe soit la même que la précédente. Tout cela est bien, mais la question se pose: comment ajuster le paramètre de l' élément restant pour que le résultat soit le même que lors de l'application de deux couches translucides?



opacityopacity

Si vous lisez cet article sur la composition des masques, vous avez peut-être déjà deviné comment choisir la valeur appropriée. Après tout, la même formule est utilisée ici, qui y était utilisée pour la composition des éléments translucides à l'aide mask-composite: add. S'il y a deux couches avec des valeurs de transparence égales à a0et a1, alors la valeur de l'indicateur résultant est calculée comme suit:

a0 + a1 - a0*a1

Ici vous pouvez trouver une démo interactive, qui vous permet de comparer l'apparence de l'image, tonifiée avec deux calques, dont les propriétés opacity( a0et a1) peuvent être contrôlées à l'aide de curseurs, et la même image tonifiée par une propriété de calque opacityqui est calculée selon la formule a0 + a1 — a0*a1.


Les options pour teinter une image, dont deux copies s'affichent côte à côte.

Il est intéressant de noter que les zones dans lesquelles se trouvent deux éléments translucides et un de ces éléments sont identiques si l'image ci-dessous n'est pas affichée (vous pouvez désactiver la sortie de l'image à l'aide de la case à cocher situé en bas de l'écran). Mais si une image est affichée sous ces couches, ses deux options sont légèrement différentes. Peut-être que cette différence est simplement le résultat d'une illusion d'optique, peut-être que certaines parties des images me semblent plus claires ou plus sombres qu'elles ne le sont vraiment.

Ils ne sont certainement pas différents si vous ne les affichez pas côte à côte, mais basculez simplement entre deux couches dont les valeurs de propriétéopacitysont égales àa0eta1, et une couche, dont la valeur opacityest trouvée par la formule a0 + a1 — a0*a1. Voici un exemple pertinent.


Variantes de teinte d'image avec la possibilité de basculer entre une et deux couches translucides.

Cet exemple peut être étendu à plusieurs couches. Dans ce cas, calculez d'abord la transparence du nouveau calque, équivalente à la transparence des deux calques inférieurs. Trouvez ensuite la transparence du calque, équivalente à la transparence du nouveau calque, et le calque immédiatement au-dessus. Cette opération est répétée jusqu'à ce que toutes les couches aient été traitées.


Réduire plusieurs couches translucides en une seule couche

Des expériences similaires m'ont amené à réfléchir à la façon de calculer les paramètres d'une image d'arrière-plan opaque, qui équivaut à une couche opaque (c0) et à une couche translucide superposée (c1dont la transparence est définie sura). Dans ce cas, l'image finale, qui est une seule couche, peut être trouvée en traitant l'image originale canal par canal, tandis que les valeurs de couleur des canaux résultants sont calculées par la formule suivante:

ch0 + (ch1 - ch0)*a

Voici ch0le canal de la couche inférieure opaque ( red, greenou blue- pour les couleurs rouge, vert et bleu), ch1est le canal correspondant de la couche translucide supérieure et l'indicateur aest un indicateur qui définit la transparence de la même couche translucide.

Si vous exprimez ces arguments sous forme de code SCSS, vous obtenez les éléments suivants:

/*       */
@function res-ch($ch0, $ch1, $a) {
  @return $ch0 + ($ch1 - $ch0)*$a
}

@function res-col($c0, $c1, $a) {
  $ch: 'red' 'green' 'blue'; /*   */
  $nc: length($ch); /*   */
  $ch-list: ();

  @for $i from 0 to $nc {
    $fn: nth($ch, $i + 1);
    $ch-list: $ch-list, 
      res-ch(call($fn, $c0), call($fn, $c1), $a);
  }

  @return RGB($ch-list)
}

Voici un exemple interactif. En l'expérimentant, vous pouvez comparer l'apparence des deux couches et leur équivalent, présenté comme une seule couche. Ici, vous pouvez sélectionner les valeurs de couleur RVB de deux calques, ainsi que le niveau de transparence du deuxième calque.


Résultats de l'application d'une couche translucide à une couche opaque

Selon l'appareil, le système d'exploitation et le navigateur, vous verrez que les panneaux de couleur de cet exemple sont identiques ... ou pas. La formule est correcte, mais la manière dont les deux couches sources sont traitées dans des environnements différents peut varier.


La partie gauche de l'image est le résultat attendu de la réduction de deux couches à une. Le côté droit montre comment, lorsque deux couches sont combinées (à partir de la partie supérieure droite de l'image), la couche affichée en bas à droite peut avoir un aspect différent de celui attendu.

J'ai demandé aux utilisateurs de Twitter de m'envoyer des captures d'écran réalisées à l'aide de la version de test simplifiée de cet exemple. À en juger par les commentaires que j'ai reçus, il semble que les deux panneaux se ressemblent toujours dans les navigateurs mobiles (Android et iOS), ainsi que dans le navigateur Firefox, quel que soit le système d'exploitation. Presque toujours, les panneaux se ressemblent sous Windows, bien que j'ai reçu des réponses indiquant que Chrome et Chromium Edge rendent parfois les panneaux différemment que prévu.

Si nous parlons de navigateurs WebKit fonctionnant sur macOS et Linux, on peut noter que les résultats sont très hétérogènes. Dans la plupart des cas, la couleur des panneaux est légèrement différente. Mais l'utilisation du profil de couleur sRGB permet de rendre les panneaux identiques. La chose la plus intéressante commence si cet exemple est considéré dans un système qui utilise deux moniteurs. Faire glisser une fenêtre d'un moniteur à un autre peut entraîner le fait que la différence entre les panneaux est visible ou non visible.

Il convient de noter que dans des scénarios réels, la différence est très faible et qu'il est peu probable qu'une paire de ces panneaux soit côte à côte. Mais même s'il y a une différence, personne ne le saura jusqu'à ce qu'il teste la page dans différents environnements. Dans tous les cas, seul un développeur web peut probablement le faire. En outre, il existe un sentiment que les couleurs des éléments opaques ordinaires peuvent également être différentes lors de l'utilisation de différents appareils, systèmes d'exploitation et navigateurs. Par exemple, la couleur #ffa800, qui est largement utilisée sur css-tricks.com, est différente sur mes ordinateurs portables avec Ubuntu et Windows. Mais après tout, les yeux de différentes personnes peuvent percevoir les mêmes couleurs de différentes manières.

Chers lecteurs! Avez-vous rencontré des problèmes avec différents navigateurs, systèmes d'exploitation ou appareils affichant différentes couleurs de pages Web?


All Articles