Imaginez le HTML suivant dans votre tête :
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
Vous ouvrez ce HTML dans votre navigateur. Quel est la couleur de la page ?
Vous pouvez penser que c’est une question piège, car le blanc n’est pas réellement une couleur, mais la page n’est de toute façon pas blanche : elle est transparente. Oui, le navigateur est blanc, mais la page présentée au sein du navigateur est transparente.
Prouve-moi que la page n’est pas blanche, car elle me semble tout de même pas mal blanche
Mode philosophe activé :
Qu’est ce qu’une page ?
Deux éléments doivent être considérés :
- l’élement
body
; - l’élement
html
.
Si l’on souhaite obtenir un fond jaune, on utilise la propriété background-color
sur le body
:
body {
background-color: yellow;
}
À partir de cet exemple, on peut imaginer que le body
remplit l’intégralité du viewport, car désormais tout est jaune.
C’est faux. Ajoutons une bordure au body
:
Vous pouvez voir qu’en réalité le body
n’utilise que l’espace dont il a besoin pour afficher le contenu « Hello world ».
Mais alors, pourquoi tout ce jaune ?
Il faut demander cela au w3c :
Traduction humaine : vous spécifiez une couleur de fond sur le body
. Le navigateur l’utilisera comme couleur de fond du canvas.
Le canvas, dites-vous ?
Une surface infinie, rien que ça.
La notion de canvas est absente de la plupart des cours dédiés au CSS (y compris du mien, dois-je avouer), bien qu’il s’agisse d’un composant très important du navigateur. Comme nous venons de le voir, en se basant sur le body
, il fourni un arrière-plan pour l’ensemble du viewport.
Avec cette nouvelle information, nous pouvons mettre à jour notre représentation mentale de la page, de haut en bas :
- l’élément
body
; - l’élément
html
; - le canvas.
Pendant longtemps, j’ai pensé que le canvas était jaune parce que le body
était le canvas. Mais non : le canvas ne fait qu’utiliser une information provenant du body
et peut être bien plus grand que le body
lui-même.
Il est intéressant de noter que bien que l’on demande au body
d’être jaune, il est en réalité transparent. Comme l’explique le W3C :
Il est inutile pour le navigateur de peindre le body
, qui a la même couleur que le canvas : il est donc traité comme étant transparent.
En d’autres termes, lorsque vous donnez une couleur de fond au body
, vous stylisez en réalité le canvas (qui ne peut pas être ciblé directement en CSS). Le canvas « vole » la valeur du body
.
Au-delà du body
Mode philosophe activé :
Qu’est ce que le
body
?
D’après le W3C, le body
représente les contenus du document
.
Si le body
est le contenu, il semble honnête de dire que ce qui est en dehors du body
n’est pas le contenu.
Dans ce cas, utiliser background-color
sur l’élément html
ne devrait pas avoir d’effet, puisqu’il ne fait pas partie du contenu ?
Pensez-y un instant : à quoi ressemblerait notre page avec ce CSS ?
html {
background-color: green;
}
body {
background-color: yellow;
}
Quelle est la couleur de la page maintenant ? Est-elle verte, est-elle jaune, est-elle les deux ? Bien sûr qu’elle est les deux.
Que voyons-nous ?
- le jaune est désormais limité au
body
; - l’élément
html
semble remplir l’ensemble du viewport.
Faux ! Une fois de plus, nous sommes trompés par les apparences.
Mais si, il remplit le viewport, toute la page est verte !
Je sais. Mais ajoutons des bordures à l’élément html
pour comprendre ce qui se passe :
Il est intéressant de noter que le navigateur n’a pas de problème pour appliquer des styles (tels que nos bordures) en dehors du body
. Mais continuons.
Donc, en réalité, le html
se comporte comme le body
: il ne prend que la place nécessaire à la présentation de son contenu, c’est à dire le body
et ses 8px
de marge, qui viennent des styles par défaut du navigateur.
Mais alors pourquoi tout ce vert ?
Même réponse du W3C :
On apprend également que l’élément racine peut être le body
ou le html
:
Bien que le W3C recommande de ne pas utiliser l’élément html
pour faire cela, c’est ce que l’on vient de faire, et c’est de là que le canvas tire sa couleur verte.
Comme dans le premier exemple, l’élément html
est traité come transparent : son vert est « volé » par le canvas.
Nous avons maintenant l’algorithme complet que le navigateur utilise pour choisir la couleur du canvas :
if (le html possède une background-color) {
on l'utilise pour peindre le canvas
}
else if (le body possède une background-color) {
on l'utilise pour peindre le canvas
}
else {
le canvas demeure transparent
}
Bien, cela fait un mystère de résolu, et ce n’est pas si étrange, finalement. Il est même assez heureux que nous n’ayons pas à donner des dimensions explicites à l’élément racine pour que la couleur de fond remplisse le viewport.
Pourquoi est-ce important ? Et c’est quoi cette histoire de blanc VS transparent ?
Comprendre qu’il y a une différence entre blanc et transparent, bien que les deux situations semblent identiques, est clé dans la compréhension de certains mystères du CSS.
Amusons-nous avec mix-blend-mode
. Cette propriété CSS nous permet de définir comment un élément devrait se mélanger visuellement avec son parent. On en parle parfois comme de « Photoshop dans le navigateur ». Que cela soit une éxagération ou non, les possibilités sont extraordinaires.
Commençons avec un exemple simple : notre h1
sera vert, et nous souhaitons changer son apparence avec mix-blend-mode: difference
.
h1 {
color: green;
mix-blend-mode: difference;
}
La valeur difference
signifie que la couleur du texte sera la différence entre la couleur originale (vert) et la couleur de l’arrière-plan.
La différence entre vert et blanc est rose. On espère donc que notre titre sera rose.
Il n’est pas rose. Je répète, il n’est pas rose.
Mais il devrait devenir rose, l’arrière-plan est blanc !
Non, il n’est pas blanc. Il est transparent.
La différence entre vert et transparent est vert, et c’est pour cela que la couleur du titre reste inchangée.
Récapitulons :
- le
body
est transparent (valeur par défaut debackground-color
) ; - le
html
est transparent (valeur par défaut debackground-color
) ; - le canvas est transparent (aucune valeur fournie par
html
oubody
).
Notre pauvre titre n’a donc rien avec quoi se mélanger.
Le correctif est facile : donnez un arrière-plan blanc au body
!
body {
background-color: white;
}
Et maintenant, ça fonctionne !
Récapitulons à nouveau :
- le
body
est transparent (white
est défini dans le CSS, mais la valeur est « volée » par le canvas) ; - le
html
est transparent (valeur par défaut debackground-color
) ; - le canvas est blanc (la valeur est issue du
body
).
Et c’est ainsi que notre titre vert se mélange au canvas pour devenir rose. Ce titre pourrait bien sûr être une image, une vidéo, quoi que ce soit. Le body
(ou n’importe quel élément contenant notre cible) doit posséder un arrière-plan (on pourrait également donner une couleur de fond à l’élément html
pour y parvenir, mais ce n’est pas standard).
Notre périple touche à sa fin, mais une question demeure...
Quelle est la couleur d’un canvas vide ?
Notre modèle mental d’une page est ainsi :
- l’élément
body
; - l’élément
html
; - le canvas.
D’après ce que nous venons d’apprendre, si le body
et le html
sont transparents, le canvas sera transparent aussi.
Mais comment la dernière couche peut-elle être transparente ? Si c’était le cas, on verrait le bureau et les autres fenêtres au travers du navigateur, tu es fou !
Laissez-moi vous expliquer. Et s’il y avait une autre couche, réellement blanche, plus bas que le canvas ?
Encore une fois, le W3C nous donne la réponse :
Traduction humaine : il y a quelque chose derrière le canvas. Vous pouvez voir cette chose si le canvas est transparent. Ce que vous voyez dépend du navigateur.
Sur tous les navigateurs auxquels je peux penser, cette dernière couche est blanche. Mais théoriquement, elle pourrait aussi montrer l’image d’un cheval en train de manger une pizza à l’ananas. Quel web étrange cela serait.
Bref, cela m’a conduit à me poser une question : y a-t-il un moyen de vraiment voir la différence entre un canvas blanc et un canvas transparent ? Peut-on obtenir la preuve que le canvas est transparent par défaut ? Je demande pour un ami.
L’indice de l’iframe
Revenons à un CSS très simple :
html,
body {
border: 3px dashed black;
}
Incluons cette page dans une autre grâce à une balise <iframe>
:
<iframe src="..." width="100%" height="300px"></iframe>
Voici ce que l’on obtient :
La question est donc : l’iframe
possède-t-elle un canvas transparent ou blanc ?
Nous pouvons obtenir la réponse en donnant un arrière-plan à la page parente :
body {
background-color: lightblue;
}
Comme vous pouvez le constater, l’iframe
est transparente. Son body
, son html
et son canvas. On peut voir la page parente au travers.
Cela prouve-t-il vraiment que le canvas est transparent ? Peut-être que les iframes n’ont pas de canvas ?
C’est une question légitime. Pour y répondre, ajoutons un fond blanc à l’élément body
de l’iframe
:
body {
background-color: white;
}
Si l’iframe
n’avait pas de canvas, la zone en dehors de son élément body
ne serait pas remplie. Mais grâce au mécanisme du canvas, la couleur de fond du body
peut être utilisée pour couvrir l’ensemble du viewport de l’iframe
.
Et c’est ainsi que l’on montre que sur n’importe quelle page, le canvas par défaut n’est pas blanc mais transparent.
Ce que vous voyez quand vous ouvrez une page vide n’est donc pas un canvas blanc. C’est juste le « fond » du navigateur, l’arrière-plan du logiciel, en dehors du monde du CSS, qui n’interagit aucunement avec quoi que ce soit.
Et voici donc notre modèle (final ?) de ce que nous voyons :
- l’élément
body
(transparent par défaut) ; - l’élément
html
(transparent par défaut) ; - le canvas (dépend du
html
et dubody
, donc transparent par défaut) ; - les fondations innaccessibles du logiciel (souvent un fond blanc).
Oh, et j’ai essayé d’en faire un dessin :
C’était sympa, ce petit voyage. Et oui, j’ai une vie.
CSS tourne beaucoup autour de ce que l’on voit, mais aussi beaucoup autour de ce que l’on ne voit pas.
Aventures CSS au pays du canvas
Cet article a été initialement publié sur dev.to
✍️ Aucun commentaire pour le moment