<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>Bastien Calou - Développeur front-end freelance</title>
	<subtitle>Je développe des sites et design systems résilients, accessibles et performants.</subtitle>
	
	<link href="https://bastiencalou.fr/feed/feed.xml" rel="self"/>
	<link href="https://bastiencalou.fr/"/>
	<updated>2025-01-17T00:00:00Z</updated>
	<id>https://bastiencalou.fr/</id>
	<author>
		<name>Bastien Calou</name>
		<email>bastien.calou@gmail.com</email>
	</author>
	
	<entry>
		<title>Cette page est 80 % moins lourde que la médiane des pages web</title>
		<link href="https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/"/>
		<updated>2025-01-17T00:00:00Z</updated>
		<id>https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/</id>
		<content type="html">&lt;p&gt;C&#39;est une constante depuis des lustres : le poids médian des pages web ne fait qu&#39;augmenter. D&#39;après le site &lt;a href=&quot;https://httparchive.org/reports/page-weight#bytesTotal&quot;&gt;HTTP Archive&lt;/a&gt;, cette augmentation se situe entre 5 et 10% par an et ne montre aucun signe de ralentissement.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/87bFVTxtKa-390.avif 390w, https://bastiencalou.fr/img/87bFVTxtKa-780.avif 780w, https://bastiencalou.fr/img/87bFVTxtKa-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/87bFVTxtKa-390.webp 390w, https://bastiencalou.fr/img/87bFVTxtKa-780.webp 780w, https://bastiencalou.fr/img/87bFVTxtKa-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/87bFVTxtKa-390.webp&quot; alt=&quot;Un graphique montre l&#39;augmentation constante du poids médian des pages web entre 2011 et 2024 : c&#39;est presque une ligne droite&quot; width=&quot;780&quot; height=&quot;495&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Vers l&#39;infini et au-delà !
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;On pourrait en explorer les causes et en déplorer les conséquences, mais ce n&#39;est pas ce que je souhaite faire ici. Je veux simplement montrer tout ce que peut contenir une page web dont le poids serait &lt;strong&gt;20% du poids médian actuel&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Le poids médian actuel sur desktop est 2 676 Ko. &lt;strong&gt;Notre objectif est donc 532 Ko&lt;/strong&gt;. Moins de 10% des pages web sont aussi légères.&lt;/p&gt;
&lt;p&gt;Que peut-on bien faire avec « si peu » de data ? Une pauvre page de connexion avec deux champs, peut-être ? Sans doute une page sans image, sans vidéo, sans interactivité, triste comme tout… Les autres pages ne sont pas si lourdes pour rien, si ?&lt;/p&gt;
&lt;p&gt;Essayons voir.&lt;/p&gt;
&lt;h2 id=&quot;ce-que-contient-cette-page&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#ce-que-contient-cette-page&quot;&gt;Ce que contient cette page&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;les-bases-:-html-css-js&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#les-bases-:-html-css-js&quot;&gt;Les bases : HTML / CSS / JS&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Du texte, déjà. Vous êtes en train de le lire. C&#39;est à la fois le plus important et l&#39;une des ressources les plus légères. Ce texte est structuré au sein d&#39;un document HTML, pour un total de &lt;strong&gt;11 Ko (soit 2,1 % de notre budget)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Du style : le CSS qui met en forme tout ça et rend votre lecture un peu plus agréable. Il pèse &lt;strong&gt;7 Ko (1,3 %).&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Un fichier JavaScript, qui gère quelques interactions basiques et le formulaire de commentaire. Il fait gentiment ça pour le modeste poids de &lt;strong&gt;3 Ko (0,6 %)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;fonts-et-medias&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#fonts-et-medias&quot;&gt;Fonts et médias&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Une chouette font, « Euclid », pour les titres et sous-titres. Grâce au script &lt;a href=&quot;https://github.com/zachleat/glyphhanger&quot;&gt;glyphanger&lt;/a&gt;, qui permet de ne conserver que les caractères réellement utiles à ce blog, le fichier qui à l&#39;origine pèse 44 Ko ne fait plus que &lt;strong&gt;15 Ko (2,8 %)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Une photo de ma tête, qui communique avec élégance une forme de sympathie professionnelle rendant irrésistible l&#39;envie de me contacter à de riches recruteurs. Elle pèse &lt;strong&gt;4,5 Ko (0,8 %)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;La capture d&#39;écran du site HTTP Archive qui introduit l&#39;article. Elle est affichée avec une largeur de &lt;code&gt;780px&lt;/code&gt;, mais si votre écran a une haute densité de pixels, le fichier servi est deux fois plus grand (&lt;code&gt;1560px&lt;/code&gt;) pour le plaisir des yeux. Le format &lt;code&gt;.avif&lt;/code&gt;, désormais très bien supporté, permet de limiter son poids à &lt;strong&gt;22 Ko (4,1 %)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Un favicon, le petit truc bleu dans l&#39;onglet du navigateur, là-haut. C&#39;est important. Il représente &lt;strong&gt;5 Ko (0,9 %)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;postAside&quot;&gt;Le nombre de requêtes compte aussi énormément dans la performance d&#39;un site. Aujourd&#39;hui, la médiane est de 76. Cette page en génère 31 (l&#39;inclusion de CodePen déclenche une bonne moitié d&#39;entre elles…)&lt;/div&gt;
&lt;h2 id=&quot;seulement-84-ko&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#seulement-84-ko&quot;&gt;Seulement 84 Ko ???&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ça ne va pas du tout. Ce post est déjà d&#39;une longueur respectable, et pourtant, nous n&#39;avons atteint que &lt;strong&gt;84 Ko&lt;/strong&gt;. 30 fois moins que la médiane. C&#39;est intolérable.&lt;/p&gt;
&lt;p&gt;Dois-je rappeler que l&#39;objectif est &lt;strong&gt;532 Ko&lt;/strong&gt; ? Il va falloir se ressaisir. Ajoutons donc d&#39;autres éléments à notre page.&lt;/p&gt;
&lt;p&gt;Ci-dessous, voici un web component qui me permet de présenter les compatibilités de différentes fonctionnalités. Voici par exemple celle pour le format &lt;code&gt;.avif&lt;/code&gt; évoqué précédemment.&lt;/p&gt;
&lt;div class=&quot;baseline&quot; lang=&quot;en&quot;&gt;
    &lt;baseline-status featureId=&quot;avif&quot;&gt;&lt;/baseline-status&gt;
  &lt;/div&gt;
&lt;p&gt;Son inclusion et l&#39;appel API associé représentent &lt;strong&gt;24 Ko (4,5 %)&lt;/strong&gt;. On continue !&lt;/p&gt;
&lt;p&gt;Une iframe CodePen ? Ce sera une des ressources les plus coûteuses de cette page avec un poids d&#39;environ &lt;strong&gt;85 Ko (6,3 %)&lt;/strong&gt;. Cela reste raisonnable compte tenu du service apporté.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;zYBWzdo&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/zYBWzdo&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Une vidéo ? Puisqu&#39;il le faut. &lt;strong&gt;79 Ko (14,5 %)&lt;/strong&gt;.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/lazy.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : un scroll vertical de la page, au fur et à mesure duquel les images sont chargées progressivement.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Un extrait de code ? En réalité, il ne rajoute que son poids en caractères. En effet, la coloration syntaxique est faite lors du pré-rendu côté serveur. Et les styles sont déjà dans l&#39;unique fichier CSS inclus.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; images &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;src/img/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;fileSlug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;.jpg&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;widths&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;350&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;formats&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;avif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;webp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;jpeg&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;outputDir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_site/img&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;D&#39;autres composants peuvent facilement être mobilisés « gratuitement », puisqu&#39;il ne s&#39;agit que du CSS déjà chargé. Allons-y, histoire de représenter l&#39;ensemble des contenus présents sur le blog.&lt;/p&gt;
&lt;p&gt;Une citation ?&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Un poids de page élevé affecte disproportionnellement les personnes qui ne peuvent pas acheter des appareils haut de gamme et avoir accès à une connexion rapide et permettant une forte consommation de données.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;&lt;cite&gt;&lt;a href=&quot;https://almanac.httparchive.org/en/2024/page-weight#page-weight-is-an-accessibility-issue&quot;&gt;Web Almanac 2024 (en anglais)&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Un tableau ? Voici la répartition du poids des ressources sur une page web (les vidéos sont exclues car beaucoup de pages en sont dénuées).&lt;/p&gt;
&lt;table&gt;
  &lt;caption&gt;Répartition du poids des ressources sur une page web (vidéos exclues)&lt;/caption&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;col&quot;&gt;Type de ressource&lt;/th&gt;
    &lt;th scope=&quot;col&quot;&gt;% du total&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Images 🖼️&lt;/td&gt;
    &lt;td&gt;39,9 %&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;JavaScript ⚡&lt;/td&gt;
    &lt;td&gt;23,2 %&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Fonts 🔤&lt;/td&gt;
    &lt;td&gt;5 %&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;CSS 💄&lt;/td&gt;
    &lt;td&gt;3 %&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;HTML ✍️&lt;/td&gt;
    &lt;td&gt;0,7 %&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Source : &lt;a href=&quot;https://almanac.httparchive.org/en/2024/page-weight#content-type-and-file-formats&quot;&gt;Web Almanac 2024&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;ca-devient-lourd...-mais-pas-assez&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#ca-devient-lourd...-mais-pas-assez&quot;&gt;Ça devient lourd… mais pas assez&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Me voilà rendu à seulement &lt;strong&gt;272 Ko&lt;/strong&gt; malgré tous mes efforts, et tous les types de contenus présents sur le blog sont déjà représentés. Je me demande si ce post était une bonne idée.&lt;/p&gt;
&lt;p&gt;Pas le choix, on va jusqu&#39;au bout : il va falloir remplir !&lt;/p&gt;
&lt;p&gt;Une autre image ? Celle-ci rajoute &lt;strong&gt;11 Ko (2,1%)&lt;/strong&gt;.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/Wbbr4RUs3L-390.avif 390w, https://bastiencalou.fr/img/Wbbr4RUs3L-780.avif 780w, https://bastiencalou.fr/img/Wbbr4RUs3L-1425.avif 1425w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/Wbbr4RUs3L-390.webp 390w, https://bastiencalou.fr/img/Wbbr4RUs3L-780.webp 780w, https://bastiencalou.fr/img/Wbbr4RUs3L-1425.webp 1425w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/Wbbr4RUs3L-390.webp&quot; alt=&quot;Une démonstration de la librairie React Joyride&quot; width=&quot;713&quot; height=&quot;393&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Un autre CodePen, peut-être ? Beaucoup des ressources nécessaires étant déjà chargées par la première iframe, il n&#39;en coûtera que &lt;strong&gt;18 Ko (3,6%)&lt;/strong&gt;.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;zYvJJzY&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/zYvJJzY&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;div class=&quot;postAside&quot;&gt;
Note : mesurer le poids d&#39;une page n&#39;est pas une science exacte. Utiliser l&#39;option « désactiver le cache » de l&#39;inspecteur réseau peut être trompeur car certaines sources seront alors chargées (et comptabilisées) deux fois, comme CodePen sur cette page. Pour mes tests, j&#39;utilise Firefox, sans extension. Dans les paramètres, j&#39;efface les « fichiers et pages en cache temporaire ». Puis je charge la page avec l&#39;onglet réseau ouvert, sans cocher « désactiver le cache ». Après l&#39;avoir parcourue en entier, je relève son poids transféré.
&lt;/div&gt;
&lt;p&gt;On dira que ma vidéo était trop courte. En voici une autre ! Celle-ci est plus longue et est accompagnée de son. Là, ça devient sérieux : &lt;strong&gt;224 Ko (42%)&lt;/strong&gt;. Mais n&#39;oublions pas qu&#39;une grande partie des sites ne contient pas de vidéo.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/blobby.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : démonstration du jeu Blobby Zombie. Lorsqu&#39;un ennemi est touché, la musique progresse en intensité.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Ça y est, nous y sommes parvenus… Cette page fait enfin &lt;strong&gt;20% du poids médian actuel&lt;/strong&gt;. Pas mal, non ?&lt;/p&gt;
&lt;h2 id=&quot;ce-que-ne-contient-pas-cette-page&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#ce-que-ne-contient-pas-cette-page&quot;&gt;Ce que ne contient pas cette page&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Si cette page a un poids raisonnable, c&#39;est parce que ce blog fait de son mieux pour éviter quelques « gouffres » de ressources, qui sont malheureusement communs sur bon nombre de sites :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iframe&lt;/code&gt; très gourmandes comme celle de Youtube ;&lt;/li&gt;
&lt;li&gt;images mal optimisées ;&lt;/li&gt;
&lt;li&gt;multiples typographies et variantes (ici, il n&#39;y a qu&#39;un seul fichier &lt;code&gt;.woff2&lt;/code&gt;) ;&lt;/li&gt;
&lt;li&gt;gros framework JavaScript des familles ;&lt;/li&gt;
&lt;li&gt;vidéos longues et HD ;&lt;/li&gt;
&lt;li&gt;scripts de tracking ;&lt;/li&gt;
&lt;li&gt;widgets de réseaux sociaux ;&lt;/li&gt;
&lt;li&gt;immense librairie d&#39;icônes utilisée à 0,1 %…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Souvent, une seule de ces erreurs suffit à plomber le poids d&#39;un projet entier. Mais tant que vous gardez un œil vigilant sur ce que mobilise votre page, je pense en avoir fait la démonstration : &lt;strong&gt;vous avez de la marge&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;idealiste-pas-sur.&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/cette-page-est-80-pourcents-moins-lourde-que-la-mediane-des-pages-web/#idealiste-pas-sur.&quot;&gt;Idéaliste ? Pas sûr.&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La légèreté n&#39;est pas réservée aux simples blogs :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La page d&#39;accueil de &lt;a href=&quot;https://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Accueil_principal&quot;&gt;Wikipédia&lt;/a&gt; pèse &lt;strong&gt;355 Ko&lt;/strong&gt;, soit 14% de la médiane.&lt;/li&gt;
&lt;li&gt;La page d&#39;accueil de &lt;a href=&quot;https://maisoncalme.fr/&quot;&gt;Maison Calme&lt;/a&gt;, que j&#39;ai réalisé pour un studio de yoga, pèse &lt;strong&gt;200 Ko&lt;/strong&gt;. 8% de la médiane.&lt;/li&gt;
&lt;li&gt;La page d&#39;accueil de &lt;a href=&quot;https://lowtechlab.org/fr&quot;&gt;Low-tech Lab&lt;/a&gt; pèse &lt;strong&gt;157 Ko&lt;/strong&gt;. 6% de la médiane.&lt;/li&gt;
&lt;li&gt;N&#39;oublions pas le fameux &lt;a href=&quot;https://news.ycombinator.com/news&quot;&gt;Hacker News&lt;/a&gt; et ses &lt;strong&gt;12 Ko&lt;/strong&gt;. 0,5% de la médiane.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les exemples sont nombreux. Malheureusement, le poids standard d&#39;un site classique est aujourd&#39;hui… comment être poli ? &lt;em&gt;Embarrassant&lt;/em&gt;. La complexité intrinsèque du projet suffit rarement à justifier le manque flagrant d&#39;optimisation des ressources et de &lt;strong&gt;choix de sobriété&lt;/strong&gt; à leur sujet.&lt;/p&gt;
&lt;p&gt;Le web est de plus en plus lourd, mais ce n&#39;est pas une fatalité. Vous choisissez ce qui rentre dans votre page.&lt;/p&gt;
&lt;p&gt;En attendant, vous pouvez faire grimper de quelques octets le poids de celle-ci en laissant un commentaire. Mais je ne pense pas que cela puisse rendre le titre de cet article mensonger : la médiane ne va-t-elle pas continuer à monter, elle aussi ?&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Comment j&#39;ai cassé la prod avec un innocent sélecteur CSS</title>
		<link href="https://bastiencalou.fr/comment-j-ai-casse-la-prod-avec-un-innocent-selecteur-css/"/>
		<updated>2024-11-12T00:00:00Z</updated>
		<id>https://bastiencalou.fr/comment-j-ai-casse-la-prod-avec-un-innocent-selecteur-css/</id>
		<content type="html">&lt;p&gt;On passe toutes et tous par là, non ? Transformer une application en page blanche, en prod de préférence ? Non ? Ça viendra, je vous le souhaite. Ce sont de belles sensations grâce auxquelles on vit intensément l&#39;instant présent.&lt;/p&gt;
&lt;p&gt;Je vous raconte.&lt;/p&gt;
&lt;h2 id=&quot;css-est-gentil&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/comment-j-ai-casse-la-prod-avec-un-innocent-selecteur-css/#css-est-gentil&quot;&gt;CSS est gentil&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;CSS a ceci de merveilleux qu&#39;il « n&#39;échoue pas ». Prenez ce sélecteur, par exemple :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;form:has(textarea)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ...
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Grâce à &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:has&quot;&gt;la pseudo-classe moderne :has&lt;/a&gt;, il cible les éléments &lt;code&gt;form&lt;/code&gt; qui contiennent un élément &lt;code&gt;textarea&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;baseline&quot; lang=&quot;en&quot;&gt;
    &lt;baseline-status featureId=&quot;has&quot;&gt;&lt;/baseline-status&gt;
  &lt;/div&gt;
&lt;p&gt;Aujourd&#39;hui, &lt;code&gt;:has&lt;/code&gt; est bien supporté par la plupart des navigateurs. Si un vieux navigateur tente d&#39;interpréter ce sélecteur, il ne le &lt;strong&gt;comprendra pas et l&#39;ignorera&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ce mécanisme est essentiel à l&#39;adoption rapide des nouvelles fonctionnalités CSS. À moins que les styles à appliquer ne soient absolument critiques, on peut admettre qu&#39;une petite partie (en décroissance) des navigateurs n&#39;en bénéficient pas. Tant que la page est lisible et utilisable, ce n&#39;est généralement pas un problème.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;
Il en va de même pour HTML : une balise moderne telle que &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt; sera interprétée comme une simple &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; sans signification par des navigateurs plus anciens. La sémantique peut être dégradée, et ce n&#39;est pas anodin, mais c&#39;est très différent que de risquer une page blanche...
&lt;/div&gt;
&lt;h2 id=&quot;mon-erreur-:-penser-que-document.queryselector()-serait-aussi-sympa...&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/comment-j-ai-casse-la-prod-avec-un-innocent-selecteur-css/#mon-erreur-:-penser-que-document.queryselector()-serait-aussi-sympa...&quot;&gt;Mon erreur : penser que &lt;code&gt;document.querySelector()&lt;/code&gt; serait aussi sympa...&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Tout change quand on entre dans le domaine de JavaScript. Chez lui, ça ne rigole pas, et il n&#39;est pas question « d&#39;échouer silencieusement ».&lt;/p&gt;
&lt;p&gt;Le code suivant présente une faille potentielle :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; $form &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;form:has(textarea)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

$form&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si un élément correspond a sélecteur CSS fourni, &lt;code&gt;$form&lt;/code&gt; contiendra un objet de type &lt;code&gt;Element&lt;/code&gt;, sur lequel on pourra agir.&lt;/p&gt;
&lt;p&gt;Mais si l&#39;élément n&#39;est pas trouvé, &lt;code&gt;$form&lt;/code&gt; contiendra &lt;code&gt;null&lt;/code&gt;. Et &lt;code&gt;addEventListener&lt;/code&gt; sur &lt;code&gt;null&lt;/code&gt;, ça fait boum. Et notre JS est joliment planté.&lt;/p&gt;
&lt;p&gt;C&#39;est simple à contourner : à moins d&#39;avoir la certitude de la présence de l&#39;élément, mieux vaut la vérifier avant de continuer, grâce à une condition :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; $form &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;form:has(textarea)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;$form&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// C&#39;est pas null, hein ?&lt;/span&gt;
  $form&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ça, c&#39;est la partie simple. Mon erreur, c&#39;était de présumer du retour du sélecteur suivant. Lisez le bien :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; $form &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;form:wow(textarea)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Non, la pseudo-classe &lt;code&gt;:wow&lt;/code&gt; n&#39;existe pas, vous n&#39;avez pas raté un chapitre de la folle histoire de CSS. Mais alors, que contiendra la variable &lt;code&gt;$form&lt;/code&gt; ? Sera-t-elle &lt;code&gt;null&lt;/code&gt;, de nouveau ?&lt;/p&gt;
&lt;p&gt;Eh bien non : &lt;code&gt;$form&lt;/code&gt; ne contiendra rien du tout. À la place, &lt;code&gt;document.querySelector()&lt;/code&gt; va exploser en plein vol et nous jeter à la figure une erreur fatale :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;Uncaught DOMException&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
Document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;querySelector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;form:wow(textarea)&#39;&lt;/span&gt; is not a valid selector&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;:wow&lt;/code&gt; n&#39;existe pas, mais c&#39;est aussi ce qui se passera sur un vieux navigateur qui ne comprend pas &lt;code&gt;:has&lt;/code&gt; : il déclenchera une erreur.&lt;/p&gt;
&lt;p&gt;Et cette erreur, si on la catche pas, elle va tout bonnement planter notre JS et tout ce qui va avec. Et si ce qui va avec, c&#39;est une &lt;em&gt;Single Page App&lt;/em&gt; générée en JS, le résultat sera une belle page blanche !&lt;/p&gt;
&lt;h2 id=&quot;et-maintenant-cassons-la-prod&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/comment-j-ai-casse-la-prod-avec-un-innocent-selecteur-css/#et-maintenant-cassons-la-prod&quot;&gt;Et maintenant, cassons la prod&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Conditionné que j&#39;étais à penser que CSS ne me trahirait pas, j&#39;ai passé un sélecteur contenant &lt;code&gt;:has&lt;/code&gt; à la librairie &lt;a href=&quot;https://react-joyride.com/&quot;&gt;React Joyride&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le but de cette librairie est de générer un « parcours pas à pas » de bienvenue. Pour cela, il faut lui passer les sélecteurs qui lui permettront de cibler les éléments à mettre en valeur.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/Wbbr4RUs3L-390.avif 390w, https://bastiencalou.fr/img/Wbbr4RUs3L-780.avif 780w, https://bastiencalou.fr/img/Wbbr4RUs3L-1425.avif 1425w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/Wbbr4RUs3L-390.webp 390w, https://bastiencalou.fr/img/Wbbr4RUs3L-780.webp 780w, https://bastiencalou.fr/img/Wbbr4RUs3L-1425.webp 1425w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/Wbbr4RUs3L-390.webp&quot; alt=&quot;Une page d&#39;accueil par dessus laquelle une boîte d&#39;information met en valeur un élément spécifique&quot; width=&quot;713&quot; height=&quot;393&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      React Joyride en action.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Confiant dans l&#39;usage de &lt;code&gt;:has&lt;/code&gt; (qui m&#39;évitait d&#39;avoir à ajouter une classe conditionnelle à un élément), je pousse mon code. Le code passe la recette sans problème et atterit en production de ce site à quelques milliers de visites par jour 🙃&lt;/p&gt;
&lt;p&gt;Quelques jours plus tard, surprise ! Quelques personnes semblent se plaindre d&#39;atterir sur une page blanche... Leur point commun ? Utiliser une version de Safari dans laquelle &lt;code&gt;:has&lt;/code&gt; n&#39;était pas encore implémentée...&lt;/p&gt;
&lt;p&gt;Je transpire un peu en réalisant mon erreur et pousse aussitôt un hotfix pour ne plus utiliser &lt;code&gt;:has&lt;/code&gt;... Je comprends alors que la librairie est ma complice dans ce crime involontaire. Les erreurs de &lt;code&gt;querySelector&lt;/code&gt; ne sont pas catchées.&lt;/p&gt;
&lt;p&gt;Ou comment une fonctionnalité « annexe » de la plateforme devient soudain capable d&#39;en crasher l&#39;intégralité.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/gilbarbara/react-joyride/issues/1035&quot;&gt;Un ticket Github&lt;/a&gt; et quelques temps plus tard, l&#39;affaire est résolue dans le code source de la librairie. Je peux de nouveau utiliser des sélecteurs modernes tels que &lt;code&gt;:has&lt;/code&gt; sans risquer l&#39;intégrité de la page.&lt;/p&gt;
&lt;p&gt;Schématiquement, si l&#39;on revient à mon exemple de base, c&#39;est aussi simple que ça :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; $form &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;form:has(textarea)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;$form&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    $form&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;morale-de-l&#39;histoire&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/comment-j-ai-casse-la-prod-avec-un-innocent-selecteur-css/#morale-de-l&#39;histoire&quot;&gt;Morale de l&#39;histoire&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Deux erreurs ont été commises dans cette affaire :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de la part de la librairie, qui ne catchait pas les erreurs (quand ce genre de choses vous arrive, faites un ticket ! à défaut de contribuer directement, vous aiderez les autrices et auteurs) ;&lt;/li&gt;
&lt;li&gt;de ma part : j&#39;étais tellement convaincu de la résilience de CSS que j&#39;ai oublié que je sortais du cadre strict de CSS et que je me trouvais en réalité en territoire JavaScript.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À l&#39;avenir, une précaution simple : tester avec un sélecteur « impossible » tel que &lt;code&gt;:uhoh&lt;/code&gt; pour m&#39;assurer de la bonne prise en charge des cas invalides...&lt;/p&gt;
&lt;p&gt;Cet article aurait pu être une simple phrase (mais où serait le plaisir ?) : &lt;strong&gt;CSS échoue silencieusement. &lt;code&gt;document.querySelector()&lt;/code&gt;, non !&lt;/strong&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Ciao, X !</title>
		<link href="https://bastiencalou.fr/ciao-x/"/>
		<updated>2024-10-22T00:00:00Z</updated>
		<id>https://bastiencalou.fr/ciao-x/</id>
		<content type="html">&lt;p&gt;Comme bien d&#39;autres avant moi, je supprime mon compte Twitter / X (et succombe à la tentation d&#39;en faire un post, désolé !).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Professionnellement, ce n&#39;est pas anodin&lt;/strong&gt;. Une dizaine d&#39;années de partage de veille quotidienne, des milliers de tweets... X ne me donne pas directement du travail, mais il est fort possible que la façade que mon profil constitue y contribue un tout petit peu.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moralement, c&#39;est une évidence&lt;/strong&gt;. Bien sûr, chacune et chacun choisira où mettre la limite de l&#39;acceptable. En ce qui me concerne, elle est allègrement franchie : Elon Musk semble déterminé à faire de ce monde un endroit chaque jour un peu plus délétère. Faut-il attendre de savoir si tous ses efforts pour ramener Donald Trump à la Maison-Blanche vont payer pour décider de partir ?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mentalement, c&#39;est une nécessité&lt;/strong&gt;. On ne se bat pas contre un algorithme conçu pour vous rendre accro. Peu importe les stratégies testées au fil des années, mon flux X est, loin de son objectif de veille technique, gangréné par des contenus violents, racistes ou débilitants, qui semblent dépeindre une société à feu et à sang. Une sorte de fin du monde en scroll vertical infini.&lt;/p&gt;
&lt;p&gt;Alors, pour paraphraser : on se déconnecte et on se casse.&lt;/p&gt;
&lt;h2 id=&quot;la-suite-ca-se-passe-ou&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/ciao-x/#la-suite-ca-se-passe-ou&quot;&gt;La suite, ça se passe où ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Depuis presque deux ans, je partage ma veille sur &lt;a href=&quot;https://piaille.fr/@bcalou&quot;&gt;mon profil Mastodon&lt;/a&gt;. Je ne vous en fait pas la pub, mais si ce post convainc ne serait-ce qu&#39;une personne de m&#39;y rejoindre, il n&#39;aura pas été en vain.&lt;/p&gt;
&lt;p&gt;Je relèverai un seul point : avec pourtant quatre fois moins d&#39;abonnés sur Mastodon que sur X, j&#39;y ai beaucoup, beaucoup plus d&#39;interactions ! Face à X, qui ressemble de plus en plus à une foire d&#39;empoigne remplie de vide, Mastodon est incroyablement rafraichissant.&lt;/p&gt;
&lt;p&gt;Enfin, il y a &lt;a href=&quot;https://bastiencalou.fr/feed/feed.xml&quot;&gt;ce bon vieux flux RSS&lt;/a&gt;. Personnellement, c&#39;est grâce aux flux RSS de quelques dizaines de blogs ou sites spécialisés que je fais le principal de ma veille. Qu&#39;est ce que c&#39;est bien, de lire des contenus intelligents sur une plateforme qui n&#39;est faite que pour ça... Comme lecteur, je recommande volontiers &lt;a href=&quot;https://feedly.com/&quot;&gt;Feedly&lt;/a&gt;, à défaut d&#39;en avoir testé d&#39;autres.&lt;/p&gt;
&lt;p&gt;Cette parenthèse Twitteresque de 13 années étant fermée, je vous dis à bientôt pour de nouveaux articles. Des vrais, cette fois-ci ;)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>De l&#39;aléatoire en CSS, c&#39;est possible ! Enfin, presque...</title>
		<link href="https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/"/>
		<updated>2024-10-14T00:00:00Z</updated>
		<id>https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/</id>
		<content type="html">&lt;p&gt;Pour la sortie de ce nouveau blog, il me fallait mettre en place un effet visuel renversant, qui impressionnerait la galerie et montrerait toute l&#39;étendue de mes capacités.&lt;/p&gt;
&lt;p&gt;Comme je n&#39;avais pas le temps de faire cela, j&#39;ai codé un effet rigolo de survol : lorsque la souris est passée sur ma photo, deux émojis parmi une centaine soigneusement sélectionnés apparaissent aléatoirement.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/photo.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : la souris survole ma photo. À chaque survol, deux émojis aléatoires recouvrent mes yeux.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Du grand art, je vous dis.&lt;/p&gt;
&lt;p&gt;Cela a soulevé une question intéressante : quelle serait la meilleure méthode pour sélectionner l&#39;émoji aléatoirement ? CSS suffirait-t-il ?&lt;/p&gt;
&lt;h2 id=&quot;css-:-la-roulette-invisible&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/#css-:-la-roulette-invisible&quot;&gt;CSS : la roulette invisible&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La roulette invisible, c&#39;est le petit nom que je donne à cette technique que je n&#39;ai pas inventée, mais qui est intéressante. Je vous explique.&lt;/p&gt;
&lt;p&gt;Tout commence avec un pseudo-élément vide.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Appliquons à ce pseudo-élément une animation &lt;code&gt;emojis&lt;/code&gt;. Son but ? Changer le contenu de la propriété &lt;code&gt;content&lt;/code&gt; pour y injecter nos émojis. Pour l&#39;instant, trois suffiront.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; emojis 1s linear infinite&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; emojis&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💥&quot;&lt;/span&gt; / &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token selector&quot;&gt;50%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐸&quot;&lt;/span&gt; / &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎉&quot;&lt;/span&gt; / &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La syntaxe &lt;code&gt;content: &amp;quot;🎉&amp;quot; / &amp;quot;&amp;quot;&lt;/code&gt; permet de définir, dans la seconde string, le texte alternatif pour ce pseudo-élément, qui pourra être lu par les technologies d&#39;assistance. Quand on utilise un pseudo-élément à des fins décoratives, il est donc recommandé d&#39;utiliser une chaîne vide pour éviter que le contenu de l&#39;émoji ne soit interprété, par exemple par un lecteur d&#39;écran.&lt;/p&gt;
&lt;div class=&quot;baseline&quot; lang=&quot;en&quot;&gt;
    &lt;baseline-status featureId=&quot;alt-text-generated-content&quot;&gt;&lt;/baseline-status&gt;
  &lt;/div&gt;
&lt;p&gt;Et voici le résultat :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;eYqYMJg&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/eYqYMJg&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Maintenant, la même chose, mais avec 100 émojis ! Bon, on s&#39;amuse bien mais on va utiliser une &lt;a href=&quot;https://sass-lang.com/documentation/at-rules/control/for/&quot;&gt;boucle SASS&lt;/a&gt;, on a pas que ça à faire...&lt;/p&gt;
&lt;pre class=&quot;language-scss&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$emojis&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💥&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🫀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👓&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐸&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👑&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐰&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐼&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐤&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐱&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🦊&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐷&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🙈&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐝&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐌&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐞&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐠&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐢&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐫&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🦔&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🦚&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🌹&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🌼&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⭐️&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🔥&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🌈&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💧&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍉&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍓&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍑&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🥝&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍆&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🥦&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🥨&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🧀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍔&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍕&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍙&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎂&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍭&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍿&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍩&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍺&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🍹&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🏀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🥋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🏆&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎟&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎭&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎨&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎬&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎹&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🥁&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎷&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎸&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🪗&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎲&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎯&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎰&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎳&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🚨&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🚇&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🚀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🛸&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🛟&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🗺&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⛱&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🌋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💻&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🖨&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💾&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🕹&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💿&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📼&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📸&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📽&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📠&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📺&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🧭&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⏰&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;⏳&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💡&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💵&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💰&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💎&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🔮&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🧬&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🧻&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎁&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎈&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🎉&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🪩&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📫&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;📚&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🔎&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🩵&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💯&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🔔&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👁‍🗨&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; emojis&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;@for&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; 1 &lt;span class=&quot;token keyword&quot;&gt;through&lt;/span&gt; list.&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$emojis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    #&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;100% &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;list.&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$emojis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; list.&lt;span class=&quot;token function&quot;&gt;nth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$emojis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et quand 100 émojis défilent en quelques secondes seulement, eh bien ça donne ça :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;xxvxYNL&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/xxvxYNL&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Le plus dur est fait. L&#39;astuce réside dans le fait d&#39;arrêter cette roulette infernale au survol.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div:hover::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation-play-state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; paused&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;postAside&quot;&gt;
L&#39;élément concerné sur le site étant un lien, je peux aussi appliquer l&#39;effet lorsque ce dernier obtient le focus. Une personne naviguant au clavier « profitera » ainsi de l&#39;effet.
&lt;/div&gt;
&lt;p&gt;Survolez l&#39;élément : l&#39;animation est arrêtée net, et un emoji est ainsi « sélectionné ».&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;JjgjLWL&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/JjgjLWL&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Vous l&#39;aurez compris, l&#39;aléatoire ici réside dans l&#39;action de survol elle-même, et plus précisément dans son timing.&lt;/p&gt;
&lt;p&gt;La touche finale, c&#39;est bien sûr de cacher le pseudo-élément jusqu&#39;à ce que le survol ait lieu :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;div:hover::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation-play-state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; paused&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notre roulette invisible est prête !&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;mdNdxwg&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/mdNdxwg&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;En appliquant les mêmes règles au pseudo-élément &lt;code&gt;after&lt;/code&gt; et quelques tests de positionnement plus tard, le résultat est là.&lt;/p&gt;
&lt;h2 id=&quot;invisible...-et-pourtant-elle-tourne&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/#invisible...-et-pourtant-elle-tourne&quot;&gt;Invisible... et pourtant, elle tourne&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Même si je trouve cette technique intéressante à partager, j&#39;étais un peu gêné une fois la mise en place effectuée.&lt;/p&gt;
&lt;p&gt;C&#39;est qu&#39;il y a quelque chose d&#39;un peu contre-nature à changer de très nombreuses fois par seconde un contenu qu&#39;on ne voit pas, non ?&lt;/p&gt;
&lt;p&gt;Faisons une analyse de performance de la page, sur une minute, pour bien voir.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/WLRGLQ2hoJ-390.avif 390w, https://bastiencalou.fr/img/WLRGLQ2hoJ-780.avif 780w, https://bastiencalou.fr/img/WLRGLQ2hoJ-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/WLRGLQ2hoJ-390.webp 390w, https://bastiencalou.fr/img/WLRGLQ2hoJ-780.webp 780w, https://bastiencalou.fr/img/WLRGLQ2hoJ-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/WLRGLQ2hoJ-390.webp&quot; alt=&quot;Analyse de performance de la démo. On y voit d&#39;innombrables barres verticales symbolisant les opérations.&quot; width=&quot;780&quot; height=&quot;350&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Chaque barre verticale est une opération sollicitant la carte graphique.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Le navigateur est au repos 99% du temps. Pas la fin du monde, donc. Mais ces milliers de petites barres vertes, ce sont des milliers d&#39;opérations parfaitement inutiles, exécutées en permanence. Sur le principe, ça me gêne !&lt;/p&gt;
&lt;p&gt;C&#39;est un peu l&#39;équivalent de préparer une pizza, de la jeter directement à la poubelle puis d&#39;en préparer une autre, et ainsi de suite jusqu&#39;à ce qu&#39;un client ait enfin envie d&#39;en profiter.&lt;/p&gt;
&lt;p&gt;Alors, pour alléger un peu cette technique de gros bourrin, il y a une piste. Au lieu d&#39;animer la propriété &lt;code&gt;content&lt;/code&gt;, nous pouvons animer le contenu d&#39;une variable CSS &lt;code&gt;--emoji&lt;/code&gt;, et nous en servir pour générer le &lt;code&gt;content&lt;/code&gt; uniquement lorsque l&#39;élément est survolé.&lt;/p&gt;
&lt;pre class=&quot;language-scss&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div:hover::before &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation-play-state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; paused&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--emoji&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; emojis&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;@for&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; 1 &lt;span class=&quot;token keyword&quot;&gt;through&lt;/span&gt; list.&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$emojis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    #&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;100% &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;list.&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$emojis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;--emoji&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#{list.nth($emojis, $i)}&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Résultat ?&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/uBnrl9kJ3_-390.avif 390w, https://bastiencalou.fr/img/uBnrl9kJ3_-780.avif 780w, https://bastiencalou.fr/img/uBnrl9kJ3_-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/uBnrl9kJ3_-390.webp 390w, https://bastiencalou.fr/img/uBnrl9kJ3_-780.webp 780w, https://bastiencalou.fr/img/uBnrl9kJ3_-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/uBnrl9kJ3_-390.webp&quot; alt=&quot;Analyse de performance de la démo ajustée. Il y a moins de barres verticales.&quot; width=&quot;780&quot; height=&quot;350&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      La carte graphique est beaucoup moins sollicitée, mais il y a toujours énormément d&#39;opérations.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Côté performance, c&#39;est maintenant à 99,6% du temps que le navigateur est au repos. Beaucoup mieux !&lt;/p&gt;
&lt;p&gt;Mais, fondamentalement, cela revient au même : le navigateur doit suivre l&#39;état de cette variable en permanence, provoquant des milliers d&#39;opérations superflues. J&#39;aimerais savoir s&#39;il est possible d&#39;obtenir une version « propre » de cette approche. Mais j&#39;en doute.&lt;/p&gt;
&lt;h2 id=&quot;la-solution-raisonnable&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/#la-solution-raisonnable&quot;&gt;La solution raisonnable&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Mon cerveau est câblé depuis longtemps pour commencer par envisager une solution purement CSS à ce genre de problème. Même quand ça ne marche pas, je découvre toujours quelque chose.&lt;/p&gt;
&lt;p&gt;Mais ici, c&#39;est bien JavaScript qui nous apporte une solution simple et performante. Le code est sans grande surprise, en voici la partie principale :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; emojis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;💥&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🫀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👓&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐸&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👑&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐰&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐼&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setRandomEmoji&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  $target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setProperty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;--emoji&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;emojis&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; emojis&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; / &quot;&quot;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

$target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mouseenter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setRandomEmoji&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plus d&#39;opérations inutiles !&lt;/p&gt;
&lt;p&gt;Certes, CSS reste à privilégier lorsque c&#39;est possible. Mais il ne faut surtout pas rester bloqué sur un langage ou un autre lorsqu&#39;il devient évident qu&#39;une meilleure solution est à chercher ailleurs.&lt;/p&gt;
&lt;h2 id=&quot;css-n&#39;a-pas-dit-son-dernier-mot&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/#css-n&#39;a-pas-dit-son-dernier-mot&quot;&gt;CSS n&#39;a pas dit son dernier mot&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Et &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Houdini_APIs&quot;&gt;Houdini&lt;/a&gt;, alors ? Cette API native permet de définir, en JavaScript, des algorithmes de rendus invoquables par la suite en CSS.&lt;/p&gt;
&lt;p&gt;Et effectivement, dans ce contexte-ci, l&#39;aléatoire est possible !&lt;/p&gt;
&lt;p&gt;Voici la définition d&#39;une règle &lt;code&gt;circle&lt;/code&gt;, qui va générer aléatoirement un cercle rouge ou vert.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;registerPaint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;circle&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; geom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; geom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; geom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;red&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;green&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On l&#39;utilise ainsi :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;circle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sympathique, car on laisse le navigateur s&#39;occuper de la logique de survol, et les possibilités ouvertes par Houdini sont bien plus vastes que mon simple exemple.&lt;/p&gt;
&lt;div class=&quot;baseline&quot; lang=&quot;en&quot;&gt;
    &lt;baseline-status featureId=&quot;paint&quot;&gt;&lt;/baseline-status&gt;
  &lt;/div&gt;
&lt;p&gt;Malheureusement, ni Firefox ni Safari ne supportent cette API à l&#39;heure actuelle. Si vous êtes sur un navigateur compatible, vous pourrez voir le résultat en survolant le composant ci-dessous :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;QWeWmop&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/QWeWmop&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;div class=&quot;postAside&quot;&gt;
Cela doit faire 5 ans que j&#39;ai entendu parler d&#39;Houdini, mais j&#39;ai l&#39;impression que le projet &lt;a href=&quot;https://ishoudinireadyyet.com/&quot;&gt;peine à se concrétiser pleinement&lt;/a&gt;. En tout cas, il semble avancer lentement. Il faut dire qu&#39;un travail énorme a été effectué ces dernières années sur des aspects bien plus fondamentaux de CSS !
&lt;/div&gt;
&lt;p&gt;Pour ma petite animation, le support limité d&#39;Houdini passe encore : c&#39;est une fonctionnalité « bonus » dont personne ne souffrira de l&#39;absence.&lt;/p&gt;
&lt;p&gt;Bien plus embêtant, impossible de trouver comment rendre du texte, et encore moins un émoji. On dirait bien que cela est impossible...&lt;/p&gt;
&lt;h2 id=&quot;random-item()-en-css-:-c&#39;est-prevu-!&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/#random-item()-en-css-:-c&#39;est-prevu-!&quot;&gt;&lt;code&gt;random-item()&lt;/code&gt; en CSS : c&#39;est prévu !&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les choses sont bien faites. Alors que je réfléchissais à cet article, je suis tombé sur &lt;a href=&quot;https://alvaromontoro.com/blog/68062/new-values-and-functions-in-CSS&quot;&gt;cet article d&#39;Alvaro Montoro&lt;/a&gt;, qui détaille les nouveautés à venir concernant les valeurs et les fonctions en CSS (le niveau 5 du module &lt;i&gt;Values and Units&lt;/i&gt;).&lt;/p&gt;
&lt;p&gt;Et vous l&#39;avez compris : parmi tout un tas de fonctionnalités très prometteuses se trouve la tant fantasmée fonction &lt;code&gt;random-item()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Voici à quoi pourrait ressembler mon code mis à jour :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div:hover:before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;random-item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💥&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;💋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🫀&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👓&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;🐸&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;👑&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;postAside&quot;&gt;
Si j&#39;ai bien compris, le &lt;code&gt;--x&lt;/code&gt; servira à « identifier » le générateur. Tous les appels à &lt;code&gt;random-item()&lt;/code&gt; possédant le même identifiant et la même liste génèreront la même valeur sur la page.
&lt;/div&gt;
&lt;p&gt;Plus simplement, la fonction &lt;code&gt;random()&lt;/code&gt; permettra d&#39;obtenir une valeur aléatoire entre deux bornes :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0vw&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 100vw&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Encore une très bonne nouvelle pour CSS, donc.&lt;/p&gt;
&lt;p&gt;Quand cela sera-t-il disponible ? Pour nous autres mortels, cela aussi relève du domaine de l&#39;aléatoire...&lt;/p&gt;
&lt;h3 id=&quot;cet-article-lance-ce-nouveau-site-!&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/de-l-aleatoire-en-css-c-est-possible-enfin-presque/#cet-article-lance-ce-nouveau-site-!&quot;&gt;Cet article lance ce nouveau site !&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Et vous pourrez suivre ses futures publications principalement via ce bon vieux &lt;a href=&quot;https://bastiencalou.fr/feed/feed.xml&quot;&gt;flux RSS&lt;/a&gt; ou mon compte &lt;a href=&quot;https://piaille.fr/@bcalou&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>« Toxic Data » : la menace de l&#39;intermédiation algorithmique</title>
		<link href="https://bastiencalou.fr/toxic-data-la-menace-de-l-intermediation-algorithmique/"/>
		<updated>2023-09-26T00:00:00Z</updated>
		<id>https://bastiencalou.fr/toxic-data-la-menace-de-l-intermediation-algorithmique/</id>
		<content type="html">&lt;p&gt;Je sors de la lecture de &lt;a href=&quot;https://editions.flammarion.com/toxic-data/9782080419415&quot;&gt;Toxic Data&lt;/a&gt;, ouvrage passionant de David Chavalarias, chercheur au CNRS, sur le rôle toxique que joue une grande partie des réseaux sociaux sur nos sociétés.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/PwVpqTojTB-390.avif 390w, https://bastiencalou.fr/img/PwVpqTojTB-607.avif 607w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/PwVpqTojTB-390.webp 390w, https://bastiencalou.fr/img/PwVpqTojTB-607.webp 607w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/PwVpqTojTB-390.webp&quot; alt=&quot;Couverture du livre Toxic Data&quot; width=&quot;304&quot; height=&quot;501&quot; loading=&quot;eager&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      On aime ce jaune bien agressif.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Il met en mots simples un sentiment de malaise que nous sommes, j&#39;en suis sûr, un grand nombre à partager. Pour ma part, ce sentiment est un moteur depuis quelques années pour adopter une attitude de grande méfiance à l&#39;égard des réseaux en question, et en particulier à l&#39;égard de ceux dont les contenus présentés sont régis par un algorithme opaque cherchant à maximiser les interactions sur la plateforme (c&#39;est à dire beaucoup d&#39;entre-eux).&lt;/p&gt;
&lt;p&gt;J&#39;ai le sentiment que ma participation active aux réseaux dans le passé (toujours existante, mais moindre), ainsi que celle d&#39;une grande partie de la société, ont sérieusement altéré la relation que j&#39;entretiens avec mon entourage, notamment dans la façon dont les débats ont tendance à être, sans exception, hautement inflammables.&lt;/p&gt;
&lt;p&gt;Mais David Chavalarias le dit mieux que moi :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;À l&#39;ère numérique, les sujets de discussion sont susceptibles de se polariser autour de points de vue toxiques à l&#39;échelle d&#39;une société entière. Pouvons-nous au moins espérer que la cohésion sociale, même affaiblie, ne sera pas rompue, et que deux camps qui s&#39;opposent sur un thème trouveront toujours un terrain d&#39;entente sur un autre ? [...] Que deux voisins en désaccord sur la vaccination continueront à échanger sur des questions politiques, que deux amis en désaccord sur des questions politiques continueront à discuter sur les questions environnementales ?
    Nous avons l&#39;habitude de vivre à l&#39;intersection de plusieurs cercles relationnels qui reflètent la diversité de nos centres d&#39;intérêt et de nos rôles sociaux. [...] Nous nous appuyons activement sur le contexte pour filtrer l&#39;information à laquelle nous accordons de l&#39;importance et pour choisir quel type d&#39;information échanger. Nous n&#39;abordons pas partout, ni n&#39;importe comment, des thèmes tels que l&#39;alimentation, l&#39;éducation, le sport, la contraception ou l&#39;immigration. [...] Bref, nous sommes capables d&#39;orienter notre attention et d&#39;adapter notre comportement en fonction du contexte social.
    [...] Les algorithmes ne font pas la distinction entre vos différents cercles relationnels et traitent indifférement vos sujets de préoccupation. [...] Facebook peut très bien vous bombarder de messages que l&#39;une de vos connaissances a appréciés alors même que vous n&#39;abordez jamais ce type de sujets avec elle. Ce bombardement intempestif vous amènera peut-être à adopter un point de vue auquel vous ne vous seriez pas exposé naturellement ou, au contraire, à rompre un lien social par overdose de contenus dissonants, alors que vous auriez très bien pu continuer à sympathiser sur d&#39;autres sujets avec cette personne.
    [Il en résulte que] la structure de vos cercles sociaux est brouillée. [...] Vous êtes privé(e) des filtres contextuels que vous appliquiez dans vos interactions quotidiennes.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;David Chavalarias, &lt;cite&gt;Toxic Data&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Les effets vont bien au-delà de l&#39;impact sur les personnes elles-mêmes :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Plus un réseau social se densifie avec l&#39;ajout de liens, plus le nombre moyen d&#39;intermédiaires entre deux personnes se réduit. Or les contenus négatifs ont tendance à se propager, de proche en proche, plus facilement que d&#39;autres types de contenus. Dès lors qu&#39;un certain seuil de densification est atteint, ces contenus négatifs sont donc les premiers à pouvoir toucher une très large fraction du réseau, même s&#39;ils sont produits par un très petit nombre de personnes.
    Dernier effet potentiel à signaler : comme les mécanismes d&#39;influence sociale ne respectent plus les frontières de vos cercles relationnels sur les réseaux sociaux numériques, les valeurs, les croyances et les comportements risquent de s&#39;y aligner en passant d&#39;un cercle relationnel à l&#39;autre. Ce phénomène favoriserait ainsi une polarisation globale de la société, sur plusieurs dimensions à la fois (par exemple, aux États-Unis, en général, les antivax sont aussi climatosceptiques et républicains). Bien que cet effet n&#39;ait pas encore été documenté, il pourrait expliquer la polarisation importante de nos sociétés actuelles et la formation concomitante de plusieurs lignes de fracture.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;David Chavalarias, &lt;cite&gt;Toxic Data&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Et l&#39;auteur de lister toutes les applications qui structurent nos vies aujourd&#39;hui, qu&#39;elles soient professionnelles, relationnelles (jusqu&#39;aux relations les plus intimes), relatives aux voyages, à la consommation d&#39;images et de vidéos... C&#39;est ce que l&#39;auteur appelle &lt;strong&gt;l&#39;intermédiation algorithmique&lt;/strong&gt;.&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;La liste est longue, et un seul ouvrage ne suffirait pas à examiner l&#39;ensemble des configurations sociales au sein desquelles le numérique s&#39;est immiscé, les choix algorithmiques qui ont été faits et leurs conséquences sociales. Il y a néamoins un point commun à toutes ces plateformes : elles se mettent en tête de gérer une partie de nos relations à autrui.
    [...] En se posant en intermédiaires dans le flux des échanges sociaux et en modelant la perception que nous avons de notre monde social, les réseaux sociaux numériques se sont arrogé le pouvoir de modeler à leur avantage les piliers de la cohésion sociale.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;David Chavalarias, &lt;cite&gt;Toxic Data&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
</content>
	</entry>
	
	<entry>
		<title>Connaît-on vraiment CSS lorsqu&#39;on utilise un framework CSS ?</title>
		<link href="https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/"/>
		<updated>2022-12-09T00:00:00Z</updated>
		<id>https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/</id>
		<content type="html">&lt;p&gt;Le sondage &lt;i&gt;State of CSS&lt;/i&gt; de l&#39;année 2022 propose un excellent outil appelé le &lt;a href=&quot;https://2022.stateofcss.com/en-US/explorer&quot;&gt;Data Explorer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Par exemple, voici un tableau croisant l&#39;usage des propriétés &lt;code&gt;scroll-snap&lt;/code&gt; avec l&#39;usage de Bootstrap.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/dQQF-tADJC-390.avif 390w, https://bastiencalou.fr/img/dQQF-tADJC-780.avif 780w, https://bastiencalou.fr/img/dQQF-tADJC-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/dQQF-tADJC-390.webp 390w, https://bastiencalou.fr/img/dQQF-tADJC-780.webp 780w, https://bastiencalou.fr/img/dQQF-tADJC-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/dQQF-tADJC-390.webp&quot; alt=&quot;Un tableau croisant l&#39;usage des propriétés scroll-snap avec l&#39;usage de Bootstrap.&quot; width=&quot;780&quot; height=&quot;534&quot; loading=&quot;eager&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Cela peut sembler un peu compliqué, mais je vais clarifier dans quelques instants. Nous avons toutes et tous des idées préconçues sur CSS :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Si tu utilises Tailwind, c&#39;est parce que tu ne veux pas apprendre CSS...&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mais Tailwind a résolu CSS, c&#39;est LA bonne façon !&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Comme toujours, la réalité est plus complexe, et j&#39;ai trouvé que cet outil était une bonne opportunité pour explorer les relations entre les frameworks CSS et le CSS natif.&lt;/p&gt;
&lt;p&gt;Peut-être pouvons nous commencer par nous mettre d&#39;accord sur deux points :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il n&#39;est pas nécessaire de connaître chaque propriété CSS pour écrire un CSS de qualité. Ce qui compte est de construire un bon modèle mental du fonctionnement de CSS.&lt;/li&gt;
&lt;li&gt;En même temps, il est utile de connaître une bonne quantité de propriétés CSS pour pouvoir s&#39;en servir lorsque cela est nécessaire, comme une boîte à outils.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En espérant que cela ne soit pas controversé. C&#39;est parti !&lt;/p&gt;
&lt;h2 id=&quot;bootstrap-la-methodologie&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#bootstrap-la-methodologie&quot;&gt;Bootstrap, la méthodologie&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bootsrap a déjà été utilisé par 81% des devs ayant répondu à ce sondage. Historiquement, c&#39;est &lt;em&gt;le&lt;/em&gt; framework CSS.&lt;/p&gt;
&lt;p&gt;Définissons quelques catégories :&lt;/p&gt;
&lt;table&gt;
  &lt;caption&gt;Relation des devs à Bootstrap&lt;/caption&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;th scope=&quot;col&quot;&gt;Opinion&lt;/th&gt;
    &lt;th scope=&quot;col&quot;&gt;Nom de code&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;51,7&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt; Ont utilisé, mais ne l&#39;utiliseront plus&lt;/td&gt;
    &lt;td&gt;Les exs&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;29&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Ont utilisé et utiliseront de nouveau&lt;/td&gt;
    &lt;td&gt;Les fans&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;16,3&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Connaissent mais ne souhaitent pas essayer&lt;/td&gt;
    &lt;td&gt;Les « non merci »&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;2,7&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Connaissent et souhaitent essayer&lt;/td&gt;
    &lt;td&gt;Les « pourquoi pas »&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;0,5&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Ne connaissent pas&lt;/td&gt;
    &lt;td&gt;Les késako&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Qui selon vous aura la meilleure connaissance du CSS natif ?&lt;/p&gt;
&lt;p&gt;Regardons donc ce que le &lt;i&gt;Data Explorer&lt;/i&gt; peut nous apprendre, avec l&#39;exemple des propriétés &lt;code&gt;scroll-snap&lt;/code&gt;. Voici un zoom sur une cellule spécifique :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/8yyeHB_jOt-390.avif 390w, https://bastiencalou.fr/img/8yyeHB_jOt-780.avif 780w, https://bastiencalou.fr/img/8yyeHB_jOt-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/8yyeHB_jOt-390.webp 390w, https://bastiencalou.fr/img/8yyeHB_jOt-780.webp 780w, https://bastiencalou.fr/img/8yyeHB_jOt-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/8yyeHB_jOt-390.webp&quot; alt=&quot;Les utilisations croisées de Bootstrap et scroll-snap.&quot; width=&quot;780&quot; height=&quot;286&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Voici comment lire cette cellule : dans l&#39;ensemble, 34% des devs a répondu avoir déjà utilisé les propriétés &lt;code&gt;scroll-snap&lt;/code&gt;. Cependant, si l&#39;on regarde uniquement les fans de Bootstrap, seulement 26% utilisent &lt;code&gt;scroll-snap&lt;/code&gt;, soit 8 points de moins.&lt;/p&gt;
&lt;p&gt;Voici donc ce que j&#39;ai entrepris : dans un horrible document, j&#39;ai répertorié ces variations pour les 54 propriétés CSS présentées et pour nos 5 profils.&lt;/p&gt;
&lt;h2 id=&quot;bootstrap-les-resultats&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#bootstrap-les-resultats&quot;&gt;Bootstrap, les résultats&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Et voici nos 5 profils, du moins familier avec le CSS natif au plus familier :&lt;/p&gt;
&lt;table&gt;
&lt;/table&gt;
&lt;table&gt;
  &lt;caption&gt;Variation de connaissance du CSS natif en fonction de l&#39;usage de Bootstrap&lt;/caption&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;th scope=&quot;col&quot;&gt;Variation de connaissance du CSS natif&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les késako&lt;/th&gt;
    &lt;td&gt;🔴&amp;nbsp;-11&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les « pourquoi pas »&lt;/th&gt;
    &lt;td&gt;🔴&amp;nbsp;-9&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les fans&lt;/th&gt;
    &lt;td&gt;🟠&amp;nbsp;-2&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les « non merci »&lt;/th&gt;
    &lt;td&gt;Pas de variation&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les exs&lt;/th&gt;
    &lt;td&gt;🟢&amp;nbsp;+2&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;h3 id=&quot;les-kesako&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-kesako&quot;&gt;Les késako&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Le profil &lt;strong&gt;késako&lt;/strong&gt; (qui ne sait pas ce qu&#39;est Bootstrap) est corrélé avec une plus faible connaissance du CSS natif : 🔴 &lt;strong&gt;-11 points&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : Bootstrap est tant utilisé que si vous ne le connaissez pas (seulement 0,5% des réponses), vous êtes probablement en train de découvrir CSS. Il est donc logique que vous ayez encore une connaissance du CSS lacunaire.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Note : Merci de garder à l&#39;esprit que les théories personnelles sont des théories... et qu&#39;elles sont personnelles.&lt;/div&gt;
&lt;h3 id=&quot;les-pourquoi-pas&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-pourquoi-pas&quot;&gt;Les « pourquoi pas »&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Le profil « &lt;strong&gt;pourquoi pas&lt;/strong&gt; » (qui est intéressé par la découverte de l&#39;outil) est également corrélé avec une plus faible connaissance du CSS natif : 🔴 &lt;strong&gt;-9 points&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : ces profils pourraient également être ceux de personnes débutantes n&#39;ayant pas encore eu le temps de tester Bootstrap. Elles souhaiteraient l&#39;essayer car c&#39;est un outil très utilisé et qu&#39;il est encore trop tôt pour elles pour décider ou non de s&#39;en passer.&lt;/p&gt;
&lt;h3 id=&quot;les-fans&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-fans&quot;&gt;Les fans&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Le profil des &lt;strong&gt;fans&lt;/strong&gt; (qui ont utilisé Bootstrap et l&#39;utiliseraient de nouveau) obtiennent un bien meilleur résultat, mais toujours 🟠 &lt;strong&gt;-2 points&lt;/strong&gt; en-dessous de la moyenne.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : ces personnes ont bien plus de connaissances que les késako et les « pourquoi pas » car elles ont peut être codé avec Bootstrap (entre autres outils) depuis des années et accumulé des savoirs en cours de route. Cela étant dit, l&#39;usage de Bootstrap ne facilite pas la découverte de nouvelles fonctionnalités CSS, ou Bootstrap est suffisant pour ce qu&#39;elles font et elles ne se préocuppent pas tant que ça des nouveautés (ou n&#39;en ont pas le temps !)&lt;/p&gt;
&lt;h3 id=&quot;les-non-merci&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-non-merci&quot;&gt;Les « non merci »&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Les « &lt;strong&gt;non merci&lt;/strong&gt; » (qui connaissent Bootstrap mais ne souhaitent pas l&#39;utiliser) obtiennent un résultat dans la &lt;strong&gt;moyenne&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : décider qu&#39;un outil n&#39;est pas pour vous requiert une compréhension suffisante des challenges posés par CSS. D&#39;autres outils pourraient également récupérer l&#39;attention de ces profils, mais cela ne semble pas gêner la découverte de fonctionnalités CSS natives pour autant.&lt;/p&gt;
&lt;h3 id=&quot;les-exs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-exs&quot;&gt;Les exs&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Les &lt;strong&gt;exs&lt;/strong&gt; (qui ont utilisé Bootstrap mais ne souhaitent plus l&#39;utiliser) font mieux que la moyenne : 🟢 &lt;strong&gt;+2 points&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : apprendre à maîtriser un framework puis décider d&#39;en arrêter l&#39;utilisation est un processus long, ces personnes ont donc une expérience substantielle. Elles ont abandonné Bootstrap car leur approche du CSS a évolué (et CSS aussi, permettant ce départ pour certaines personnes). Elles ont peut être même été témointes de la longue transformation de CSS au cours des années. Elles ont décidé que Bootstrap n&#39;était plus pour elles et d&#39;utiliser le CSS natif davantage. Par ailleurs, on ne choisit pas toujours ses outils : elles ont peut être été contraintes d&#39;utiliser Boostrap pour un employeur ou un client, tout en investissant dans le CSS natif en parallèle.&lt;/p&gt;
&lt;p&gt;Voici les détails groupés par catégories :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/HBCJQYMksb-390.avif 390w, https://bastiencalou.fr/img/HBCJQYMksb-780.avif 780w, https://bastiencalou.fr/img/HBCJQYMksb-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/HBCJQYMksb-390.webp 390w, https://bastiencalou.fr/img/HBCJQYMksb-780.webp 780w, https://bastiencalou.fr/img/HBCJQYMksb-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/HBCJQYMksb-390.webp&quot; alt=&quot;Détails des résultats groupés par catégories de fonctionnalités CSS.&quot; width=&quot;780&quot; height=&quot;225&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Le plus grand écart (-8 points) entre les exs et les fans se situe au niveau des fonctionnalités d&#39;interaction (&lt;code&gt;scroll-snap&lt;/code&gt;, interactions tactiles, &lt;code&gt;overscroll-behavior&lt;/code&gt;...).&lt;/p&gt;
&lt;p&gt;Je pense qu&#39;il faut aussi noter que les catégorie des fans est correlée avec une moins bonne connaissance des fonctionnalités liées à l&#39;accessibilité (-5 points par rapport aux exs).&lt;/p&gt;
&lt;h2 id=&quot;tailwind-la-methodologie&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#tailwind-la-methodologie&quot;&gt;Tailwind, la méthodologie&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Parlons maintenant du nouveau roi de la récré.&lt;/p&gt;
&lt;p&gt;D&#39;abord, nos 5 profils :&lt;/p&gt;
&lt;table&gt;
  &lt;caption&gt;Relation des devs à Tailwind&lt;/caption&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;th scope=&quot;col&quot;&gt;Opinion&lt;/th&gt;
    &lt;th scope=&quot;col&quot;&gt;Nom de code&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;36,4&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Ont utilisé et utiliseront de nouveau&lt;/td&gt;
    &lt;td&gt;Les fans&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;25&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Connaissent mais ne souhaitent pas essayer&lt;/td&gt;
    &lt;td&gt;Les « non merci »&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;25&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Connaissent et souhaitent essayer&lt;/td&gt;
    &lt;td&gt;Les « pourquoi pas »&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;9,8&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Ont utilisé, mais ne l&#39;utiliseront plus&lt;/td&gt;
    &lt;td&gt;Les exs&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;4,1&amp;nbsp;%&lt;/th&gt;
    &lt;td&gt;Ne connaissent pas&lt;/td&gt;
    &lt;td&gt;Les késako&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;D&#39;après-vous, qui aura le meilleur score cette fois-ci ?&lt;/p&gt;
&lt;h2 id=&quot;tailwind-les-resultats&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#tailwind-les-resultats&quot;&gt;Tailwind, les résultats&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;L&#39;ordre a changé ! En effet, les fans obtiennent maintenant un meilleur résultat que les « pourquoi pas ».&lt;/p&gt;
&lt;p&gt;Et les résultats eux-même ont aussi fortement changé.&lt;/p&gt;
&lt;table&gt;
  &lt;caption&gt;Variation de connaissance du CSS natif en fonction de l&#39;usage de Tailwind&lt;/caption&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;th scope=&quot;col&quot;&gt;Variation de connaissance du CSS natif&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les késako&lt;/th&gt;
    &lt;td&gt;🔴&amp;nbsp;-9&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les « pourquoi pas »&lt;/th&gt;
    &lt;td&gt;🔴&amp;nbsp;-5&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les « non merci »&lt;/th&gt;
    &lt;td&gt;🟢&amp;nbsp;+1&amp;nbsp;point&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les fans&lt;/th&gt;
    &lt;td&gt;🟢&amp;nbsp;+2&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;Les exs&lt;/th&gt;
    &lt;td&gt;🔥&amp;nbsp;+6&amp;nbsp;points&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;h2 id=&quot;les-kesako-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-kesako-1&quot;&gt;Les késako&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le profil &lt;strong&gt;késako&lt;/strong&gt; (qui ne sait pas ce qu&#39;est Tailwind) est correlé avec une faible connaissance du CSS natif : 🔴 &lt;strong&gt;-9 points&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : comme pour les personnes qui ne connaissent pas Bootstrap. Si vous ne connaissez pas Tailwind, vous êtes possiblement en train de découvrir l&#39;écosystème CSS. Mais vous pourriez aussi avoir des années d&#39;expérience et ne pas être au courant des dernières actualités CSS, ce qui pourrait expliquer pourquoi ce profil n&#39;est « que » 9 points en dessous de la moyenne (tandis que pour Bootstrap, c&#39;était 11).&lt;/p&gt;
&lt;h2 id=&quot;les-pourquoi-pas-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-pourquoi-pas-1&quot;&gt;Les « pourquoi pas »&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le profil « &lt;strong&gt;pourquoi pas&lt;/strong&gt; » (qui aimerait découvrir Tailwind) est correlé avec une baisse de 🔴 &lt;strong&gt;-5 points&lt;/strong&gt; par rapport à la moyenne.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : c&#39;est une baisse moins importante que pour Bootstrap (-9 points), mais la logique pourrait être la même. Si vous n&#39;avez pas utilisé cet outil très répandu ou que vous n&#39;avez pas encore le recul nécessaire pour décider de vous en passer, vous êtes peut-être en phase de découverte de CSS, il est donc logique que vous ne connaissiez pas le CSS natif parfaitement non plus. C&#39;est tout de même un meilleur score qu&#39;avec Bootstrap. Si vous avez entendu parler de Tailwind, cela signifie que vous vous intéressez aux évolutions récentes de CSS, tandis que vous pourriez avoir entendu parler de Bootstrap il y a longtemps de cela.&lt;/p&gt;
&lt;h2 id=&quot;les-non-merci-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-non-merci-1&quot;&gt;Les « non merci »&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le profil « &lt;strong&gt;non merci&lt;/strong&gt; » (qui a entendu parler de Tailwind mais n&#39;est pas intéressé) dépasse legèrement la moyenne : 🟢 &lt;strong&gt;+1 point&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : comme pour Bootstrap. Ces personnes ont assez d&#39;expérience pour juger qu&#39;un outil leur correspond ou non. Cette expérience s&#39;accompagne d&#39;une bonne connaissance du CSS natif, juste au dessus de la moyenne. Mais...&lt;/p&gt;
&lt;h2 id=&quot;les-fans-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-fans-1&quot;&gt;Les fans&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les &lt;strong&gt;fans&lt;/strong&gt; (qui ont utilisé Tailwind et l&#39;utiliseront de nouveau) sont dans une position très différente. Avec Bootstrap, ces personnes connaissaient moins de CSS natif (-2 points), mais avec Tailwind, elles en connaissent plus : 🟢 &lt;strong&gt;+2 points&lt;/strong&gt; ! Encore mieux que les « non merci ».&lt;/p&gt;
&lt;p&gt;Théorie personnelle : contrairement à ce que l&#39;on lit parfois, aimer Tailwind n&#39;est pas corrélé avec une moindre connaissance du CSS natif. Tout d&#39;abord, rappelons-nous qu&#39;avec ses classes utilitaires, Tailwind utilise une approche plus proche du CSS natif que Bootstrap. Les devs Tailwind connaissent par exemple les concept tels que &lt;em&gt;flex&lt;/em&gt;, là où les devs Bootstrap utiliseraient une classe &lt;code&gt;column&lt;/code&gt; (qui utilise en réalité &lt;em&gt;flexbox&lt;/em&gt; en coulisse et n&#39;a rien à voir avec les vraies colonnes CSS...) Enfin, il y a le fait que Tailwind soit un outil récent. Si vous lisez des articles sur Tailwind, il est presque impossible que vous ne lisiez pas aussi des articles sur les améliorations natives de CSS. Tailwind fait partie de l&#39;écosystème moderne. Ceci étant dit...&lt;/p&gt;
&lt;h2 id=&quot;les-exs-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#les-exs-1&quot;&gt;Les exs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le profil des &lt;strong&gt;exs&lt;/strong&gt; (ayant utilisé Tailwind mais ne souhaitant plus l&#39;utiliser) fait bien mieux que la moyenne : 🔥 &lt;strong&gt;+6 points&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Théorie personnelle : bien que les devs utilisant Tailwind fassent partie de l&#39;écosystème moderne et connaissent leur CSS, les devs ayant tourné leur dos à Tailwind semblent en savoir plus. Premièrement, Tailwind ne résoud pas et ne couvre pas tout (ni ne prétend le faire). Certains fonctionnalités modernes, comme &lt;code&gt;:has&lt;/code&gt;, les &lt;em&gt;container queries&lt;/em&gt;, les &lt;em&gt;cascade layers&lt;/em&gt;, les &lt;code&gt;@supports&lt;/code&gt; &lt;em&gt;queries&lt;/em&gt;... nécessitent de les connaître nativement pour les utiliser à leur plein potentiel. Cela ne signifie pas que les fans de Tailwind ne les connaissent pas et ne peuvent pas utiliser les deux, mais les personnes déçues par l&#39;approche de Tailwind semblent simplement investir plus de temps dans la compréhension du CSS natif. Cela n&#39;en fait pas de meilleures personnes, mais leur boîte à outil semble un peu plus étendue.&lt;/p&gt;
&lt;p&gt;Voici le détail des résultats par catégories de fonctionnalités :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/zuD3n5RHMl-390.avif 390w, https://bastiencalou.fr/img/zuD3n5RHMl-780.avif 780w, https://bastiencalou.fr/img/zuD3n5RHMl-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/zuD3n5RHMl-390.webp 390w, https://bastiencalou.fr/img/zuD3n5RHMl-780.webp 780w, https://bastiencalou.fr/img/zuD3n5RHMl-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/zuD3n5RHMl-390.webp&quot; alt=&quot;Détail des résultats pour Tailwind.&quot; width=&quot;780&quot; height=&quot;222&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Ici, le plus gros écart entre les exs et les fans (-8 points) concerne la catégorie des sélecteurs, qui contient &lt;code&gt;::marker&lt;/code&gt;, &lt;code&gt;:has&lt;/code&gt; et &lt;code&gt;:where&lt;/code&gt;. Les fans de Tailwind ne les utilisent pas beaucoup.&lt;/p&gt;
&lt;p&gt;Encore une fois, il y a un gros écart au rayon accessibilité : si les personnes utilisant Tailwind font mieux que la moyenne (+2 points), les exs font bien mieux avec +9 points.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;J&#39;espère que cette petite expérience était intéressante. Ce n&#39;est pas une publication scientifique revue par les pairs, alors prenez-là avec du recul, mais j&#39;ai fait de mon mieux avec ce que j&#39;avais. N&#39;oublions pas le biais d&#39;échantillonnage : les personnes répondant à un sondage sur CSS ne peuvent pas représenter tout le monde.&lt;/p&gt;
&lt;p&gt;Voici quelques conclusions que je vous soumets :&lt;/p&gt;
&lt;h3 id=&quot;a-propos-de-bootstrap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#a-propos-de-bootstrap&quot;&gt;À propos de Bootstrap&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Bootstrap est sur le déclin, et ce n&#39;est peut être pas bien grave. Il a fait partie du voyage de nombreuses et nombreux devs, mais l&#39;utiliser aujourd&#39;hui est correlé avec une moindre connaissance de précieuses fonctionnalités CSS natives. Ce n&#39;est pas un mauvais outil et il a sauvé bien du monde par le passé, mais il a aujourd&#39;hui du mal à rester pertinent.&lt;/p&gt;
&lt;p&gt;Je ne souhaite pas que les gens abandonnent Bootstrap si l&#39;outil leur convient : la seule chose qui compte est la qualité de ce qu&#39;on construit. Il faut juste être conscient que CSS est bien plus étendu que cela aujourd&#39;hui (et beaucoup le sont déjà, j&#39;en suis sûr).&lt;/p&gt;
&lt;h3 id=&quot;a-propos-de-tailwind&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#a-propos-de-tailwind&quot;&gt;À propos de Tailwind&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Non, l&#39;utilisation de Tailwind ne rend pas quelqu&#39;un ignorant vis-à-vis du « vrai CSS ». Ces personnes utilisent un outil moderne et ont accumulé une connaissance substantielle de CSS au cours de leur apprentissage. Elles ont peut être appris le CSS natif récemment et pourraient être plus à jour que quelqu&#39;un qui connaissait bien CSS il y a dix ans mais n&#39;est pas resté à jour.&lt;/p&gt;
&lt;p&gt;Cependant, elles devraient être conscientes que maîtriser Tailwind n&#39;est pas et ne peut pas être maîtriser CSS, si une telle chose existe. Certaines fonctionnalités ne se transposent tout simplement pas à Tailwind. Cela n&#39;empêche pas d&#39;écrire du CSS de qualité mais réduit la taille théorique de la boîte à outils. Les personnes apprenant Tailwind et désireuses de continuer à apprendre pourraient réinvestir cette motivation et continuer à découvrir des fonctionnalités CSS natives, qui sont là pour durer et se transféreront d&#39;un outil à un autre.&lt;/p&gt;
&lt;h3 id=&quot;a-propos-du-css-natif&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/connait-on-vraiment-css-lorsqu-on-utilise-un-framework-css/#a-propos-du-css-natif&quot;&gt;À propos du CSS natif&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://bastiencalou.fr/l-ere-du-no-hacks-css&quot;&gt;2022 a été une excellente année pour CSS&lt;/a&gt; et je pense que connaître ses capacités natives est un atout puissant. Bien sûr, cela ne remplace pas une compréhension profonde de la logique CSS, qui n&#39;est pas juste une liste de propriétés, mais cela fournit une vaste boîte à outil dans laquelle piocher pour faire face à divers obstacles.&lt;/p&gt;
&lt;p&gt;Pour Bootstrap et Tailwind, les personnes connaissant le plus de CSS natif étaient celles qui avaient testé le framework. Alors ne rejetez pas forcément tous ces outils par idéologie : découvrir de nouvelles façons d&#39;écrire du CSS – même pour réaliser qu&#39;elles ne vous conviennent pas au final – est potentiellement précieux et pourrait donner un nouvel éclairage à la façon dont vous écrivez du CSS natif.&lt;/p&gt;
&lt;p&gt;Que pensez-vous de tout cela ? Si vous parvenez à des conclusions différentes, n&#39;hésitez pas à les partager (en respectant tout le monde, ce n&#39;est que du CSS !).&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Paris Web 2022 — Jour 2, le récap !</title>
		<link href="https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/"/>
		<updated>2022-10-14T00:00:00Z</updated>
		<id>https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/</id>
		<content type="html">&lt;p&gt;Suite et fin de mes aventures chez Paris Web, avec les 8 conférences du deuxième jour (et toujours des petites étoiles &lt;strong&gt;subjectives&lt;/strong&gt; pour démarquer mes préférées).&lt;/p&gt;
&lt;h2 id=&quot;1.-bien-doser-l&#39;utilisation-d&#39;aria-pour-eviter-les-catastrophes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#1.-bien-doser-l&#39;utilisation-d&#39;aria-pour-eviter-les-catastrophes&quot;&gt;1. Bien doser l&#39;utilisation d&#39;ARIA pour éviter les catastrophes ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Une première présentation donnée par deux personnes : une voyante et une non-voyante (utilisant pour la présentation une barette braille).&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Nous sommes collègues. Il nous arrive souvent de regarder le même site mais de ne pas voir la même chose.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;div class=&quot;postAside&quot;&gt;Note : Les citations sont basées sur ma prise de notes. Elle reflètent le propos mais la formulation exacte peut varier.&lt;/div&gt;
&lt;p&gt;Sophie et Bart définissent ARIA comme un moyen permettant de modifier l&#39;&lt;i&gt;accessibility tree&lt;/i&gt; (que vous pouvez voir dans le dev tools au même titre que le &lt;i&gt;DOM tree&lt;/i&gt;).&lt;/p&gt;
&lt;p&gt;Mais son utilisation est bien souvent maladroite : &lt;code&gt;aria-label&lt;/code&gt; qui masque le contenu réel, &lt;code&gt;aria-live&lt;/code&gt; sur un carrousel qui interrompt en permanence le flux normal de lecture...&lt;/p&gt;
&lt;p&gt;Jusqu&#39;au paroxysme : le site d&#39;un hôpital belge dont le &lt;code&gt;body&lt;/code&gt; possédait un attribut &lt;code&gt;aria-hidden&lt;/code&gt;...&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Dans les audits, on demande plus souvent d&#39;effacer de l&#39;ARIA que d&#39;en ajouter.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Et donc un énième rappel : ARIA complète les informations du HTML, mais c&#39;est bien la bonne écriture de ce dernier à la base qui garantit la bonne accessibilité.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gq_y9PDQgLw&amp;t=697&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;2.-designgouv-:-insuffler-une-culture-du-design-au-sein-de-l&#39;etat&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#2.-designgouv-:-insuffler-une-culture-du-design-au-sein-de-l&#39;etat&quot;&gt;2. DesignGouv : insuffler une culture du design au sein de l&#39;État ⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;L&#39;occasion d&#39;abord de découvrir le nouveau site présentant le &lt;a href=&quot;https://accessibilite.numerique.gouv.fr/&quot;&gt;référentiel général d&#39;amélioration de l&#39;accessibilité&lt;/a&gt;, beaucoup plus sympathique que l&#39;ancien.&lt;/p&gt;
&lt;p&gt;Une autre ressource intéressante : &lt;a href=&quot;https://observatoire.numerique.gouv.fr/observatoire/&quot;&gt;l&#39;observatoire de la qualité des démarches en ligne&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Depuis 2021, l&#39;équipe de DesignGouv est intervenu sur 112 projets, auprès de 14 ministères. Une belle performance dont on aurait aimé voir plus de détails concrets.&lt;/p&gt;
&lt;p&gt;Et un rappel simple mais important :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Plus on créé de nouveaux outils, plus il y en a à maintenir.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Un passage à noter lors des questions-réponses : le gouvernement recommande-t-il les outils de surcouche d&#39;accessibilité (que certains spécialistes avait osé critiqué, avant d&#39;être poursuivis par les éditeurs) ? La réponse est donnée : non. Applaudissements nourris.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ym2sI8Jlu6A&amp;t=4314&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;3.-le-making-of-du-rgesn-:-tout-savoir-sur-le-referentiel-d&#39;ecoconception-des-services-numeriques&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#3.-le-making-of-du-rgesn-:-tout-savoir-sur-le-referentiel-d&#39;ecoconception-des-services-numeriques&quot;&gt;3. Le making-of du RGESN : tout savoir sur le référentiel d’écoconception des services numériques ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Une conférence très spécifique, non pas sur ce nouveau référentiel lui-même, mais sur les coulisses de sa conception.&lt;/p&gt;
&lt;p&gt;Plus de cent bénévoles, des centaines de critères ramenés au nombre final de 79, pour une version 1 qui devrait sortir ce mois-ci (en voici la &lt;a href=&quot;https://ecoresponsable.numerique.gouv.fr/publications/referentiel-general-ecoconception/&quot;&gt;version bêta&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Le format est très proche du RGAA (le référentiel pour l&#39;accessibilité), et pour cause : les deux projets ont des intervenants communs.&lt;/p&gt;
&lt;p&gt;La &lt;a href=&quot;https://www.vie-publique.fr/loi/278056-loi-15-novembre2021-reen-reduire-empreinte-environnementale-du-numerique&quot;&gt;loi visant à réduire l&#39;empreinte du numérique en France de 2021&lt;/a&gt; n&#39;impose pas encore le respect de ce nouveau référentiel. Il n&#39;y a encore aucune obligation légale à ce sujet.&lt;/p&gt;
&lt;p&gt;Et enfin, pour vous donner une idée, le nouveau site de l&#39;ADEME (Agence de la transition écologique) respecte ce référentiel à 70%.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gq_y9PDQgLw&amp;t=7824&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;4.-designer-l&#39;urgence&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#4.-designer-l&#39;urgence&quot;&gt;4. Designer l&#39;urgence ⭐⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Designer dans l&#39;urgence en mode pompier VS designer l&#39;urgence &lt;em&gt;avec&lt;/em&gt; des pompiers.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Une conférence drôle et passionnante pour répondre à une question très sérieuse : comment aborder le design lorsque des vies sont en jeu ?&lt;/p&gt;
&lt;p&gt;Pour reprendre en main le système d&#39;information des pompiers, Julien s&#39;est immergé dans le métier, et après son témoignage, vous ne pourrez plus dire que la recherche UX est trop difficile à mettre en œuvre dans votre secteur.&lt;/p&gt;
&lt;p&gt;Le monde de l&#39;urgence est fait de contraintes physiques et mentales imctibles. Sous le choc d&#39;un accident, même une interface applicative d&#39;apparence simple (« êtes-vous témoin ou victime ? ») n&#39;a plus rien d&#39;évident.&lt;/p&gt;
&lt;p&gt;L&#39;occasion également de tordre le cou au mythe du « produit minimum viable » (MVP). Une méthode excellente dans nombre de cas, mais tout simplement inapplicable lors de la refonte d&#39;un service aussi critique : quand on sauve des vies, on ne peut pas commencer par la « version simple ».&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Move fast and don&#39;t break things.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gq_y9PDQgLw&amp;t=10167&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;5.-comment-canal+-travaille-et-integre-l&#39;accessibilite-numerique&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#5.-comment-canal+-travaille-et-integre-l&#39;accessibilite-numerique&quot;&gt;5. Comment Canal+ travaille et intègre l’accessibilité numérique ? ⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Depuis un an, Amélien a eu la délicate tâche de sensibiliser les équipes de Canal+ aux enjeux et aux techniques de l&#39;accessibilité.&lt;/p&gt;
&lt;p&gt;Les améliorations sont là, mais on ne peut s&#39;empêcher de constater que même dans une si grosse entreprise, les bases ne sont pas acquises : comment peut-on encore être en charge de l&#39;intégration d&#39;un service massivement utilisé tel que myCanal sans se soucier des problèmes de focus, une des bases de l&#39;accessibilité ? Le chemin est long et le recrutement (et donc les formations) doivent évoluer.&lt;/p&gt;
&lt;p&gt;Enfin, je suis interpellé par ce rôle étrange chez Canal+ : &lt;i&gt;Legal Product Manager&lt;/i&gt;, en charge de la vie privée, l&#39;accessibilité et l&#39;éco-conception. Une si grosse entreprise pense-t-elle que ces trois domaines, qui n&#39;ont de commun que l&#39;obligation légale et/ou l&#39;image de l&#39;entreprise, ne mérite pas au moins 3 emplois distincts ?&lt;/p&gt;
&lt;p&gt;Force et courage à Amélien, donc ;)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gq_y9PDQgLw&amp;t=17964&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;6.-numerique-et-ethique-:-l&#39;impossible-equation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#6.-numerique-et-ethique-:-l&#39;impossible-equation&quot;&gt;6. Numérique et éthique : l&#39;impossible équation ? ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Même si Audrey et Agnès avouent prêcher un public déjà convaincu (« c&#39;est la première fois qu&#39;on m&#39;applaudit parce que je critique Amazon »), le sinistre tour d&#39;horizon offert ici est nécessaire et percutant.&lt;/p&gt;
&lt;p&gt;200 composants, 50 minerais et 75 kilos de matière première pour produire un téléphone (la production représente 75% des émissions), téléphone dont la durée de vie atteindra en moyenne 2 ou 3 ans et ne sera probablement pas recyclé... Sans parler du travail des enfants.&lt;/p&gt;
&lt;p&gt;Et ce n&#39;est que la partie production : saviez-vous que même si vous n&#39;avez pas de profil Facebook, vous possédez malgré tout un &lt;i&gt;shadow account&lt;/i&gt; ? Que des drônes étaient capables de suivre des manifestants jusqu&#39;à leur domicile, en France ? Que Facebook, encore lui, a joué un rôle déterminant dans le génocide des Rohingya ? Et la liste semble sans fin.&lt;/p&gt;
&lt;p&gt;L&#39;invervention se clôture avec quelques conseils élémentaires : gardez votre téléphone (au moins 7 ans, idéalement). Utilisez le nouvel &lt;a href=&quot;https://www.ecologie.gouv.fr/indice-reparabilite&quot;&gt;indice de réparabilité&lt;/a&gt; lors d&#39;un achat. Réparez, et, si vraiment vous devez vous séparer de votre appareil encore en fonctionnement, ne le laissez pas traîner dans un tiroir : vendez ou donnez-le.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gq_y9PDQgLw&amp;t=20357&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;7.-themiser-un-design-system&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#7.-themiser-un-design-system&quot;&gt;7. Thémiser un design system ⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nous atteignons la fin d&#39;après-midi de ce deuxième jour et je ne vous cache pas que mon cerveau commence à se transformer en compote. 16 conférences, c&#39;est beaucoup.&lt;/p&gt;
&lt;p&gt;En écoutant Matthieu, développeur responsable du design system des outils Proton (Mail, Drive...), je réalise à quel point mon propre travail (puisque je fais la même chose, à plus petite échelle) est difficile à expliquer &lt;em&gt;techniquement&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Car oui, les variables CSS sont géniales, mais quand on rajoute à cela des valeurs par défaut, des valeurs optionnelles, des valeurs configurables par les utilisateurs... Ça devient complexe !&lt;/p&gt;
&lt;p&gt;Matthieu a ainsi théorisé un modèle pour les noms de variables :&lt;/p&gt;
&lt;pre&gt;&lt;code tabindex=&quot;0&quot;&gt;--usage-location-state-impact-property
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Une idée m&#39;a particulièrement parlé : un design system est une « rationalisation » du design, et devient ainsi un outil objectif pour challenger toute nouvelle modification des designers ou managers. Pas pour stagner, mais pour assurer au projet de ne pas partir dans tous les sens, ce qui est essentiel à cette échelle.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ym2sI8Jlu6A&amp;t=25385&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;8.-url-reprenons-les-bases&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#8.-url-reprenons-les-bases&quot;&gt;8. URL ; reprenons les bases ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Là, il n&#39;y a plus personne dans ma boîte crânienne, ou plutôt il y a trop de choses, mais cette dernière conférence va fournir son lot d&#39;informations passionnantes.&lt;/p&gt;
&lt;p&gt;Même si vous connaissez les 5 parties d&#39;une URL, les subtitilités d&#39;écriture de chacune d&#39;entre elles réservent des surprises.&lt;/p&gt;
&lt;p&gt;Quels sont les pièges tendus aux utilisateurs grâce aux homoglyphes ? Pourquoi Chrome devrait gentiment s&#39;abstenir de modifier les URLs affichées ? Qu&#39;est ce que le test du bouton du milieu de la souris ?&lt;/p&gt;
&lt;p&gt;On réfléchit rarement aux URLs, qu&#39;on prend pour acquises, mais elles constituent la base du web et on a tendance à minimiser leurs capacités.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gq_y9PDQgLw&amp;t=28739&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;8-bonnes-raisons-de-venir-a-paris-web-2023&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-2-le-recap/#8-bonnes-raisons-de-venir-a-paris-web-2023&quot;&gt;8 bonnes raisons de venir à Paris Web 2023&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Les conférences (une trentaine !) sont de top qualité, j&#39;ai appris beaucoup.&lt;/li&gt;
&lt;li&gt;Le choix des conférences par les équipes est savamment équilibré entre design, accessibilité et technique pour vous tenir en haleine.&lt;/li&gt;
&lt;li&gt;Les orateurs et oratrices viennent de tout horizon, vous n&#39;entendrez pas 10 patrons de start-ups à la suite.&lt;/li&gt;
&lt;li&gt;Une accessibilité remarquable, en cohérence avec le contenu : traduction LSF, vélotypie, traduction de l&#39;anglais vers le français... Et cela a effectivement permis à de nombreuses personnes en situation de handicap d&#39;être présentes.&lt;/li&gt;
&lt;li&gt;Le prix est plutôt accessible pour un événement de ce type (surtout si vous demandez à votre boîte de participer).&lt;/li&gt;
&lt;li&gt;Pardonnez-moi d&#39;être terre à terre, mais l&#39;on y mange très bien, même en tant que végétarien, et ce n&#39;est pas négligeable pour mobiliser toute cette concentration.&lt;/li&gt;
&lt;li&gt;Vous serez en immersion parmi tout un tas de gens qui veulent bien faire comme vous, et ça fait du bien.&lt;/li&gt;
&lt;li&gt;On pourra se dire bonjour :)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À l&#39;année prochaine !&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Paris Web 2022 — Jour 1, le récap !</title>
		<link href="https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/"/>
		<updated>2022-10-12T00:00:00Z</updated>
		<id>https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/</id>
		<content type="html">&lt;p&gt;Il y a pile une semaine, c&#39;était mon premier Paris Web, et quelle journée ! 8 conférences (&lt;a href=&quot;https://www.paris-web.fr/revoir?range%5Byear%5D=2022%3A2022&quot;&gt;parmi les 16 proposées&lt;/a&gt;) passionnantes et variées.&lt;/p&gt;
&lt;p&gt;En voici un récap à chaud, partiel et partial, qui j&#39;espère vous donnera envie pour l&#39;année prochaine !&lt;/p&gt;
&lt;p&gt;J&#39;ai mis des petites étoiles pour faire ressortir mes conférences préférées, mais c&#39;est tout à fait biaisé par mes propres intérêts : je suis impressionné par la qualité de l&#39;ensemble.&lt;/p&gt;
&lt;h2 id=&quot;1.-on-se-leve-et-on-se-casse-:-tour-d&#39;horizon-d&#39;un-travail-sans-capital&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#1.-on-se-leve-et-on-se-casse-:-tour-d&#39;horizon-d&#39;un-travail-sans-capital&quot;&gt;1. On se lève et on se casse : tour d’horizon d’un travail sans capital ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ça commence fort dès le matin avec la présentation politique de la journée.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Je ne sais pas qui fait 35h par semaine dans la salle, mais moi cela m&#39;est tout à fait insupportable.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;div class=&quot;postAside&quot;&gt;Note : Les citations sont basées sur ma prise de notes. Elle reflètent le propos mais la formulation exacte peut varier.&lt;/div&gt;
&lt;p&gt;Au-delà des phrases (et du titre) chocs, Maïtané et Thomas ont créé toute une série de visualisations astucieuses pour créer le débat et comparer différentes formes d&#39;activités : salariat, portage salarial, micro-entreprise, coopérative d&#39;activité et d&#39;emploi...&lt;/p&gt;
&lt;p&gt;Dans quelle structure peut-on parler d&#39;argent sans tabou ? Dans laquelle choisit-on ses clients, ou ses collaborateurs ? Quelle structure participe le mieux au bien commun ? Et, pour répondre à cette notion de « sans capital », dans quelles structures les bénéfices nous reviennent-ils le plus directement possible ?&lt;/p&gt;
&lt;p&gt;Pour ma part, une confirmation que le salariat, ce n&#39;est pas trop pour moi, mais aussi un rappel qu&#39;il n&#39;y a pas que le freelance en face !&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rI35dYvljZo&amp;t=2705s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;2.-concevoir-des-services-eco-responsables-en-alliant-design-de-services-et-eco-conception-numerique&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#2.-concevoir-des-services-eco-responsables-en-alliant-design-de-services-et-eco-conception-numerique&quot;&gt;2. Concevoir des services éco-responsables en alliant Design de Services et Éco-conception Numérique ⭐&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Cela fait 12 ans que je conçois des services, et 12 ans que je les conçois sans me poser la question de l&#39;impact sur la planète.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;La conception centrée sur les utilisateurs est devenue une telle religion qu&#39;il est difficile de le faire entendre : tout ce qui est bon pour les clients et le chiffre d&#39;affaire ne l&#39;est pas forcément pour notre écosystème.&lt;/p&gt;
&lt;p&gt;Une évidence ? Dans certains secteurs, oui, mais pas nécessairement dans le numérique et son illusion de dématérialisation.&lt;/p&gt;
&lt;p&gt;Le design centré sur l&#39;utilisateur est centré sur l&#39;utilisateur... au dépend du reste. Il est temps de prendre un sacré recul pour inclure la conception des services dans une démarche beaucoup plus globale.&lt;/p&gt;
&lt;p&gt;Et pour convaincre les entreprises qui n&#39;y verraient que des contraintes, un seul axe : soit vous prenez le train, soit vous restez passifs face à une évolution inexorable.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pJuHsOi0q4Y&amp;t=4926s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;3.-animating-the-impossible&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#3.-animating-the-impossible&quot;&gt;3. Animating the Impossible ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C&#39;était une forte promesse, et c&#39;est un succès !&lt;/p&gt;
&lt;p&gt;Je ne connaissais pas la méthode FLIP, qui permet de réaliser des transitions visuelles complexes entre deux états, avec un état final difficile à prévoir (notamment la position exacte de l&#39;élément relativement au point de départ, l&#39;élément pouvant atterrir dans un autre endroit du DOM).&lt;/p&gt;
&lt;p&gt;L&#39;idée géniale est donc la suivante, en 4 étapes (FLIP) :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;i&gt;First&lt;/i&gt;&lt;/strong&gt; : stocker la position et les dimensions de l&#39;élément actuel.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;i&gt;Last&lt;/i&gt;&lt;/strong&gt; : placer instantanément l&#39;élément dans sa position finale dans le DOM pour en trouver les dimensions et la position finale (ceci se passe dans la phase de &lt;i&gt;layout&lt;/i&gt;, on ne sollicite pas la phase de &lt;i&gt;paint&lt;/i&gt; et donc c&#39;est invisible !).
  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;i&gt;Invert&lt;/i&gt;&lt;/strong&gt; : Inverser l&#39;animation prévue à la base en calculant la différence entre les états &lt;i&gt;First&lt;/i&gt; et &lt;i&gt;Last&lt;/i&gt;.
  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;i&gt;Play&lt;/i&gt;&lt;/strong&gt; : jouer l&#39;animation finale.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Je ne sais pas si j&#39;explique bien, mais c&#39;est à ça que sert la vidéo, non ?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pJuHsOi0q4Y&amp;t=8131s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;4.-l&#39;industrialisation-des-designers-du-web&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#4.-l&#39;industrialisation-des-designers-du-web&quot;&gt;4. L&#39;industrialisation des designers du web ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Salle comble, c&#39;est manifestement un sujet qui parle à beaucoup.&lt;/p&gt;
&lt;p&gt;25 ans après la phase d&#39;effervescence joyeuse du web, le constat n&#39;est pas réjouissant : les écoles n&#39;enseignent plus les bases des arts plastiques et appliqués. La SNCF mobilise 200 designers pour réaliser une application médiocre. L&#39;esthétique, le sensible et la narration sont mis de côté face à l&#39;assemblage de blocs.&lt;/p&gt;
&lt;p&gt;Et c&#39;est Figma qui va en prendre pour son grade. L&#39;outil révolutionnaire pour les designers est aussi un outil de contrôle idéal pour les managers, assimilable à une ligne de montage surveillée.&lt;/p&gt;
&lt;p&gt;Les designers sont presques dépossédés de leur métier : c&#39;est désormais tout le monde qui peut « chuchoter au curseur du designer » de déplacer ceci, d&#39;agrandir cela.&lt;/p&gt;
&lt;p&gt;&lt;q&gt;Laissez-nous commiter !&lt;/q&gt;, demande Cécile, dans un excellent parallèle avec le processus de développement et ses phases de réflexion solitaires. Figma, c&#39;est parfois un peu comme si les collègues de votre agence vous indiquaient que vous n&#39;avez pas fermé la parenthèse de votre fonction alors que vous êtes encore en train de coder...&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rI35dYvljZo?t=11467s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;5.-illectronisme-et-numerisation-des-services-publics&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#5.-illectronisme-et-numerisation-des-services-publics&quot;&gt;5. Illectronisme et numérisation des services publics ⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;L&#39;administration française donne-t-elle les moyens aux citoyens d&#39;accéder à leurs droits et de réaliser leurs démarches obligatoires ?&lt;/p&gt;
&lt;p&gt;Avec 9% de français n&#39;ayant aucun équipement pour accéder à Internet et 7% d&#39;illetrisme en France, il est clair qu&#39;une administration totalement numérique (et même si les services en ligne continuent à s&#39;améliorer) ne répondra pas seule au problème.&lt;/p&gt;
&lt;p&gt;Selon Raphaël, il faut se méfier du tout-numérique, qui cache le fantasme d&#39;un citoyen modèle, qui se fond dans le moule et remplit gentiment son formulaire en ligne. Vision laissant sur le carreau tous les cas particuliers (et ils sont nombreux) et pouvant être source d&#39;une perte d&#39;autonomie et d&#39;humiliation.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TGnbXfyIbq8&amp;t=324s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;6.-lost-in-translation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#6.-lost-in-translation&quot;&gt;6. Lost in translation ⭐⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Manuel me prend par les sentiments avec un sujet cher à mon cœur : HTML, et plus précisément le mystère de l&#39;incompétence globale pour utiliser correctement ce langage.&lt;/p&gt;
&lt;p&gt;Quelle que soit la stack, React ou intégration native, la plupart des erreurs d&#39;accessibilité viennent du HTML. 20 ans à répéter les bases, et pourtant !&lt;/p&gt;
&lt;p&gt;C&#39;est précisément parce que la syntaxe de HTML est simple que ce langage est mal maîtrisé. Car la complexité ne vient pas de la syntaxe : elle vient de la compréhension des structures, de la sémantique, de tout ce qui est invisible dans un design. Et cela, c&#39;est bien plus complexe.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Some people just don&#39;t care.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Certaines personnes s&#39;en fichent-elles tout simplement ? J&#39;ai bien peur qu&#39;il ait raison, mais Manuel ne se veut pas fataliste pour autant. Une conférence très drôle sur &lt;em&gt;le&lt;/em&gt; langage du web.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TGnbXfyIbq8&amp;t=2828s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;7.-transferts-de-donnees-:-est-ce-que-je-peux-encore-utiliser-des-fournisseurs-americains&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#7.-transferts-de-donnees-:-est-ce-que-je-peux-encore-utiliser-des-fournisseurs-americains&quot;&gt;7. Transferts de données : est-ce que je peux encore utiliser des fournisseurs américains ? ⭐⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Non.&lt;/p&gt;
&lt;p&gt;Autant le contenu de la conférence est technique pour le profane, autant la conclusion est sans appel. Même si les entreprises naviguent dans un flou règlementaire, soupesant les bénéfices et les risques d&#39;une petite entrave à la règle, la fête est finie.&lt;/p&gt;
&lt;p&gt;L&#39;administration Bush a signé un mandat simple : il permet de faire usage aux USA comme bon leur semble de toute donnée présente (ou transmise) sur leur territoire, même celles récoltées par « hasard » (oui, c&#39;est le mot utilisé).&lt;br /&gt;
Alors, votre prestataire des USA (ou travaillant lui-même avec les USA) pourra vous fournir toutes les précautions contractuelles du monde, cela ne change pas grand chose : face aux contrats, c&#39;est la loi qui gagne.&lt;/p&gt;
&lt;p&gt;Et si une société hors USA a des liens quelconques avec le pays, ce dernier se réserve aussi l&#39;exploitation des données qu&#39;ils pourra récupérer. Les ramifications sont vertigineuses.&lt;/p&gt;
&lt;p&gt;Bref, exit Google Analytics, Mailchimp et les autres. Un petit séisme, en somme.&lt;/p&gt;
&lt;p&gt;Comme dit le diction :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Il ne faut pas se demander si on va se faire hacker. Il faut se demander &lt;em&gt;quand&lt;/em&gt; on va se faire hacker.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TGnbXfyIbq8&amp;t=7667s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;8.-objectifs-2025-de-l&#39;accessibilite-:-quels-defis-nous-attendent&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/paris-web-2022-jour-1-le-recap/#8.-objectifs-2025-de-l&#39;accessibilite-:-quels-defis-nous-attendent&quot;&gt;8. Objectifs 2025 de l’accessibilité : quels défis nous attendent ? ⭐&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fin de journée morose, pas à cause des intervenants mais du constat dressé : accessibilité, on n&#39;y est pas, et loin de là.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Ne faites pas accessible, vous ne serez jamais inquiété.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Avec une obligation récente (2021 pour le secteur public et très grosses entreprises privées) ou même future (2025 pour le reste du secteur privé) et peu ou pas d&#39;amendes conséquentes pour le moment, le chemin pour un web accessible ne fait que commencer.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Seules 20% des 250 démarches les plus utilisées par les français sont accessibles alors que c&#39;est imposé depuis 2012.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Le sujet est profond et culturel : est-on prêt, en tant que société, à investir là-dessus ? Les actes ne le prouvent pas actuellement.&lt;/p&gt;
&lt;p&gt;Une remarque est révélatrice : l&#39;un des intervenants estime qu&#39;une personne avec des compétences en la matière n&#39;a pas spécialement plus de chances d&#39;être recrutée qu&#39;une autre. Un bonus sympathique, tout au plus.&lt;/p&gt;
&lt;p&gt;Oui, le sujet est de plus en plus abordé. Mais c&#39;est encore beaucoup trop anecdotique.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Toutes les grosses boîtes ont un budget sécurité énorme, et le budget accessibilité ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TGnbXfyIbq8&amp;t=11402s&quot;&gt;Voir la conférence sur YouTube&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Une musique de jeu évolutive grâce à JavaScript</title>
		<link href="https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/"/>
		<updated>2022-04-07T00:00:00Z</updated>
		<id>https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/</id>
		<content type="html">&lt;p&gt;Le week-end dernier, j&#39;ai eu le plaisir de composer la musique de &lt;cite&gt;Blobby Zombie&lt;/cite&gt;, un jeu créé en 48h seulement par mon ami Simon et son camarade Pierre-Yves, lors d&#39;une Game Jam organisée par &lt;a href=&quot;http://www.hitboxmakers.fr/&quot;&gt;Hitbox Makers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Concevoir et coder un jeu en 48h n&#39;étant visiblement pas assez difficile, ils ont créé un jeu multijoueur en ligne fonctionnel. Bravo à eux !&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://glop.legeay.dev/&quot;&gt;Pour jouer, c&#39;est par ici !&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il faut être plusieurs, chacun sur un ordinateur, et tout le monde partage la même partie. Les règles et commandes sont disponibles &lt;a href=&quot;https://github.com/GJLOP/gjlop_front/blob/master/README.md#comment-jouer&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;De mon côté, ces deux jours se sont divisés ainsi :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;7h le premier jour pour la composition de la bande-son ;&lt;/li&gt;
&lt;li&gt;7h le deuxième jour pour la &amp;quot;programmation musicale&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;la-musique&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/#la-musique&quot;&gt;La musique&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le jeu repose sur un mécanisme de dernier survivant. Il va donc falloir monter en pression progressivement pour que ruissellent les gouttes de sueur des joueuses et joueurs.&lt;/p&gt;
&lt;p&gt;Avec un brief aussi complet que les trois mots « arcade »,  « horreur » et  « fun », je me lance.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://soundcloud.com/b-calou/blobby-zombie&quot;&gt;Écouter « Blobby Zombie » sur SoundCloud&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Anticipant sur la programmation à venir, j&#39;utilise une structure la plus simple possible : une boucle de 4 accords. À chaque nouveau cycle, un instrument se rajoute.&lt;/p&gt;
&lt;p&gt;Voici un schéma, c&#39;est important pour la suite, et j&#39;aime les schémas.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/pzhIUZvNh6-390.avif 390w, https://bastiencalou.fr/img/pzhIUZvNh6-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/pzhIUZvNh6-390.webp 390w, https://bastiencalou.fr/img/pzhIUZvNh6-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/pzhIUZvNh6-390.webp&quot; alt=&quot;Schéma de la structure du morceau.&quot; width=&quot;390&quot; height=&quot;158&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Les instruments s&#39;empilent de cycle en cycle pour faire monter la pression.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Mais comment adapter cette montée en pression de plusieurs minutes à une partie qui pourrait se dérouler beaucoup plus vite ?&lt;/p&gt;
&lt;h2 id=&quot;la-programmation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/#la-programmation&quot;&gt;La programmation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Commençons par une adaptation simple : j&#39;avais choisi &lt;strong&gt;130 BPM&lt;/strong&gt; pour la bande son. Passer à &lt;strong&gt;128 BPM&lt;/strong&gt; est un changement quasi-inaudible qui me permet en revanche d&#39;obtenir des cycles de 15 secondes exactement, ce qui sera bien plus sympathique pour coder et déboguer. C&#39;est toujours ça de pris.&lt;/p&gt;
&lt;p&gt;Bon, il nous faut un moyen de sauter de cycle en cycle, par exemple lorsqu&#39;un nouveau joueur se transforme en zombie.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/MZVoPwNfg6-390.avif 390w, https://bastiencalou.fr/img/MZVoPwNfg6-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/MZVoPwNfg6-390.webp 390w, https://bastiencalou.fr/img/MZVoPwNfg6-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/MZVoPwNfg6-390.webp&quot; alt=&quot;Passage d&#39;une section à une autre.&quot; width=&quot;390&quot; height=&quot;212&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Passer d&#39;une section à l&#39;autre permet d&#39;adapter la situation à l&#39;évolution du jeu.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Puisque mes cycles font 15 secondes, c&#39;est assez facile à calculer.&lt;/p&gt;
&lt;p&gt;Si je suis au cycle 2 et que je souhaite avancer au cycle 3, je peux calculer qu&#39;il faut avancer à 30 secondes dans le morceau (le cycle 1 commençant à 0 seconde, et le cycle 2 à 15 secondes).&lt;/p&gt;
&lt;p&gt;C&#39;est exactement ce que fait cette première démo. À chaque fois que vous cliquerez sur le bouton « Sauter », vous sauterez au début de la section suivante :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;XWVZJKR&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/XWVZJKR&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;h3 id=&quot;fludifier-les-sauts-de-cycles&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/#fludifier-les-sauts-de-cycles&quot;&gt;Fludifier les sauts de cycles&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Si vous jouez un peu avec, vous pouvez probablement entendre que le résultat n&#39;est pas très satisfaisant.&lt;/p&gt;
&lt;p&gt;Il y a deux raisons à cela :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sauter au début du cycle interrompt le rythme que vous pouvez entendre dès le début et tout au long du morceau (cette note unique et répétitive) ;&lt;/li&gt;
&lt;li&gt;sauter au début du cycle suivant interrompt la &lt;strong&gt;progression d&#39;accords&lt;/strong&gt; et la fait recommencer au début, ce qui n&#39;est pas du tout naturel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La progression d&#39;accords, c&#39;est simplement l&#39;enchaînement des 4 accords qui donne sa structure au morceau. On entend cette progression à partir du deuxième cycle.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/jmLWbfwc03-390.avif 390w, https://bastiencalou.fr/img/jmLWbfwc03-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/jmLWbfwc03-390.webp 390w, https://bastiencalou.fr/img/jmLWbfwc03-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/jmLWbfwc03-390.webp&quot; alt=&quot;La progression d&#39;accords du morceau.&quot; width=&quot;390&quot; height=&quot;91&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Voici un cycle au complet : 4 accords qui font peur s&#39;enchaînent sur 8 mesures.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;On va simplifier un peu (beaucoup) le nom des accords et les appeler C, G, C et F (do, sol, do et fa).&lt;/p&gt;
&lt;p&gt;On peut ainsi mettre à jour notre schéma, pour représenter cette progression à partir du deuxième cycle :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/xpHCaXIrqA-390.avif 390w, https://bastiencalou.fr/img/xpHCaXIrqA-780.avif 780w, https://bastiencalou.fr/img/xpHCaXIrqA-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/xpHCaXIrqA-390.webp 390w, https://bastiencalou.fr/img/xpHCaXIrqA-780.webp 780w, https://bastiencalou.fr/img/xpHCaXIrqA-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/xpHCaXIrqA-390.webp&quot; alt=&quot;Shéma de la structure du morceau et de la progression d&#39;accords.&quot; width=&quot;780&quot; height=&quot;324&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      À l&#39;exception de la note unique à la basse et de la batterie qui est uniquement rythmique, chaque nouveau cycle se base sur la même progression d&#39;accords.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Le problème, donc, c&#39;est que si nous passons du milieu du cycle 3 au début du cycle 4, par exemple, nous risquons de faire ça :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/cURabQAt9L-390.avif 390w, https://bastiencalou.fr/img/cURabQAt9L-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/cURabQAt9L-390.webp 390w, https://bastiencalou.fr/img/cURabQAt9L-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/cURabQAt9L-390.webp&quot; alt=&quot;Saut de sol vers do.&quot; width=&quot;390&quot; height=&quot;159&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      On saute du deuxième accord de la section 3 vers le premier accord de la section 4.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Patatra, la progression d&#39;accords est cassée. Alors que nous nous préparions à entendre C puis F pour finir le cycle 3, nous reprenons la progression au départ : C, puis G à nouveau ! Et si on enchaîne vite les cycles, on entend quasiment le premier accord en permanence.&lt;/p&gt;
&lt;p&gt;Or le cerveau est très doué pour s&#39;habituer à une progression d&#39;accords bien spécifique, et toute déviation est troublante pour l&#39;auditeur (ce que certains compositeurs peuvent utiliser à leur avantage, mais c&#39;est une autre histoire).&lt;/p&gt;
&lt;p&gt;Pour remédier à cette violation rythmique et harmonique intolérable à l&#39;oreille, le remède est simple : il ne faut pas aller au début du cycle suivant, mais à l&#39;instant du cycle suivant qui correspond à l&#39;instant actuellement joué.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/D2Hsx1u36o-390.avif 390w, https://bastiencalou.fr/img/D2Hsx1u36o-780.avif 780w, https://bastiencalou.fr/img/D2Hsx1u36o-1128.avif 1128w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/D2Hsx1u36o-390.webp 390w, https://bastiencalou.fr/img/D2Hsx1u36o-780.webp 780w, https://bastiencalou.fr/img/D2Hsx1u36o-1128.webp 1128w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/D2Hsx1u36o-390.webp&quot; alt=&quot;Saut de sol vers sol.&quot; width=&quot;564&quot; height=&quot;228&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Cette fois, on part du deuxième accord du cycle pour arriver sur le deuxième accord du suivant.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Techniquement, c&#39;est presque plus simple que la première version : au lieu de calculer le début de la section suivante, nous allons ajouter 15 secondes – la durée d&#39;un cycle – à la position de lecture.&lt;/p&gt;
&lt;p&gt;Par exemple, si la musique a commencé depuis 5 secondes, nous pouvons sauter jusqu&#39;à &lt;code&gt;5 + 15 = 20&lt;/code&gt; secondes (alors que le début du cycle 2 est à 15 secondes).&lt;/p&gt;
&lt;p&gt;Essayez et comparez. Le résultat vous semble-t-il moins abrupt ?&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;JjMpGzm&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/JjMpGzm&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Alors, attention, j&#39;ai dit que les transitions étaient moins abruptes, pas parfaites ! Selon le moment où vous avancez, l&#39;arrivée de tel ou tel instrument peut tout de même sauter aux oreilles. Mais la structure rythmique et harmonique est sauve, et c&#39;est déjà beaucoup.&lt;/p&gt;
&lt;h3 id=&quot;masquer-la-transition&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/#masquer-la-transition&quot;&gt;Masquer la transition&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Pour améliorer encore l&#39;effet, voici la botte secrète : un bon gros son bien énergique, qui va venir déguiser notre saut dans le morceau, en plus d&#39;annoncer à tous les joueurs qu&#39;il vient d&#39;y avoir du grabuge.&lt;/p&gt;
&lt;p&gt;Ce son, c&#39;est ce que j&#39;appelle le &lt;em&gt;hit&lt;/em&gt;. En jouant le &lt;em&gt;hit&lt;/em&gt; au bon moment, ce dernier occupe tout l&#39;espace sonore et va permettre aux sauts de s&#39;effectuer « discrètement ». Tous les coups sont permis...&lt;/p&gt;
&lt;p&gt;Voici le résultat.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;JjMpKjd&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/JjMpKjd&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Ce n&#39;est pas encore parfait, mais compte tenu du timing serré, c&#39;est déjà pas mal !&lt;/p&gt;
&lt;h3 id=&quot;harmoniser-le-hit&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/#harmoniser-le-hit&quot;&gt;Harmoniser le hit&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finissons avec une petite touche cosmétique.&lt;/p&gt;
&lt;p&gt;Actuellement, le &lt;em&gt;hit&lt;/em&gt; est toujours le même son. Ce ne sont pas n&#39;importe quelles notes qui sont jouées : elles correspondent précisément à celle du premier accord de la progression.&lt;/p&gt;
&lt;p&gt;Autrement dit, elles sonnent très bien sur le premier accord.&lt;/p&gt;
&lt;p&gt;Sur les autres accords, le rendu n&#39;est pas choquant, car le &lt;em&gt;hit&lt;/em&gt; est un élément bien séparé du reste de la musique. Mais qu&#39;est ce que ça donnerait si le &lt;em&gt;hit&lt;/em&gt; était harmonisé avec l&#39;accord actuellement joué ?&lt;/p&gt;
&lt;p&gt;Pour cela, j&#39;ai exporté 4 &lt;em&gt;hits&lt;/em&gt; différents. Ensuite, il suffit de faire correspondre le &lt;em&gt;hit&lt;/em&gt; avec l&#39;accord courant. Si on est dans le dernier quart d&#39;un cycle, c&#39;est qu&#39;il faut jouer le &lt;em&gt;hit&lt;/em&gt; qui correspond au dernier accord.&lt;/p&gt;
&lt;p&gt;C&#39;est parti !&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;gOovMez&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/gOovMez&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Cette amélioration passe sans doute inaperçue, c&#39;est d&#39;ailleurs son but, mais je pense qu&#39;elle rajoute une petite couche de satisfaction auditive à l&#39;ensemble.&lt;/p&gt;
&lt;h2 id=&quot;musique-+-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/une-musique-de-jeu-evolutive-grace-a-javascript/#musique-+-code&quot;&gt;Musique + code = ❤️&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=HlYkDBsUe14&quot;&gt;Voir un extrait du jeu sur YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C&#39;est la première fois que je combine ma passion pour la musique et mes connaissances en programmation, et en seulement 48h j&#39;ai pu voir à quel point les possibilités étaient grandes.&lt;/p&gt;
&lt;p&gt;C&#39;est l&#39;occasion de recommander une excellente chaîne YouTube : &lt;a href=&quot;https://www.youtube.com/channel/UCeZLO2VgbZHeDcongKzzfOw&quot;&gt;8-bit Music Theory&lt;/a&gt;. Je ne comprends pas la moitié de ce qu&#39;il raconte, mais ses analyses de bande-sons vidéoludiques me fascinent et m&#39;ont fortement influencé pour cette petite expérience.&lt;/p&gt;
&lt;p&gt;Quelques liens pour finir :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://glop.legeay.dev/&quot;&gt;Blobby Zombie&lt;/a&gt;, le jeu&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/GJLOP/gjlop_front&quot;&gt;Le code source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://soundcloud.com/bastien-calou/blobby-zombie&quot;&gt;La bande-son&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>L&#39;ère du no-hacks CSS</title>
		<link href="https://bastiencalou.fr/l-ere-du-no-hacks-css/"/>
		<updated>2022-03-28T00:00:00Z</updated>
		<id>https://bastiencalou.fr/l-ere-du-no-hacks-css/</id>
		<content type="html">&lt;p&gt;Si vous avez appris CSS n&#39;importe quand avant 2020, il y a fort à parier que vous avez collecté tout un tas d&#39;astuces (ou &lt;em&gt;hacks&lt;/em&gt;) en cours de route. Vous savez, ces choses comme le centrage vertical, les styles pour les éléments de formulaire, le dimensionnement des images, les retours à la ligne... De la magie noire. Des comportement incroyablement spécifiques que vous recherchez dans Google, espérant que quelqu&#39;un a déjà écrit un article à ce propos, et qui ruineront votre journée dans le cas contraire.&lt;/p&gt;
&lt;p&gt;Beaucoup de mes collègues regardent CSS avec une grande méfiance, car ils ont dû s&#39;y frotter il y a 10 ans, avant de se diriger vers le back-end, la gestion de projet, le design ou même le « front-end pur JS ».&lt;/p&gt;
&lt;p&gt;Beaucoup de gens vont jusqu&#39;à regarder les développeurs utilisant CSS comme d&#39;étranges créatures, ceux qui sont parvenu à dompter le monstre, ceux qui ont pu voir au travers de la jungle impénétrable des &lt;em&gt;hacks&lt;/em&gt; et donner du sens à tout cela aux dépends de leur propre sanité d&#39;esprit.&lt;/p&gt;
&lt;p&gt;Mais la réalité est la suivante :&lt;/p&gt;
&lt;h2 id=&quot;nous-n&#39;aimons-pas-les-hacks-css&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/l-ere-du-no-hacks-css/#nous-n&#39;aimons-pas-les-hacks-css&quot;&gt;Nous n&#39;aimons pas les hacks CSS&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Personnellement, je les déteste. Ils peuvent être amusants à montrer à quelqu&#39;un qui se débat face à un étrange comportement de mise en page (tadaaaa !), mais je les méprise, car ce ne sont que des contournements, ou d&#39;horribles façon non-standards d&#39;utiliser des propriétés qui n&#39;ont jamais été faites pour cela. Ces codes sont énigmatiques, un cauchemar de maintenance, et, probablement le pire, ils créent une méfiance envers CSS qui au bout du compte fait du mal à l&#39;ensemble de l&#39;écosystème.&lt;/p&gt;
&lt;p&gt;Et c&#39;est ainsi que naissent les memes de Petter Griffin se battant contre le CSS, les blagues sur l&#39;alignement vertical... Fichtre, j&#39;ai même l&#39;ironique mug &lt;q&gt;CSS is awesome&lt;/q&gt; comme bannière Twitter.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/nKGXIM8tAS-390.avif 390w, https://bastiencalou.fr/img/nKGXIM8tAS-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/nKGXIM8tAS-390.webp 390w, https://bastiencalou.fr/img/nKGXIM8tAS-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/nKGXIM8tAS-390.webp&quot; alt=&quot;Un mug sur le quel est écrit CSS is awesome. Le texte déborde de son conteneur.&quot; width=&quot;390&quot; height=&quot;130&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Ces blagues nous ont aidé à supporter la dure réalité de CSS pendant des années, mais le fait est qu&#39;elles sont désormais périmées. En réalité, les utilser reviendrait presque à dire :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;J&#39;ai appris CSS il y a 10 ans, j&#39;ai détesté cela et je n&#39;ai jamais ré-essayé ! (insérez la présentation d&#39;une librairie CSS-in-JS miraculeuse ici)&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Oui, il est temps que cette bannière Twitter s&#39;en aille...&lt;/p&gt;
&lt;h2 id=&quot;2022-sera-t-elle-le-debut-de-l&#39;ere-du-no-hacks-css&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/l-ere-du-no-hacks-css/#2022-sera-t-elle-le-debut-de-l&#39;ere-du-no-hacks-css&quot;&gt;2022 sera-t-elle le début de l&#39;ère du no-hacks CSS ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Beaucoup de choses se passent autour de CSS ces temps-ci, et je pense que 2022 pourrait être l&#39;année où l&#39;on se débarasse des hacks CSS, ou du moins où l&#39;on cesse de les considérer comme du « CSS normal ».&lt;/p&gt;
&lt;p&gt;Jetez un oeil à ce tweet, par exemple :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/VqNZlQb-17-390.avif 390w, https://bastiencalou.fr/img/VqNZlQb-17-780.avif 780w, https://bastiencalou.fr/img/VqNZlQb-17-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/VqNZlQb-17-390.webp 390w, https://bastiencalou.fr/img/VqNZlQb-17-780.webp 780w, https://bastiencalou.fr/img/VqNZlQb-17-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/VqNZlQb-17-390.webp&quot; alt=&quot;Tweet de Bramus&quot; width=&quot;780&quot; height=&quot;696&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Source : &lt;a href=&quot;https://x.com/bramus/status/11475583226165055501&quot;&gt;X&lt;/a&gt;
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Les choses avancent vite est CSS devient un langage mature. Même la communauté des navigateurs s&#39;organise pour faire évoluer CSS de la meilleure façon possible, avec par exemple l&#39;initative &lt;a href=&quot;https://wpt.fyi/interop-2022&quot;&gt;Interop&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;l&#39;exemple-de-accent-color&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/l-ere-du-no-hacks-css/#l&#39;exemple-de-accent-color&quot;&gt;L&#39;exemple de accent-color&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La propriété &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/accent-color&quot;&gt;accent-color&lt;/a&gt; est plutôt simple et l&#39;une de mes nouveautés préférées.&lt;/p&gt;
&lt;p&gt;Son seul but est de vous permettre de changer la couleur des inputs natifs : checkboxes, boutons radios, ranges... Voyez plutôt :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;accent-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; crimson&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;XWVpOxB&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/XWVpOxB&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Une ligne de CSS et zéro hack.&lt;/p&gt;
&lt;p&gt;Pendant des années (oserai-je dire des décennies ?), les développeurs CSS ont réalisé cet effet en cachant l&#39;input réel en en montrant un input factice possédant l&#39;apparence désirée. Les deux étaient liés par la bonne vieille pseudo-classe &lt;code&gt;:checked&lt;/code&gt;. Ce code n&#39;a jamais été du code normal. C&#39;était du code sale, propice aux bugs, attendant patiemment d&#39;être remplacé par une solution propre.&lt;/p&gt;
&lt;h2 id=&quot;laisser-tomber-les-hacks-est-aussi-votre-responsabilite&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/l-ere-du-no-hacks-css/#laisser-tomber-les-hacks-est-aussi-votre-responsabilite&quot;&gt;Laisser tomber les hacks est aussi votre responsabilité&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La propriété &lt;code&gt;accent-color&lt;/code&gt; est également un bon exemple de cela. En effet, elle est nouvelle et n&#39;est pas supportée par tous les navigateurs.&lt;/p&gt;
&lt;p&gt;Eh bien comme dirait l&#39;autre, je n&#39;en ai cure.&lt;/p&gt;
&lt;p&gt;CSS étant génial, il ignorera simplement &lt;code&gt;accent-color&lt;/code&gt; sur les navigateurs plus vieux et utilisera les couleurs par défaut. Ce qui est tout à fait acceptable (faites simplement attention à tester le contraste si votre fond n&#39;est pas blanc).&lt;/p&gt;
&lt;p&gt;Encore mieux, le temps passant, de plus en plus de gens utiliseront un navigateur supportant cette fonctionnalité et verront le design initialement voulu. Voici la magie de l&#39;amélioration progressive : votre site web s&#39;améliore alors que vous n&#39;êtes même pas en train de travailler.&lt;/p&gt;
&lt;p&gt;Le fait que je ne m&#39;en soucie pas ne veux pas dire que ce sera le cas pour tout le monde. Un designer ou un manager décidera peut-être qu&#39;il est important que les inputs respectent la couleur de la marque, même sur les vieux navigateurs, et je respecte cela. Mais ce n&#39;est pas qu&#39;une question de design, il y a des coûts et des bénéfices.&lt;/p&gt;
&lt;p&gt;Je défendrais donc la position que bidouiller le CSS (une bidouille qui peut bugger) pour une fraction de l&#39;audience (une fraction qui aurait une très bonne solution alternative et dont la taille diminuera avec le temps) n&#39;en vaut pas la peine dans la plupart des cas.&lt;/p&gt;
&lt;p&gt;J&#39;adore également la propriété &lt;code&gt;gap&lt;/code&gt; pour flexbox, qui rend la gestion des espacements si simple :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;abEpMOx&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/abEpMOx&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Une fraction en diminution des navigateurs ne supporte pas cette fonctionnalité et ne montrera   aucun espace entre les éléments. Que vous soyez prêt à utiliser un &lt;a href=&quot;https://bastiencalou.fr/posts/flexbox-les-marges-negatives-a-la-rescousse/&quot;&gt;hack de marges négatives&lt;/a&gt; ou non est un autre débat sur lequel il vous faudra trancher.&lt;/p&gt;
&lt;p&gt;J&#39;ai commencé à faire la paix avec le fait qu&#39;une petite fraction (et encore une fois, en diminution) des utilisateurs n&#39;aura pas les espaces. Tant que le contenu est parfaitement lisible, cela ne me dérange pas.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;
Mise à jour 2024 : la propriété &lt;code&gt;gap&lt;/code&gt; est désormais supportée pour flexbox sur l&#39;ensemble des navigateurs majeurs. 🎉
&lt;/div&gt;
&lt;h2 id=&quot;adieux-les-hacks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/l-ere-du-no-hacks-css/#adieux-les-hacks&quot;&gt;Adieux les hacks&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bien sûr, j&#39;utilise toujours des hacks, de temps en temps. Mais j&#39;ai cessé de les considérer comme du CSS commun.&lt;/p&gt;
&lt;p&gt;CSS rattrape son retard sur nos bidouilles et est en train d&#39;éradiquer les hacks en proposant des fonctionnalités standards et robustes. Si vous utilisez (et défendez) les techniques d&#39;amélioration progressive grâce auxquelles vous savez que votre contenu sera toujours accessible sans chaque ligne de CSS désirée, vous pouvez utiliser ces nouveautés à volonté. Vous vivrez libre, plus longtemps et, je le crois, ferez de meilleurs sites web.&lt;/p&gt;
&lt;p&gt;Partagez cet article à un ou une collègue qui déteste CSS ;) Si c&#39;est votre cas, je ne peux pas vous blâmer. Mais nous sommes en 2022 et CSS a changé.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Calculs CSS infernaux à partir de données physiques</title>
		<link href="https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/"/>
		<updated>2021-06-18T00:00:00Z</updated>
		<id>https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/</id>
		<content type="html">&lt;p&gt;Côté CSS, je suis assez satisfait de l&#39;effet &lt;strong&gt;renversant&lt;/strong&gt; (j&#39;exagère un peu) de survol que j&#39;ai mis en place (voir sur &lt;a href=&quot;https://top-livres.netlify.app/&quot;&gt;le site&lt;/a&gt;).&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/hover.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : lorsque le curseur survole un livre, ce dernier pivote avec un effet 3D.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Il s&#39;agit en fait d&#39;une adaptation d&#39;un projet open source, &lt;a href=&quot;https://3dbook.xyz/&quot;&gt;3dbook.xyz&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;L&#39;intérêt de cette adaptation réside dans le fait que j&#39;ai utilisé les variables CSS pour faire le lien entre des données concrètes, comme le nombre de pages, et le rendu CSS final.&lt;/p&gt;
&lt;p&gt;Car tout ça est subtil. L&#39;épaisseur du livre, par exemple, va dépendre bien sûr du nombre de pages, mais aussi de la taille du livre. Un livre de poche de 200 pages vu de près pourra paraître aussi épais qu&#39;un gros livre de 400 pages vu d&#39;un peu plus loin...&lt;/p&gt;
&lt;p&gt;Cela nécessite donc quelques calculs !&lt;/p&gt;
&lt;h2 id=&quot;les-donnees&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/#les-donnees&quot;&gt;Les données&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici les données concrètes qui nous intéressent, par exemple pour le livre &lt;em&gt;Clyde Fans&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;23.5&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;488&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Respectivement :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la largeur et la hauteur du livre en centimètres ;&lt;/li&gt;
&lt;li&gt;le nombre de pages ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;offset: true&lt;/code&gt; pour préciser que les pages sont plus petites que la couverture elle-même, ce qui est parfois le cas pour les gros livres (voir le gif ci-dessus).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;passer-les-donnees-a-l&#39;element&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/#passer-les-donnees-a-l&#39;element&quot;&gt;Passer les données à l&#39;élément&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Grâce au langage de templating &lt;code&gt;liquid&lt;/code&gt;, je pourrais alors générer des styles inline à partir de ces variables :&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width * &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;px&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans cet exemple, un livre faisant &lt;code&gt;20cm&lt;/code&gt; de large dans le monde physique fera &lt;code&gt;200px&lt;/code&gt; sur mon site.&lt;/p&gt;
&lt;p&gt;On peut faire en réalité bien plus propre et flexible, en passant ces paramètres aux composant sous forme de variables CSS.&lt;/p&gt;
&lt;p&gt;Voici ce que ça donne :&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;book &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;book--offset&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;
    --width: &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;;
    --height: &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;;
    --pages: &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pages &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;;
  &lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La variable &lt;code&gt;offset&lt;/code&gt;, si elle est présente, permet d&#39;ajouter une classe supplémentaire à l&#39;élément &lt;code&gt;.book&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Les 3 autres variables sont passées grâce à l&#39;attribut &lt;code&gt;style&lt;/code&gt;, et sont maintenant disponibles pour chaque élément &lt;code&gt;.book&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;
Note : Les variables CSS sont scopées. Chaque élément &lt;code&gt;.book&lt;/code&gt; possède désormais ces 3 variables qui ne sont accessibles qu&#39;à lui-même et ses enfants.
&lt;/div&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/hs31GzJx5F-390.avif 390w, https://bastiencalou.fr/img/hs31GzJx5F-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/hs31GzJx5F-390.webp 390w, https://bastiencalou.fr/img/hs31GzJx5F-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/hs31GzJx5F-390.webp&quot; alt=&quot;L&#39;inspecteur du DOM montre les trois variables associées à l&#39;élement book.&quot; width=&quot;390&quot; height=&quot;68&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Les variables sont désormais disponibles dans le scope CSS de l&#39;élément.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;css-:-let-the-fun-begin&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/#css-:-let-the-fun-begin&quot;&gt;CSS : let the fun begin&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Maintenant, nous pouvons utiliser ces variables pour mettre en forme notre livre. Ici, ça se complique et il ne faut pas lésiner sur les commentaires.&lt;/p&gt;
&lt;p&gt;Je vais expliquer seulement quelques lignes du code. On commence avec quelques définitions.&lt;/p&gt;
&lt;pre class=&quot;language-scss&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.book &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* The books will be contained inside a square of this dimension */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--base-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 250&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--base-size-rem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; 0.0625rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;@include&lt;/span&gt; &lt;span class=&quot;token selector&quot;&gt;medium &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;--base-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 350&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Je souhaite que les livres soient contenus dans un carré de &lt;code&gt;250&lt;/code&gt; pixels de côté (&lt;code&gt;--base-size&lt;/code&gt;). Je décline ensuite cette valeur en &lt;code&gt;rem&lt;/code&gt; (mieux que les pixels), grâce à une petite multiplication.&lt;/p&gt;
&lt;p&gt;La mixin &lt;code&gt;@medium&lt;/code&gt; est une media query qui me permet d&#39;agrandir la taille de base sur des écrans plus larges.&lt;/p&gt;
&lt;p&gt;Notez comme je ne redéclare pas &lt;code&gt;--base-size-rem&lt;/code&gt; dans la mixin &lt;code&gt;@medium&lt;/code&gt;. En effet, &lt;code&gt;--base-size-rem&lt;/code&gt; est dynamiquement calculée à partir de &lt;code&gt;--base-size&lt;/code&gt;. Quand l&#39;une change, l&#39;autre aussi, y compris à l&#39;intérieur d&#39;une media query.&lt;/p&gt;
&lt;p&gt;On continue :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.book&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--is-portrait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * 999&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    1
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette syntaxe du démon permet de savoir si le livre est en format paysage ou portrait, et de stocker cette info dans la variable &lt;code&gt;--is-portrait&lt;/code&gt; (ça fait ça de moins à saisir dans la « base de données »).&lt;/p&gt;
&lt;p&gt;Pas très clair ? On décompose.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;clamp&lt;/code&gt; est une fonction CSS qui va me donner une valeur entre deux bornes (le premier et le troisième paramètre).&lt;/p&gt;
&lt;p&gt;Par exemple :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* 0.2, car c&#39;est entre les bornes */&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; -15&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* 0, car le chiffre du milieu est trop petit */&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* 1, car le chiffre du milieu est trop grand */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notre valeur du milieu à nous, en simplifiant la syntaxe, ressemble à ça : &lt;code&gt;(height - width) * 999&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si le livre est au format portrait, la hauteur est plus grande que la largeur, et donc &lt;code&gt;(height - width)&lt;/code&gt; est positif. La multiplication par &lt;code&gt;999&lt;/code&gt; va nous faire obtenir un nombre très grand, transformé en 1 par les bornes du &lt;code&gt;clamp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;À l&#39;inverse, on obtiendra un nombre négatif si le livre est au format paysage, qui sera ramené à 0 par les bornes du &lt;code&gt;clamp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et voici comment on obtient un booléen en CSS 🙃 À manier avec précaution, nous sommes d&#39;accord...&lt;/p&gt;
&lt;p&gt;Je peux ensuite utiliser ce booléen pour obtenir d&#39;autres valeurs.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/Bz5B5ApJap-390.avif 390w, https://bastiencalou.fr/img/Bz5B5ApJap-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/Bz5B5ApJap-390.webp 390w, https://bastiencalou.fr/img/Bz5B5ApJap-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/Bz5B5ApJap-390.webp&quot; alt=&quot;Les livres en format paysage sont trop gros.&quot; width=&quot;390&quot; height=&quot;156&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Si tous les livres font la même hauteur, ceux qui sont en paysage comme &lt;cite&gt;Panthère&lt;/cite&gt; deviennent beaucoup trop gros. D&#39;où l&#39;intérêt du booléen &lt;code&gt;is-portrait&lt;/code&gt; pour la suite.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Quelle devrait être la hauteur d&#39;un livre s&#39;il est en portrait ? La hauteur du conteneur, soit &lt;code&gt;--base-size-rem&lt;/code&gt;. S&#39;il est en paysage, au contraire, cela devrait être dépendant de largeur, qui elle sera &lt;code&gt;--base-size-rem&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Note : L&#39;usage de &lt;code&gt;object-fit: contain&lt;/code&gt; pour contenir l&#39;image n&#39;est pas suffisante ici, car d&#39;autres éléments et pseudo-éléments constitutifs de l&#39;effet final ont besoin de connaître les dimensions exactes.&lt;/div&gt;
&lt;p&gt;Et c&#39;est ainsi que l&#39;on parvient à des atrocités de ce genre :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.book&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* Height is base size if portrait, based on size ratio otherwise */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--height-rem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--is-portrait&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/pqNON9Ck_u-343.avif 343w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/pqNON9Ck_u-343.webp 343w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/pqNON9Ck_u-343.webp&quot; alt=&quot;Expression de dégoût.&quot; width=&quot;172&quot; height=&quot;127&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Allez, on s&#39;accroche une dernière fois, promis. &lt;code&gt;clamp&lt;/code&gt;, on connaît déjà, alors regardons nos bornes. Que remarque t-on si le livre est en mode portrait ? La première borne :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--is-portrait&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette valeur devient simplement &lt;code&gt;--base-size-rem&lt;/code&gt;, puisque &lt;code&gt;is-portrait&lt;/code&gt; vaut 1. Et c&#39;est aussi la valeur de la seconde borne. Si les bornes sont identiques, peu importe la valeur du milieu, le résultat sera &lt;code&gt;--base-size-rem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et c&#39;est que l&#39;on souhaite. Pour les livres portrait, la hauteur est la taille du conteneur, tout bêtement.&lt;/p&gt;
&lt;p&gt;Au contraire, pour un livre paysage, la borne du bas deviendra &lt;code&gt;0&lt;/code&gt; grâce à notre booléen. Et donc la valeur du milieu pourra entrer en action. La voici :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On prend la valeur de base (qui sera donc la largeur), on divise par le ratio entre largeur et hauteur, et hop, on obtient notre hauteur.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/4WJEwymLv3-390.avif 390w, https://bastiencalou.fr/img/4WJEwymLv3-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/4WJEwymLv3-390.webp 390w, https://bastiencalou.fr/img/4WJEwymLv3-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/4WJEwymLv3-390.webp&quot; alt=&quot;Le livre en paysage est plus petit qu&#39;avant.&quot; width=&quot;390&quot; height=&quot;155&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Les livres en paysage font désormais une taille raisonnable, car leur dimension principale devient leur largeur.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;support-navigateur&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/#support-navigateur&quot;&gt;Support navigateur&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Quelques navigateurs dignes d&#39;être considérés (Edge 18, Safari 13...), ne prennent pas en charge l&#39;opération CSS &lt;code&gt;clamp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La mixin suivante permet de détecter ce support, pour mettre en place une solution de fallback avec des calculs un peu moins fins.&lt;/p&gt;
&lt;pre class=&quot;language-scss&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@mixin&lt;/span&gt; &lt;span class=&quot;token selector&quot;&gt;supports-clamp &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @supports &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0px&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1px&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 2px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;@content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pour reprendre notre calcul du dessus, on l&#39;utilise ainsi :&lt;/p&gt;
&lt;pre class=&quot;language-scss&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.book &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--height-rem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;@include&lt;/span&gt; &lt;span class=&quot;token selector&quot;&gt;supports-clamp &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/* Height is base size if portrait, based on size ratio otherwise */&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;--height-rem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--is-portrait&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--ratio-width-height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--base-size-rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si &lt;code&gt;clamp&lt;/code&gt; n&#39;est pas supporté, le navigateur utilisera la première ligne et ignorera tout le reste. Pour quelques utilisateurs, le rendu sera un peu moins subtil, mais le contenu reste lisible et c&#39;est l&#39;essentiel.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : &lt;code&gt;clamp&lt;/code&gt; est désormais supporté par tous les navigateurs majeurs.&lt;/div&gt;
&lt;h2 id=&quot;vers-un-css-plus-adapte-aux-calculs-visuels&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/calculs-css-infernaux-a-partir-de-donnees-physiques/#vers-un-css-plus-adapte-aux-calculs-visuels&quot;&gt;Vers un CSS plus adapté aux calculs visuels ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le &lt;a href=&quot;https://github.com/bcalou/top-books-2020/blob/master/src/styles/blocs/_book.scss&quot;&gt;code CSS complet du composant&lt;/a&gt; est disponible.&lt;/p&gt;
&lt;p&gt;Tout cela est bien stimulant, mais guère lisible, y compris pour moi-même quelques mois après l&#39;avoir écrit.&lt;/p&gt;
&lt;p&gt;Pour un projet perso, c&#39;est bien sympathique, mais la scalabilité n&#39;est pas au rendez-vous.&lt;/p&gt;
&lt;p&gt;Cela reste pourtant la solution qui me paraît la plus élégante, car elle se repose sur des informations physiques concrètes et ne nécessite pas de manipulations JavaScript qui seraient par nature moins performantes. On peut donc espérer que la syntaxe CSS continue d&#39;évoluer pour permettre ce genre d&#39;opérations avec plus de fluidité.&lt;/p&gt;
&lt;p&gt;Peut-être grâce à &lt;a href=&quot;https://houdini.how/about/&quot;&gt;Houdini&lt;/a&gt; ?&lt;/p&gt;
&lt;p&gt;En attendant, il faudra faire fonctionner nos petites cellules grises... Et commenter, beaucoup commenter !&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Optimisation agressive des performances d&#39;un site statique</title>
		<link href="https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/"/>
		<updated>2021-06-16T00:00:00Z</updated>
		<id>https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/</id>
		<content type="html">&lt;p&gt;Grâce au &lt;em&gt;pre-rendering&lt;/em&gt; d&#39;Eleventy, &lt;em&gt;Lighthouse&lt;/em&gt; donne déjà à &lt;a href=&quot;https://top-livres.netlify.app/&quot;&gt;notre site&lt;/a&gt; le vénérable score de 100 points en performance 💪. Mais si nous essayions d&#39;aller plus loin ? Le simple calcul d&#39;un outil n&#39;est pas une excuse pour ne pas mieux faire !&lt;/p&gt;
&lt;p&gt;Voici les techniques, certaines banales, d&#39;autres plus exotiques, que j&#39;ai l&#39;habitude d&#39;utiliser.&lt;/p&gt;
&lt;h2 id=&quot;lazy-loading-des-images&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/#lazy-loading-des-images&quot;&gt;Lazy loading des images&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C&#39;est désormais d&#39;une simplicité absolue en HTML :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;loading&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lazy&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ainsi, les images sont chargées au fil du scroll. HTML mon amour.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/lazy.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : un scroll vertical de la page, au fur et à mesure duquel les images sont chargées progressivement.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Un autre attribut a récemment fait son apparition, que je m&#39;empresse d&#39;ajouter :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;loading&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lazy&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;decoding&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;async&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;L&#39;attribut &lt;code&gt;decoding=&amp;quot;async&amp;quot;&lt;/code&gt; autorise le navigateur à traiter en parallèle le rendu de la page et celui de l&#39;image, ce dernier devenant donc non bloquant.&lt;/p&gt;
&lt;p&gt;L&#39;impact sera faible sur mes images de taille moyenne, mais ça ne mange pas de pain.&lt;/p&gt;
&lt;h2 id=&quot;picture-source-and-srcset&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/#picture-source-and-srcset&quot;&gt;Picture, source &amp;amp; srcset&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pour les couvertures, trois formats d&#39;image cohabitent : &lt;code&gt;avif&lt;/code&gt;, actuellement supporté par &lt;a href=&quot;https://caniuse.com/avif&quot;&gt;Chrome &amp;amp; Opera&lt;/a&gt;, &lt;code&gt;webp&lt;/code&gt;, désormais &lt;a href=&quot;https://caniuse.com/webp&quot;&gt;très bien supporté&lt;/a&gt;, et &lt;code&gt;jpeg&lt;/code&gt;, pour les navigateurs un peu à la traîne.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : Le format &lt;code&gt;avif&lt;/code&gt; est désormais supporté par tous les navigateurs majeurs !&lt;/div&gt;
&lt;p&gt;Le navigateur peut choisir son format préféré grâce au tag &lt;code&gt;picture&lt;/code&gt;, qui contient un tag &lt;code&gt;source&lt;/code&gt; pour chacun des trois formats d&#39;image. Il contient également un tag &lt;code&gt;img&lt;/code&gt; qui sera le seul interprété si le navigateur ne comprend pas &lt;code&gt;picture&lt;/code&gt;. On tire ici parti de la solidité du HTML, qui va simplement ignorer ce qui n&#39;a pas de sens pour lui.&lt;/p&gt;
&lt;p&gt;Notez que les attributs &lt;code&gt;loading&lt;/code&gt;, &lt;code&gt;decoding&lt;/code&gt; et &lt;code&gt;alt&lt;/code&gt; se trouvent sur la balise de &lt;em&gt;fallback&lt;/em&gt;, mais qu&#39;ils seront bien pris en compte.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;picture&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;book__cover&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image/avif&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dist/smile_350.avif 350w, dist/smile_700.avif 700w&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;sizes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;(min-width: 32em) 21.875rem, 15.625rem&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image/webp&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dist/smile_350.webp 350w, dist/smile_700.webp 700w&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;sizes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;(min-width: 32em) 21.875rem, 15.625rem&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image/jpeg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dist/smile_350.jpg 350w, dist/smile_700.jpg 700w&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;sizes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;(min-width: 32em) 21.875rem, 15.625rem&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;loading&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lazy&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;decoding&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;async&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dist/smile_350.jpg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Couverture de Smile&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;picture&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Chaque couverture est donc proposée en &lt;code&gt;avif&lt;/code&gt;, &lt;code&gt;webp&lt;/code&gt; et en &lt;code&gt;jpeg&lt;/code&gt;, mais également avec deux largeurs différentes : &lt;code&gt;350px&lt;/code&gt; et &lt;code&gt;700px&lt;/code&gt;. C&#39;est ce qui est proposé au navigateur grâce à l&#39;attribut &lt;code&gt;srcset&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Enfin, l&#39;attribut &lt;code&gt;sizes&lt;/code&gt; permet au navigateur de connaître la taille d&#39;affichage des images (il faut lui dire, car il ne peut pas le deviner à partir du CSS, pour des raisons d&#39;implémentation).&lt;/p&gt;
&lt;p&gt;Le contenu de l&#39;attribut s&#39;interprète ainsi : au dessus de &lt;code&gt;32em&lt;/code&gt; de large pour le viewport, l&#39;image fera &lt;code&gt;21.875rem&lt;/code&gt; de large. Sinon, elle fera seulement &lt;code&gt;15.625rem&lt;/code&gt; de large.&lt;/p&gt;
&lt;p&gt;Le navigateur connaît la taille du viewport et en déduit la taille de l&#39;image affichée.&lt;/p&gt;
&lt;p&gt;Grâce à toutes les informations à sa disposition, le navigateur peut finalement choisir quelle image utiliser, en fonction des formats supportés, de la taille du viewport, du &lt;em&gt;pixel ratio&lt;/em&gt; de l&#39;écran, du cache, de la qualité de connexion...&lt;/p&gt;
&lt;p&gt;Voici le poids des dix images en fonction du format et de la dimension :&lt;/p&gt;
&lt;table&gt;
  &lt;caption&gt;Poids des images en fonction de leur format et dimension&lt;/caption&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;th scope=&quot;col&quot;&gt;avif&lt;/th&gt;
    &lt;th scope=&quot;col&quot;&gt;webp&lt;/th&gt;
    &lt;th scope=&quot;col&quot;&gt;jpeg&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;350px&lt;/th&gt;
    &lt;td&gt;🌟&amp;nbsp;147Ko&lt;/td&gt;
    &lt;td&gt;252Ko&lt;/td&gt;
    &lt;td&gt;321Ko&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&quot;row&quot;&gt;700px&lt;/th&gt;
    &lt;td&gt;249Ko&lt;/td&gt;
    &lt;td&gt;459Ko&lt;/td&gt;
    &lt;td&gt;624Ko&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;On varie donc du simple au quadruple ! Avec des images plus grandes, la différence sera encore plus importante.&lt;/p&gt;
&lt;h3 id=&quot;generer-les-images-avec-eleventy&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/#generer-les-images-avec-eleventy&quot;&gt;Générer les images avec Eleventy&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Plutôt être forcé à regarder la saison 29 de &lt;em&gt;Plus belle la vie&lt;/em&gt; que de produire à la main toutes les images nécessaires à cette optimisation.&lt;/p&gt;
&lt;p&gt;Pour rappel, on parle de 10 livres × 3 formats × 2 tailles, doit 60 images !&lt;/p&gt;
&lt;p&gt;Non, je souhaite prendre l&#39;image de la meilleure qualité possible, et laisser la machine faire le reste. Et là, merveille : Eleventy propose exactement ce qu&#39;il me faut.&lt;/p&gt;
&lt;p&gt;Nous allons créer un helper &lt;code&gt;bookImage&lt;/code&gt;, que nous appellerons pour chaque item :&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; bookImage item &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Un helper est une fonction qui retourne un template. Elle se déclare ainsi, encore une fois dans le fichier &lt;code&gt;.eleventy.js&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addLiquidShortcode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bookImage&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bookImage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bookImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;book&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;p&gt;Hello world !&amp;lt;/p&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rappel important : Eleventy étant un &lt;strong&gt;générateur de site statique&lt;/strong&gt;, ce JavaScript est exécuté une fois pour toutes lorsque le site est généré, et non pas au &lt;em&gt;runtime&lt;/em&gt; côté client. Le but est toujours d&#39;avoir un HTML statique au final.&lt;/p&gt;
&lt;p&gt;Dans notre helper, nous allons utiliser le plugin officiel &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/&quot;&gt;Image&lt;/a&gt;. Ça se passe comme ça :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; images &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;src/img/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;book&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fileSlug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;.jpg&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;widths&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;350&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;formats&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;avif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;webp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;jpeg&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;outputDir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_site/img&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si nous passons un objet &lt;code&gt;book&lt;/code&gt; et que nous avons bien un fichier image correspondant dans &lt;code&gt;src/img/&lt;/code&gt;, cette fonction va générer les 6 images nécessaires.&lt;/p&gt;
&lt;p&gt;Seule bizarrerie à mentionner, le &lt;code&gt;null&lt;/code&gt; dans la liste des largeurs, nécessaire au cas où l&#39;image source fait moins de &lt;code&gt;700px&lt;/code&gt; (la grande taille sera alors la taille originale de l&#39;image, par exemple &lt;code&gt;579px&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Ensuite, et je vous passe les détails d&#39;implémentation, nous allons retourner le template correspondant. Vous savez, le gros bout de code décrit plus haut avec toutes les &lt;code&gt;sources&lt;/code&gt;, &lt;code&gt;srcset&lt;/code&gt;...&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;picture class=&quot;book__cover&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;sources&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &amp;lt;img
    src=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;url&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
    alt=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;alt&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  /&gt;
&amp;lt;/picture&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Peut-être l&#39;avez vous remarqué, ce helper a de formidable qu&#39;il fait deux choses très importantes à la fois :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il génère les images nécessaires ;&lt;/li&gt;
&lt;li&gt;il renvoie le markup associé.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La séparation de ces deux processus est fréquente. Qu&#39;ils soient ici si intriqués facilitera certainement la maintenance.&lt;/p&gt;
&lt;p&gt;Une autre façon de le dire, c&#39;est que le template génère à la volée les images dont il a besoin !&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/generation.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : les images sont générées dans un dossier. Le processus peut être désactivé en développement pour gagner du temps.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;css-critique-inline&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/#css-critique-inline&quot;&gt;CSS critique inline&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Actuellement, la cascade du site ressemble à ça :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/G3Bdc9oSIz-390.avif 390w, https://bastiencalou.fr/img/G3Bdc9oSIz-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/G3Bdc9oSIz-390.webp 390w, https://bastiencalou.fr/img/G3Bdc9oSIz-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/G3Bdc9oSIz-390.webp&quot; alt=&quot;Trois étapes de chargement distinctes se suivent : d&#39;abord le HTML, puis le CSS/JS, puis les images.&quot; width=&quot;390&quot; height=&quot;125&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      J&#39;ai utilisé une simulation « slow 3G » pour forcer le trait.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;On voit nettement les deux ressources &lt;strong&gt;bloquantes&lt;/strong&gt; que sont le CSS et le JavaScript.&lt;/p&gt;
&lt;p&gt;Contrairement aux images, le CSS et le JavaScript bloquent l&#39;affichage de la page tant qu&#39;ils ne sont pas chargés, parsés et exécutés.&lt;/p&gt;
&lt;p&gt;Le client récupère le HTML, puis effectue deux nouvelles requêtes pour récupérer le CSS et le JavaScript. Il ne se passera rien d&#39;autre pendant ce temps. La page restera blanche et les images ne commenceront pas à se charger. Quel gâchis !&lt;/p&gt;
&lt;p&gt;Une bonne solution serait d&#39;utiliser un &lt;em&gt;server push&lt;/em&gt;, pour envoyer ces ressources avant même que le navigateur ne les ait demandé. Mais il faut pour cela avoir accès au serveur.&lt;/p&gt;
&lt;p&gt;Alors me vient une pensée impure :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mon CSS ne fait que 4ko, qu&#39;est ce qui m&#39;empêche de le mettre directement dans le HTML lors du build ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Il s&#39;agit en réalité d&#39;une technique très efficace appelée &lt;em&gt;Critical CSS Inline&lt;/em&gt;, qui consiste à placer le CSS nécessaire au rendu de ce que l&#39;on voit en premier directement dans le HTML. On charge ensuite le reste du CSS en asynchrone, sans bloquer la page.&lt;/p&gt;
&lt;p&gt;Dans mon cas, le CSS critique représente la quasi totalité de ma petite page, mais la technique n&#39;en est pas moins intéressante.&lt;/p&gt;
&lt;p&gt;Je vais ici faire appel au plugin &lt;a href=&quot;https://github.com/gregives/eleventy-critical-css&quot;&gt;eleventy-critical-css&lt;/a&gt;, qui cette fois n&#39;est pas officiel mais créé par la communauté.&lt;/p&gt;
&lt;p&gt;Je n&#39;ai pas grand chose à dire sur l&#39;utilisation tant elle est directe :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prod&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;criticalCss&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;assetPaths&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;_site/index.html&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;minify&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C&#39;est tout !&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/arHc1ya2JY-390.avif 390w, https://bastiencalou.fr/img/arHc1ya2JY-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/arHc1ya2JY-390.webp 390w, https://bastiencalou.fr/img/arHc1ya2JY-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/arHc1ya2JY-390.webp&quot; alt=&quot;Le code source du HTML dans lequel on peut voir du CSS minifié.&quot; width=&quot;390&quot; height=&quot;126&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Le CSS critique est extrait puis directement inclus dans l&#39;index.html.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;En plus d&#39;inclure le CSS critique, le plugin ajoute la ligne suivante :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;./css/styles.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;print&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onload&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;media&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;all&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette technique permet de charger le reste du CSS en asynchrone. En effet, le navigateur charge les CSS associées au media &lt;code&gt;print&lt;/code&gt; en asynchrone par défaut. Une fois ceci fait, la destination de la feuille de style est mise à jour de &lt;code&gt;print&lt;/code&gt; vers &lt;code&gt;all&lt;/code&gt; grâce à &lt;code&gt;onload=&amp;quot;this.media=&#39;all&#39;&lt;/code&gt;. Habile.&lt;/p&gt;
&lt;h3 id=&quot;et-le-javascript&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/#et-le-javascript&quot;&gt;Et le JavaScript ?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Quand au JavaScript, qui sert uniquement à gérer l&#39;ouverture fluide des éléments &lt;code&gt;details&lt;/code&gt; sur mobile, l&#39;attribut &lt;code&gt;async&lt;/code&gt; sera idéal :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;./dist/script.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si l&#39;utilisateur venait à cliquer sur un élément &lt;code&gt;details&lt;/code&gt; avant que le script ne soit chargé, il s&#39;ouvrirait alors sans transition, soit son comportement par défaut. Quand le JavaScript arrive, on utilise donc l&#39;approche d&#39;amélioration progressive sur ces éléments pour améliorer l&#39;expérience.&lt;/p&gt;
&lt;p&gt;Résultat, nous n&#39;avons plus aucune ressource bloquante !&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/rExt8zBd36-390.avif 390w, https://bastiencalou.fr/img/rExt8zBd36-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/rExt8zBd36-390.webp 390w, https://bastiencalou.fr/img/rExt8zBd36-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/rExt8zBd36-390.webp&quot; alt=&quot;Seules deux étapes sont visibles : d&#39;abord le HTML, ensuite tout le reste en parallèle.&quot; width=&quot;390&quot; height=&quot;106&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Nous avons ainsi drastiquement amélioré le &lt;strong&gt;chemin critique&lt;/strong&gt;, soit cet instant crucial entre la requête et l&#39;affichage de la page.&lt;/p&gt;
&lt;p&gt;En une seule requête, notre utilisateur verra un contenu.&lt;/p&gt;
&lt;p&gt;Mon petit projet effectue désormais un chargement initial de &lt;strong&gt;128k&lt;/strong&gt; et s&#39;affiche en moins d&#39;une seconde.&lt;/p&gt;
&lt;h2 id=&quot;un-site-performant-c&#39;est-forcement-moche&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/optimisation-agressive-des-performances-d-un-site-statique/#un-site-performant-c&#39;est-forcement-moche&quot;&gt;Un site performant, c&#39;est forcément moche ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Il n&#39;y a rien de plus faux ! Il n&#39;y a &lt;strong&gt;aucune&lt;/strong&gt; corrélation entre la beauté d&#39;un site et sa performance. Si vous avez les bons designers et les bons développeurs, les deux sont parfaitement compatibles.&lt;/p&gt;
&lt;p&gt;Ne me croyez pas sur parole : voici une &lt;a href=&quot;https://www.11ty.dev/speedlify/&quot;&gt;liste d&#39;autres sites générés avec Eleventy&lt;/a&gt;, qui atteignent les 100 points sur tous les critères, tout en étant bien plus riches que le mien.&lt;/p&gt;
&lt;p&gt;Ces 100 points ne sont d&#39;ailleurs qu&#39;un point de départ : mon petit projet les atteignait avant même les optimisations décrites dans cet article. Ils ne doivent donc pas nous empêcher d&#39;aller plus loin !&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Eleventy — Pour un web simple, performant et accessible</title>
		<link href="https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/"/>
		<updated>2021-06-14T00:00:00Z</updated>
		<id>https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/</id>
		<content type="html">&lt;p&gt;Et si nous gardions Vue, React et ses compagnons pour les web app &lt;em&gt;vraiment&lt;/em&gt; complexes ? Et s&#39;ils devenaient &lt;strong&gt;l&#39;exception à la règle&lt;/strong&gt;, plutôt que d&#39;être notre modèle mental par défaut ?&lt;/p&gt;
&lt;p&gt;Tant de sites ne sont pas si complexes que ça ! Portfolios, sites vitrines, documentation en ligne, blogs... Ce web là mérite bien mieux que la complexité et les coûts qu&#39;engendrent l&#39;utilisation de nos frameworks JS favoris.&lt;/p&gt;
&lt;p&gt;Une des ces nombreuses alternatives s&#39;appelle &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Eleventy&lt;/a&gt;. Il s&#39;agit un générateur de site statique, dont je suis totalement tombé sous le charme pour sa simplicité et son efficacité.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Le site sur lequel vous lisez cet article est fait lui aussi avec Eleventy !&lt;/div&gt;
&lt;h2 id=&quot;ca-sert-a-quoi&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#ca-sert-a-quoi&quot;&gt;Ça sert à quoi ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pour découvrir la bête, j&#39;ai réalisé un site tout simple présentant &lt;a href=&quot;https://top-livres.netlify.app/&quot;&gt;mes 10 livres préférés de l&#39;année&lt;/a&gt; (entends-je une remarque sur mon sens inestimable du design ?).&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/hLBjTJQgDz-390.avif 390w, https://bastiencalou.fr/img/hLBjTJQgDz-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/hLBjTJQgDz-390.webp 390w, https://bastiencalou.fr/img/hLBjTJQgDz-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/hLBjTJQgDz-390.webp&quot; alt=&quot;Une capture d&#39;écran du site montrant une liste de livres et leurs descriptions.&quot; width=&quot;390&quot; height=&quot;221&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      C&#39;est pas moche, c&#39;est sobre.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Le site est totalement statique : à cette adresse se trouve un fichier HTML, accompagné d&#39;un peu de CSS et de JS. Pour la performance, on ne fait pas mieux.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/ijJtDDFOg_-390.avif 390w, https://bastiencalou.fr/img/ijJtDDFOg_-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/ijJtDDFOg_-390.webp 390w, https://bastiencalou.fr/img/ijJtDDFOg_-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/ijJtDDFOg_-390.webp&quot; alt=&quot;L&#39;outil lighthouse montre des scores de 100/100 dans les quatres catégories : performance, accessibilité, bonnes pratiques et référencement.&quot; width=&quot;390&quot; height=&quot;189&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Les scores des divers outils en ligne ne se substituent pas à l&#39;analyse humaine, mais permettent de vérifier que l&#39;essentiel est là.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Certes, le site est basique, mais j&#39;aurais tout aussi bien pu le générer grâce à un appel GraphQL, une boucle React et autres joyeusetés. Sauf qu&#39;on ne bat pas la simplicité. &lt;q&gt;Boring code is good code&lt;/q&gt;, qu&#39;ils disent.&lt;/p&gt;
&lt;p&gt;Pour autant, je ne me suis pas amusé à écrire à la main les 770 lignes de ce fichier, très redondantes (10 répétitions du composant permettant d&#39;afficher un livre et sa description).&lt;/p&gt;
&lt;p&gt;C&#39;est ici qu&#39;&lt;strong&gt;Eleventy&lt;/strong&gt; entre en scène.&lt;/p&gt;
&lt;h2 id=&quot;comment-ca-marche&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#comment-ca-marche&quot;&gt;Comment ça marche ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Si on voulait résumer grossièrement, on pourrait présenter Eleventy ainsi :&lt;/p&gt;
&lt;pre&gt;&lt;code tabindex=&quot;0&quot;&gt;données + templates = ♡ HTML ♡
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;markdown-la-base-de-donnees&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#markdown-la-base-de-donnees&quot;&gt;Markdown, la « base de données »&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Chaque livre représenté dans le site est un fichier &lt;code&gt;markdown&lt;/code&gt; (d&#39;autres formats, tels que &lt;code&gt;JSON&lt;/code&gt; sont possibles). Voici par exemple celui pour le livre &lt;em&gt;Dune&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; book
&lt;span class=&quot;token key atrule&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dune
&lt;span class=&quot;token key atrule&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Frank Herbert
&lt;span class=&quot;token key atrule&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1965&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;896&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#cf5441&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;publisher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Pocket
&lt;span class=&quot;token key atrule&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; https&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//www.lisez.com/livre&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;de&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;poche/dune/9782266320481
&lt;span class=&quot;token key atrule&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Ce pavé a la réputation d&#39;être un peu chiant&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; et oui&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bon&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; peut&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;être&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; faut rentrer dedans comme on dit&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Les trois tirets au début et à la fin permettent de définir une table. Le reste est assez direct.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Note : Il serait formidable de pouvoir typer les objets, avec chaque type de champ et des champs optionnels...&lt;/div&gt;
&lt;p&gt;Voici donc ma belle liste de livres :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/GmnLyBVZLP-390.avif 390w, https://bastiencalou.fr/img/GmnLyBVZLP-780.avif 780w, https://bastiencalou.fr/img/GmnLyBVZLP-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/GmnLyBVZLP-390.webp 390w, https://bastiencalou.fr/img/GmnLyBVZLP-780.webp 780w, https://bastiencalou.fr/img/GmnLyBVZLP-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/GmnLyBVZLP-390.webp&quot; alt=&quot;La liste des 10 fichiers markdown.&quot; width=&quot;780&quot; height=&quot;233&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Si nous sommes très, très loin d&#39;une base de données telle qu&#39;on l&#39;entend habituellement, cette simplicité vient avec ses avantages : il est ultra simple de mettre à jour le contenu.&lt;/p&gt;
&lt;p&gt;Je n&#39;ai qu&#39;à modifier le fichier (potentiellement directement sur Github), et le process automatique de build que je décris plus loin se mettra en action. Corollaire : les données sont versionnées et il devient difficile d&#39;en perdre.&lt;/p&gt;
&lt;p&gt;On ne pourra certes pas faire du relationnel bien avancé, mais pour notre exemple, c&#39;est parfait !&lt;/p&gt;
&lt;h3 id=&quot;rendre-disponible-les-donnees&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#rendre-disponible-les-donnees&quot;&gt;Rendre disponible les données&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Par défaut, il est déjà possible de boucler sur cette collection de livres, qui sera ordonnée par date de création des fichiers markdown.&lt;/p&gt;
&lt;p&gt;C&#39;est bien pratique pour les posts d&#39;un blog, mais dans mon cas je souhaite avoir une collection ordonnée par ordre alphabétique. Il faut alors la déclarer dans un fichier dédié, &lt;code&gt;.eleventy.js&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addCollection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;itemsAscending&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  collection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFilteredByGlob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;src/items/*.md&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Un peu de travail manuel, certes, mais en contrepartie, une grande liberté.&lt;/p&gt;
&lt;p&gt;Je pourrais trier par année, par auteur, ou même créer une sous-collection contenant uniquement les livres de moins de 100 pages. Après tout, ce n&#39;est que du JavaScript : on fait exactement ce qu&#39;on veut.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Important : Ce JavaScript n&#39;est pas exécuté côté client, mais bien lors de la génération du HTML statique, que je détaille ensuite.&lt;/div&gt;
&lt;h3 id=&quot;templating&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#templating&quot;&gt;Templating&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;De nombreux langages de templating sont compatibles. J&#39;ai choisi &lt;code&gt;liquid&lt;/code&gt; pour une raison qui a totalement disparu de mon esprit (probablement parce qu&#39;il n&#39;y avait aucune raison).&lt;/p&gt;
&lt;p&gt;Voici donc la boucle du fichier &lt;code&gt;index.liquid&lt;/code&gt; qui va générer les livres :&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;main&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; item &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; collections&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;itemsAscending &lt;span class=&quot;token delimiter punctuation&quot;&gt;-%}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;include&lt;/span&gt; src/partials/item &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;-%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans le fichier &lt;code&gt;item.liquid&lt;/code&gt; dont voici un extrait, la syntaxe parle d&#39;elle-même :&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item__title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;subtitle &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h3&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item__subtitle&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;subtitle &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C&#39;est simple, c&#39;est bien 👌&lt;/p&gt;
&lt;h3 id=&quot;vous-prendrez-bien-un-peu-de-css-js&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#vous-prendrez-bien-un-peu-de-css-js&quot;&gt;Vous prendrez bien un peu de CSS / JS ?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Oui, mais à condition de pouvoir utiliser &lt;code&gt;SASS&lt;/code&gt; et du JavaScript moderne !&lt;/p&gt;
&lt;p&gt;Pour satisfaire ces besoins, Eleventy utilise un système de &lt;a href=&quot;https://www.11ty.dev/docs/plugins/&quot;&gt;plugins&lt;/a&gt; très simples à utiliser.&lt;/p&gt;
&lt;p&gt;Encore une fois, ça se passe dans le fichier de configuration &lt;code&gt;.eleventy.js&lt;/code&gt;. Pour le CSS, d&#39;abord :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; prod &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ELEVENTY_ENV&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;prod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sass&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/styles/**/*.scss&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;outputDir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_site/css&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;cleanCSS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prod&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;sourcemaps&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;prod&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Le booléen &lt;code&gt;prod&lt;/code&gt; nous permettra de minifier le CSS uniquement en production, et de générer des &lt;em&gt;sourcemaps&lt;/em&gt; uniquement en développement.&lt;/p&gt;
&lt;p&gt;Même système pour le JavaScript :&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;babel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/js/script.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;outputDir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_site/js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;uglify&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prod&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Il n&#39;y a pas grand chose à ajouter. Si je peux éviter de tout câbler à la main à chaque projet, tant mieux (je t&#39;aime toujours, Gulp).&lt;/p&gt;
&lt;h3 id=&quot;action-!&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#action-!&quot;&gt;Action !&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Tout est en place. Voici la commande que j&#39;utilise pour lancer le serveur de développement :&lt;/p&gt;
&lt;pre&gt;&lt;code tabindex=&quot;0&quot;&gt;eleventy --input=src --serve
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Les données markdown sont injectées dans les templates, eux-même transformés en bon vieux HTML.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--input=src&lt;/code&gt; désigne le dossier dans lequel j&#39;ai placé tout mon code source (&lt;code&gt;liquid&lt;/code&gt;, &lt;code&gt;markdown&lt;/code&gt;, &lt;code&gt;css&lt;/code&gt;...).&lt;/p&gt;
&lt;p&gt;Le flag &lt;code&gt;--serve&lt;/code&gt; vous créera un petit &lt;em&gt;live server&lt;/em&gt; à rechargement automatique. À chaque fois que vous changez un fichier, le HTML final est régénéré, en un dixième de seconde de mon côté.&lt;/p&gt;
&lt;p&gt;Et voici la commande de build :&lt;/p&gt;
&lt;pre&gt;&lt;code tabindex=&quot;0&quot;&gt;ELEVENTY_ENV=prod eleventy --input=src
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En utilisant un service tel que &lt;a href=&quot;https://app.netlify.com/&quot;&gt;Netlify&lt;/a&gt; (pour qui travaille le créateur d&#39;Eleventy, tout est lié), il ne vous reste plus qu&#39;à renseigner la commande à lancer et le dossier généré à servir (&lt;code&gt;_site&lt;/code&gt; pour Eleventy).&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/6ZG8zB8oWV-390.avif 390w, https://bastiencalou.fr/img/6ZG8zB8oWV-650.avif 650w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/6ZG8zB8oWV-390.webp 390w, https://bastiencalou.fr/img/6ZG8zB8oWV-650.webp 650w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/6ZG8zB8oWV-390.webp&quot; alt=&quot;La configuration Netlify.&quot; width=&quot;325&quot; height=&quot;72&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      La commande &lt;code&gt;build&lt;/code&gt; contient l&#39;appel à Eleventy.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Le projet Netlify étant lié au projet Github, chaque push ou modification du code sur Github mettra à jour le site en une poignée de secondes.&lt;/p&gt;
&lt;h2 id=&quot;un-meilleur-web&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#un-meilleur-web&quot;&gt;Un meilleur web ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;À nouveau, il est évident qu&#39;un outil tel qu&#39;Eleventy n&#39;est pas adapté à des applications à forte complexité métier, et ce n&#39;est pas le terrain sur lequel il joue.&lt;/p&gt;
&lt;p&gt;En revanche, nous avons désormais un site :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;léger&lt;/strong&gt;, car rien ne peut battre du HTML ;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;performant&lt;/strong&gt;, le CPU n&#39;étant pas sollicité par une montagne de JavaScript ;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;accessible&lt;/strong&gt;, pour peu que le HTML soit écrit correctement bien sûr ;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;explorable&lt;/strong&gt; par les moteurs de recherche ;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;prédictible&lt;/strong&gt;, dans le sens où la complexité se situe côté serveur ;&lt;/li&gt;
&lt;li&gt;aisément &lt;strong&gt;modifiable&lt;/strong&gt; et rapidement &lt;strong&gt;déployable&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bref, des objectifs parfois mis à mal lorsqu&#39;on utilise des outils inadaptés, mais des objectifs essentiels...&lt;/p&gt;
&lt;p&gt;Voici un web qui me plaît !&lt;/p&gt;
&lt;p&gt;Retrouvez le code complet de ce projet sur &lt;a href=&quot;https://github.com/bcalou/top-books-2020&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-jamstack&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/eleventy-pour-un-web-simple-performant-et-accessible/#la-jamstack&quot;&gt;La Jamstack&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Eleventy fait partie de l&#39;approche &lt;a href=&quot;https://jamstack.org/&quot;&gt;Jamstack&lt;/a&gt;, qui se définit par des termes souvent obscurs, mais dont le point le plus important est sans doute la génération en avance des sites côté back : le &lt;em&gt;pre-rendering&lt;/em&gt;.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/p4_EwwfxRd-390.avif 390w, https://bastiencalou.fr/img/p4_EwwfxRd-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/p4_EwwfxRd-390.webp 390w, https://bastiencalou.fr/img/p4_EwwfxRd-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/p4_EwwfxRd-390.webp&quot; alt=&quot;Logo Jamstack.&quot; width=&quot;390&quot; height=&quot;205&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;&lt;a href=&quot;https://jamstack.org/generators/&quot;&gt;Beaucoup de générateurs&lt;/a&gt; sont d&#39;ailleurs disponibles. Eleventy a la réputation de faire partie des plus simples, ce que j&#39;ai largement pu vérifier par moi-même.&lt;/p&gt;
&lt;p&gt;J&#39;aime particulièrement le fait qu&#39;il ne soit pas lié à un langage ou un framework en particulier. Bref, Je le conserve précieusement dans ma boîte à outils.&lt;/p&gt;
&lt;p&gt;La prochaine fois, ne vous demandez pas &lt;q&gt;Quel framework JS vais-je choisir ?&lt;/q&gt;, mais bien &lt;q&gt;Suis-je dans l&#39;absolue nécessité d&#39;en utiliser un ?&lt;/q&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Que se passe-t-il lorsque vous écrivez un sélecteur CSS invalide ?</title>
		<link href="https://bastiencalou.fr/que-se-passe-t-il-lorsque-vous-ecrivez-un-selecteur-css-invalide-de-terribles-choses/"/>
		<updated>2020-12-07T00:00:00Z</updated>
		<id>https://bastiencalou.fr/que-se-passe-t-il-lorsque-vous-ecrivez-un-selecteur-css-invalide-de-terribles-choses/</id>
		<content type="html">&lt;p&gt;J&#39;aimerais parler d&#39;un comportement très spécifique de CSS qui pourrait vous causer quelques maux de tête si vous n&#39;en avez pas connaissance.&lt;/p&gt;
&lt;p&gt;Créons un bouton :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Click me&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Je souhaite que ce bouton change de couleur lorsqu&#39;il est pressé. Avec la pseudo-classe &lt;code&gt;:active&lt;/code&gt;, c&#39;est facile.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;button:active&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;OJXYNag&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/OJXYNag&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Jusqu&#39;ici, tout va bien.&lt;/p&gt;
&lt;p&gt;Pour améliorer l&#39;accessibilité, je veux appliquer le même effet lorsque le bouton est ciblé à l&#39;aide du clavier ou d&#39;une technologie d&#39;assistance (et ne rien faire de spécial si le focus vient de la souris).&lt;/p&gt;
&lt;p&gt;Cela est possible grâce à la nouvelle pseudo-classe &lt;code&gt;:focus-visible&lt;/code&gt;. À l&#39;heure où j&#39;écris ces lignes, elle est supportée sans préfixe par &lt;a href=&quot;https://caniuse.com/?search=focus-visible&quot;&gt;Chrome et Edge&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : La pseudo-classe est désormais supportée par tous les navigateurs majeurs 🎉.&lt;/div&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;button:active,
button:focus-visible&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;bGeyyPo&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/bGeyyPo&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Si vous utilisez Chrome ou Edge, vous pouvez essayer de cibler le bouton avec la touche &lt;kbd&gt;Tab&lt;/kbd&gt;. Vous devriez alors voir les styles appliqués par le sélecteur &lt;code&gt;:focus-visible&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/focus.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : un bouton obtient le focus du navigateur et ses couleurs s&#39;inversent.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Ceci est d&#39;une grande aide si vous n&#39;utilisez pas la souris.&lt;/p&gt;
&lt;h2 id=&quot;mais-il-y-a-un-probleme&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/que-se-passe-t-il-lorsque-vous-ecrivez-un-selecteur-css-invalide-de-terribles-choses/#mais-il-y-a-un-probleme&quot;&gt;Mais il y a un problème&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pouvez-vous deviner ce qui se passera sur des navigateurs plus vieux ? Bien entendu, les styles associés à &lt;code&gt;:focus-visible&lt;/code&gt; ne s&#39;appliqueront pas, mais un effet de bord, peut-être ?&lt;/p&gt;
&lt;p&gt;On perd aussi les styles de la pseudo-classe &lt;code&gt;:active&lt;/code&gt; !&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/firefox.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : le bouton est préssé, mais il ne change pas de couleur.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Les styles associés à la pseudo-classe &lt;code&gt;:active&lt;/code&gt; ne s&#39;appliquent pas sur Firefox, bien que ce navigateur comprenne parfaitement ce sélecteur. Tristesse infinie.&lt;/p&gt;
&lt;p&gt;Le problème vous paraît peut-être évident si vous le connaissez, mais lorsque j&#39;ai dû le débugger au sein d&#39;un fichier CSS bien plus complexe, il m&#39;a ennuyé pour quelques bonnes minutes. Et je ne pense pas que ce soit un fait très connu des débutants.&lt;/p&gt;
&lt;p&gt;Comment dire ?&lt;/p&gt;
&lt;h2 id=&quot;si-quelconque-partie-du-selecteur-echoue-la-totalite-du-selecteur-echoue&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/que-se-passe-t-il-lorsque-vous-ecrivez-un-selecteur-css-invalide-de-terribles-choses/#si-quelconque-partie-du-selecteur-echoue-la-totalite-du-selecteur-echoue&quot;&gt;Si quelconque partie du sélecteur échoue, la totalité du sélecteur échoue&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;En d&#39;autres termes, si un navigateur ne connaît pas le sélecteur &lt;code&gt;:focus-within&lt;/code&gt;, il ignorera la totalité de votre règle, y compris la partie concernant le sélecteur &lt;code&gt;:active&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On pourrait dire que CSS est légèrement susceptible. S&#39;il n&#39;aime pas le type d&#39;olive que vous avez mis sur la pizza, il n&#39;envisagera même pas de la manger.&lt;/p&gt;
&lt;p&gt;Voici la spécification du W3C :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Lors de l&#39;interprétation d&#39;une liste de déclarations, une syntaxe inconnue à quelconque position provoque l&#39;arrêt du parser. Ce dernier avance jusqu&#39;à ce qu&#39;il trouve un point-virgule (ou la fin du bloc). Il recommence alors à zéro avec la déclaration suivante.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-syntax-3/#error-handling&quot;&gt;Error-handling&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Et voici donc le correctif qu&#39;il vous faudra utiliser : séparer les styles « sûrs » des styles plus exotiques.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;button:active&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;button:focus-visible&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;oNzbByo&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/oNzbByo&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Maintenant, le sélecteur &lt;code&gt;:focus-visible&lt;/code&gt; pourrait être ignoré, mais ne dérangera pas le sélecteur &lt;code&gt;:active&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;mais-pourquoi-ce-comportement&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/que-se-passe-t-il-lorsque-vous-ecrivez-un-selecteur-css-invalide-de-terribles-choses/#mais-pourquoi-ce-comportement&quot;&gt;Mais pourquoi ce comportement ?&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Pas si robuste pour un langage qui devrait s&#39;adapter à autant de situations, n&#39;est-ce pas ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;CSS est cassé ! JS seul peut nous sauver !&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Il se trouve qu&#39;il y a en réalité une bonne raison pour cela, qui est expliquée dans un vieux document à propos de CSS 2 :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;CSS 2.2 donne un sens particulier à la virgule (,) dans les sélecteurs. Cependant, puisque nous ne savons pas si la virgule pourrait acquérir de nouveaux sens dans de futures versions de CSS, l&#39;ensemble de l&#39;instruction devrait être ignorée s&#39;il y a une erreur où que ce soit dans le sélecteur, même si le reste du sélecteur semble acceptable en CSS 2.2.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS22/syndata.html#rule-sets&quot;&gt;Rule sets, declaration blocks, and selectors&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Les concepteurs de CSS ont fait preuve d&#39;une impressionnante capacité d&#39;anticipation. En effet, voici quelques sélecteurs CSS que nous pourrons utiliser tôt ou tard (et pour certains, c&#39;est déjà le cas) :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* h1.title, h2.title, h3.title */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.title:is(h1, h2, h3)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* exclusions multiples */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.title:not(h1, h2)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* sélecteur de parent */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;section:has(img, figure)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ces sélecteurs contiennent des virgules, mais ces virgules ne séparent pas des sélecteurs de premier niveau.&lt;/p&gt;
&lt;p&gt;Si un navigateur ne comprend pas &lt;code&gt;:is&lt;/code&gt; et essaie de séparer notre premier exemple, cela pourrait donner quelque chose de ce genre :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;code&gt;.title.is(h1&lt;/code&gt; : c&#39;est quoi ce truc ? Je passe à la suite.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;h2&lt;/code&gt; : ciblons tous les &lt;code&gt;h2&lt;/code&gt;, même ceux qui n&#39;ont pas la classe &lt;code&gt;.title&lt;/code&gt; !&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;h3)&lt;/code&gt; : hein ?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;astuce&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/que-se-passe-t-il-lorsque-vous-ecrivez-un-selecteur-css-invalide-de-terribles-choses/#astuce&quot;&gt;Astuce&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Certains développeurs ont même utilisé ce comportement comme une astuce pour discriminer un navigateur précis.&lt;/p&gt;
&lt;p&gt;Vous voulez appliquer un style à tous les navigateurs sauf à Internet Explorer ? Vous n&#39;avez qu&#39;à ajouter un sélecteur moderne simplement destiné à ce qu&#39;Internet Explorer ignore la règle.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.covfefe:not(div),
h1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; red&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tadaa, le &lt;code&gt;h1&lt;/code&gt; sera rouge seulement si le navigateur comprend &lt;code&gt;:not&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Avec la bonne combinaison de sélecteurs, vous pourriez cibler ou exclure n&#39;importe quelle version spécifique d&#39;un navigateur. Ce qui, bien entendu, est très sale, et je l&#39;espère plus nécessaire aujourd&#39;hui 🙏.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Flexbox : les marges négatives à la rescousse</title>
		<link href="https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/"/>
		<updated>2020-11-02T00:00:00Z</updated>
		<id>https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/</id>
		<content type="html">&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : Bonne nouvelle, la technique décrite dans cet article est devenue pratiquement obsolète grâce au &lt;a href=&quot;https://caniuse.com/flexbox-gap&quot;&gt;large support de la propriété gap&lt;/a&gt; par les navigateurs modernes.&lt;/div&gt;
&lt;p&gt;La gestion des espaces avec flexbox n&#39;est pas aussi simple qu&#39;elle en a l&#39;air. Voici une simple astuce que j&#39;ai beaucoup utilisée ces derniers temps.&lt;/p&gt;
&lt;h2 id=&quot;le-probleme&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#le-probleme&quot;&gt;Le problème&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici notre HTML pour cette démo :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hello World&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;HTML&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;CSS&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;JavaScript&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Front-end dev&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Web&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Lorem ipsum...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C&#39;est un article avec une liste de tags. Avec un peu de CSS basique, voici à quoi il ressemble.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;dyXdqOL&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/dyXdqOL&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Nous souhaitons que la liste des tags soit un conteneur flex, avec la possibilité d&#39;un retour à la ligne. Allons-y !&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comme vous pouvez le voir, j&#39;ai aussi ajouté de l&#39;espace après chaque élément &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;, &lt;code&gt;2em&lt;/code&gt; étant égal à &lt;code&gt;32px&lt;/code&gt; pour un texte basique (avec l&#39;avantage de s&#39;adapter aux préférences de l&#39;utilisateur et à la taille de font de l&#39;élément lui-même).&lt;/p&gt;
&lt;p&gt;Et voici le résultat :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;WNxMgpp&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/WNxMgpp&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Cela peut sembler assez bien, mais le diable est dans les détails.&lt;/p&gt;
&lt;p&gt;Regardez le coin inférieur droit de l&#39;article : je l&#39;ai rendu redimensionnable pour que vous puissez simuler un redimensionnement du navigateur.&lt;/p&gt;
&lt;p&gt;Il y a deux problèmes principaux. Pouvez-vous les repérer ?&lt;/p&gt;
&lt;h2 id=&quot;le-probleme-horizontal&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#le-probleme-horizontal&quot;&gt;Le problème horizontal&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le premier problème est qu&#39;à cause de sa marge à droite, le dernier élément passe à la ligne trop tôt.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/wrap.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : l&#39;article est réduit en largeur jusqu&#39;à ce que le dernier tag de la liste passe à la ligne.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Remarquez-vous comme le dernier élément aurait suffisamment d&#39;espace pour aller plus loin à droite avant de revenir à la ligne ? Comparez cet espace à l&#39;espace à gauche du premier élement.&lt;/p&gt;
&lt;p&gt;Il serait possible de corriger ce problème en excluant le dernier élément de cette règle :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;li:not(:last-child)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;mdEXGvE&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/mdEXGvE&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Mais le problème est le même : tous les autres élément reviennent à la ligne trop tôt.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/autres.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : l&#39;article est réduit en largeur et les tags passent les uns après les autres à la ligne.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Désormais, le dernier élement peut aller plus loin vers la droite, mais les autres provoquent un retour à la ligne prématuré.&lt;/p&gt;
&lt;p&gt;Bon, si &lt;code&gt;margin-right&lt;/code&gt; ne convient pas, que dire de &lt;code&gt;margin-left&lt;/code&gt; ? Essayons de l&#39;utiliser sur chaque élément, à l&#39;exception du premier, qui ne devrait pas être précédé par un espace.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;li:not(:first-child)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;BazrZQv&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/BazrZQv&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Est-ce mieux désormais ? Prenez un moment pour essayer de deviner quel pourrait être le problème.&lt;/p&gt;
&lt;p&gt;Puisqu&#39;il n&#39;y a plus de marge à droite, le retour à la ligne a lieu exactement quand il le faut. Mais maintenant, notre problème est ailleurs :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/left.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : l&#39;article est réduit en largeur et le dernier élément passe à la ligne, avec un décalage vers la droite par rapport au premier de la ligne du dessus.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Nous ne sommes pas vraiment en position de nous plaindre. Nous avons demandé à CSS que tous les éléments sauf le premier aient une marge à gauche, et c&#39;est ce qui se passe.&lt;/p&gt;
&lt;p&gt;Comme il serait agréable de pouvoir exclure les éléments étant les premiers de leur ligne ! Mais il n&#39;y a pas de sélecteur magique comme celui-ci :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;li:not(:first-flex-row-item)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* N&#39;existe pas */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Un tel sélecteur hypothétique pourrait causer une &lt;em&gt;dépendance circulaire&lt;/em&gt;. Par exemple, je pourrais dire que le premier élément d&#39;une ligne a une petite taille de font. Cela pourrait permettre à l&#39;élément de retourner sur la ligne précédente (car il prendrait moins de place). Il ne serait donc plus ciblé par le sélecteur, reprendrait sa taille originale, reviendrait sur la seconde ligne et... 🤯&lt;/p&gt;
&lt;p&gt;Les dépendances circulaires sont une des raisons principales pour lesquelles nous n&#39;avons pas encore accès aux &lt;a href=&quot;https://css-tricks.com/lets-not-forget-about-container-queries/&quot;&gt;container queries&lt;/a&gt;. Mais c&#39;est une autre histoire.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : Après des années d&#39;effort, les &lt;i&gt;containers queries&lt;/i&gt; sont désormais &lt;a href=&quot;https://caniuse.com/css-container-queries&quot;&gt;bien supportées !&lt;/a&gt;&lt;/div&gt;
&lt;h2 id=&quot;l&#39;astuce-de-la-marge-negative&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#l&#39;astuce-de-la-marge-negative&quot;&gt;L&#39;astuce de la marge négative&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici donc la solution : d&#39;abord, tous les éléments reçoivent un &lt;code&gt;margin-left&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;yLJKPXy&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/yLJKPXy&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Nous devons maintenant nous débarrasser de l&#39;espace à gauche du premier élément, et nous pouvons faire cela à l&#39;aide de marges négatives.&lt;/p&gt;
&lt;p&gt;Les marges négatives ne sont pas considérées comme faisant partie des bonnes pratiques, et je pense qu&#39;il faut les éviter autant que possible, car elles peuvent rendre la logique de votre code plus difficile à comprendre.&lt;/p&gt;
&lt;p&gt;Ceci étant dit, elles sont &lt;a href=&quot;https://www.w3.org/TR/CSS2/box.html#margin-properties&quot;&gt;autorisées par le w3c&lt;/a&gt; et offrent un très bon support navigateur.&lt;/p&gt;
&lt;p&gt;Et dans notre cas, elles nous sauvent la mise :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;MWeVomw&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/MWeVomw&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/9NLXmeg-A4-390.avif 390w, https://bastiencalou.fr/img/9NLXmeg-A4-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/9NLXmeg-A4-390.webp 390w, https://bastiencalou.fr/img/9NLXmeg-A4-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/9NLXmeg-A4-390.webp&quot; alt=&quot;Des bordures bleues montrent que la liste des éléments est décalée vers la droite jusqu&#39;en dehors de son parent, pour que le premier élément paraisse visuellement au bon endroit.&quot; width=&quot;390&quot; height=&quot;254&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Une bordure bleue sur l&#39;élément &lt;code&gt;ul&lt;/code&gt; révèle l&#39;astuce.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;et-l&#39;axe-vertical&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#et-l&#39;axe-vertical&quot;&gt;Et l&#39;axe vertical ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Devinez quoi, c&#39;est la même chose !&lt;/p&gt;
&lt;p&gt;Il est impossible de cibler tous les éléments en excluant ceux qui sont sur la première ligne.&lt;/p&gt;
&lt;p&gt;Il faut donc donner à tout le monde une marge supérieure.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;zYBWzdo&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/zYBWzdo&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;À cause de cet ajout, la liste apparaît plus bas que ce que nous souhaitons.&lt;/p&gt;
&lt;p&gt;Il serait possible de retirer la propriété &lt;code&gt;margin-bottom: 1em&lt;/code&gt; du titre pour compenser.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/VCFfiT-btI-390.avif 390w, https://bastiencalou.fr/img/VCFfiT-btI-628.avif 628w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/VCFfiT-btI-390.webp 390w, https://bastiencalou.fr/img/VCFfiT-btI-628.webp 628w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/VCFfiT-btI-390.webp&quot; alt=&quot;La marge entre le titre et les éléments est équivalente à la marge ajoutée au dessus des éléments.&quot; width=&quot;314&quot; height=&quot;285&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Retirer la marge sous le titre (zone jaune) compenserait le nouvel espace à l&#39;intérieur de l&#39;élement &lt;code&gt;ul&lt;/code&gt; (bordures bleues).
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Mais j&#39;essaie de toujours &lt;strong&gt;garder mes éléments indépendants du contexte&lt;/strong&gt;. La liste pourrait apparaître sous un autre élément quelque part ailleurs. Ou le titre pourrait être suivi par autre chose que cette liste.&lt;/p&gt;
&lt;p&gt;Nous devons donc utiliser la même astuce et appliquer une marge négative à notre liste :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -1em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voici notre version finale. Elle fonctionne sur tous les navigateurs qui supportent correctement flexbox, y compris Internet Explorer 11.&lt;/p&gt;
&lt;h2 id=&quot;et-la-propriete-gap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#et-la-propriete-gap&quot;&gt;Et la propriété &lt;code&gt;gap&lt;/code&gt; ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les articles tels que celui-ci deviendront obsolète lorsque la propriété CSS &lt;code&gt;gap&lt;/code&gt; sera largement supportée.&lt;/p&gt;
&lt;p&gt;Mais ce n&#39;est pas encore le cas. À l&#39;heure où j&#39;écris ces lignes, le &lt;a href=&quot;https://caniuse.com/flexbox-gap&quot;&gt;support navigateur est de 70%&lt;/a&gt;. Pas super, comparé au support à 99% de flexblox lui-même – Safari serait-il devenu le nouvel Internet Explorer ?&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : Après ce qui a semblé être une petite période de flottement, Safari s&#39;est repris en main et a rattrapé une bonne partie de son retard sur ses concurrents. Ce cliché n&#39;a plus lieu d&#39;être.&lt;/div&gt;
&lt;p&gt;Tous les autres navigateurs modernes devraient vous montrer le même résultat avec le code suivant, sans astuce !&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1em 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* row-gap + column-gap */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* Plus de style sur les items eux-mêmes */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;zYBWRaO&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/zYBWRaO&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Le point embêtant est qu&#39;il n&#39;est pas possible de détecter le support de cette propriété. Prenez le code suivant :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@supports&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1em 2em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* Désactiver les astuces et utiliser la solution propre */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La syntaxe &lt;code&gt;@supports&lt;/code&gt; permet d&#39;appliquer des règles uniquement si le navigateur comprend ce qui se trouve entre les parenthèses.&lt;/p&gt;
&lt;p&gt;Le problème est que &lt;code&gt;gap&lt;/code&gt; est également une propriété utilisée pour les grilles CSS, avec un bien meilleur support de 92%. Mais cela ne signifie pas que la propriété fonctionnera pour flexbox.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/w3c/csswg-drafts/issues/3559&quot;&gt;Le problème est étudié&lt;/a&gt; par le &lt;em&gt;CSS Working Group&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;En attendant, vive les marges négatives.&lt;/p&gt;
&lt;h2 id=&quot;et-maintenant-avec-des-variables&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#et-maintenant-avec-des-variables&quot;&gt;Et maintenant, avec des variables ✨&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nous pouvons améliorer notre code et le rendre plus générique si besoin. J&#39;aime séparer mon CSS produisant des éléments BEM sémantiques et mes classes utilitaires. Je vais donc créer une classe utilitaire &lt;code&gt;u-flex&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Je ne suis pas un grand fan du fait d&#39;avoir des classes orientées style dans mon HTML, et je pourrais donc utiliser une mixin SASS pour parvenir au même résultat, mais vous saisissez l&#39;idée.&lt;/p&gt;
&lt;p&gt;Utilisons les variables CSS, qui sont très bien supportées (95%). En CSS, il est possible d&#39;obtenir l&#39;opposé d&#39;une valeur en la multipliant par &lt;code&gt;-1&lt;/code&gt;. Voici un exemple :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* -2em */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Voici donc notre classe utilitaire :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.u-flex&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--row-gap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;-1 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--column-gap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.u-flex &gt; *&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--row-gap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--column-gap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;J&#39;aime utiliser le sélecteur d&#39;enfant direct (&lt;code&gt;&amp;gt; *&lt;/code&gt;) avec flexbox et grid. Il s&#39;accorde très bien avec la relation parent/enfants de ces fonctionnalités et fonctionnera à tous les coups.&lt;/p&gt;
&lt;p&gt;Et voici comment je l&#39;utiliserai :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;u-flex&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;HTML&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;CSS&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;JavaScript&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Front-end dev&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Web&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--row-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--column-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;oNLqEQz&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/oNLqEQz&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Le pouvoir des variables CSS nous permet de définir des espaces différents pour chaque élément ciblé. Nous pourrions même définir des valeurs par défaut pour l&#39;ensemble du document :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--row-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--column-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ainsi, nous n&#39;avons besoin de changer les variables localement que si nous souhaitons une valeur différente.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : Plutôt que des variables à la racine, l&#39;utilisation d&#39;une valeur par défaut serait plus appropriée, par exemple : &lt;code&gt;var(--row-gap, 1em);&lt;/code&gt;&lt;/div&gt;
&lt;h2 id=&quot;mauvaises-pratiques&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/flexbox-les-marges-negatives-a-la-rescousse/#mauvaises-pratiques&quot;&gt;Mauvaises pratiques&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nous connaissons toutes et tous un tas de mauvaises pratiques : &lt;code&gt;!important&lt;/code&gt; est une autre qui me vient à l&#39;esprit. Mais comme les marges négatives, même &lt;code&gt;!important&lt;/code&gt; a des cas d&#39;usages légitimes.&lt;/p&gt;
&lt;p&gt;Cet astuce de la marge négative est un rappel pour moi : les choses que l&#39;on apprend à éviter pourraient nous être bien utiles un jour ou l&#39;autre. Tout dépend du contexte.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>HTML n&#39;est pas un langage de programmation et c’est sa plus grande qualité</title>
		<link href="https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/"/>
		<updated>2020-10-21T00:00:00Z</updated>
		<id>https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/</id>
		<content type="html">&lt;div class=&quot;postAside&quot;&gt;
  &lt;p&gt;Mise à jour 2024 : Mon avis sur la question a évolué. HTML n&#39;est certes pas un langage de programmation &lt;strong&gt;impératif&lt;/strong&gt;, mais &lt;a href=&quot;https://briefs.video/videos/is-html-a-programming-language/&quot; title=&quot;Vidéo: HTML est-il un langage de programmation ? (en anglais)&quot;&gt;les arguments&lt;/a&gt; pour le considérer comme un langage de programmation &lt;strong&gt;déclaratif&lt;/strong&gt; me semblent tout à fait fondés.&lt;/p&gt;
  &lt;p&gt;Je ne souhaite pas modifier l&#39;article car il correspond à mes vues de l&#39;époque, mais gardez cette disctinction sémantique en tête : j&#39;ai utilisé le terme « langage de programmation » incorrectement à la place de « langage de programmation &lt;strong&gt;impératif&lt;/strong&gt; ».&lt;/p&gt;
  &lt;p&gt;Les autres points sont toujours d&#39;actualité !&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;J&#39;adore HTML. Plus j&#39;en apprends à son sujet, plus je trouve que c&#39;est un travail de génie. Par dessus tout, j&#39;adore qu&#39;il ne s&#39;agisse pas d&#39;un langage de programmation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Les langages de programmation sont nuls&lt;/strong&gt;. Ils plantent en permanence (je vous jure, j&#39;écris toujours mon JavaScript parfaitement du premier coup, et pourtant il persiste à planter !?).&lt;/p&gt;
&lt;p&gt;Pire, quand ils plantent, la plupart du temps, l&#39;ensemble du programme s&#39;écrase ! Autant essayer d&#39;empiler des cure-dents sur un viaduc par plein vent.&lt;/p&gt;
&lt;p&gt;Mais comparez cela à la beauté qu&#39;est HTML :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nav&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Home&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;products.html&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Products&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;about.html&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;About&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nav&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ceci est un magnifique et sémantique bout de HTML5. Il contribue à l&#39;accessibilité, à la lisibilité, à l&#39;application des styles, à la découverte du contenu par les robots.&lt;/p&gt;
&lt;p&gt;Et il ne plante pas.&lt;/p&gt;
&lt;p&gt;Si un vieux navigateur ne connaît pas HTML5, il traitera l&#39;élément &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; comme une bonne vieille &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, et &lt;strong&gt;cela fonctionnera&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Si un développeur ou un utilisateur avec un éditeur de code (par exemple dans l&#39;administration d&#39;un WordPress) écrit &lt;code&gt;nax&lt;/code&gt; au lieu de &lt;code&gt;nav&lt;/code&gt;, &lt;strong&gt;cela fonctionnera toujours&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Prenons un autre exemple :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;summary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;HTML&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;summary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  HTML is an acronym for HyperText Markup Language.
  It was created by Tim Berners-Lee in 1989.
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tout le monde ne connaît pas l&#39;élément &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;, voici donc ce qu&#39;il produira dans un navigateur moderne :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;oNbRWJZ&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/oNbRWJZ&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Je n&#39;ai pas &lt;em&gt;programmé&lt;/em&gt; ce comportement (les développeurs de navigateur l&#39;ont programmé). J&#39;ai &lt;em&gt;décrit&lt;/em&gt; le contenu du document et fait confiance au navigateur pour l&#39;afficher du mieux qu&#39;il pouvait. Et je pense que cela est très, très sympa.&lt;/p&gt;
&lt;p&gt;Et cela fonctionnera aussi avec les vieux navigateurs : il n&#39;y aura pas d&#39;interactivité, mais le contenu sera affiché et c&#39;est bien le plus important.&lt;/p&gt;
&lt;h2 id=&quot;restez-calme-et-arretez-de-programmer&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/#restez-calme-et-arretez-de-programmer&quot;&gt;Restez calme et arrêtez de programmer&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je ne veux pas programmer. Je dois souvent le faire, quand HTML n&#39;est pas suffisant pour décrire ce que mon site devrait faire. Et comme beaucoup d&#39;entre nous, mon quotidien tourne autour des frameworks JavaScript, et j&#39;aime beaucoup certains d&#39;entre eux.&lt;/p&gt;
&lt;p&gt;Mais quand je pense à l&#39;utilisateur, je sais que la pire chose que je puisse faire est de programmer.&lt;/p&gt;
&lt;p&gt;À chaque fois que je programme, j&#39;ai l&#39;impression de signer une étrange décharge dans mon esprit :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Par la présente, je reconnais que j&#39;introduis un comportement non-standard dans ce site web, déchargeant le navigateur de sa responsabilité d&#39;assurer une expérience fiable pour chaque utilisateur. Je fais cela en ayant consience de ma connaissance partielle des technologies web, de l&#39;existence de limites dans mes implémentations, temporelles et techniques, qui ne peuvent être estimées. Je réalise que ce que je fais échouera probablement à un certain moment ou dans certaines situations. Mais je n&#39;ai pas le choix et je promets de ne pas merder.&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/mEsEziB8lN-390.avif 390w, https://bastiencalou.fr/img/mEsEziB8lN-500.avif 500w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/mEsEziB8lN-390.webp 390w, https://bastiencalou.fr/img/mEsEziB8lN-500.webp 500w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/mEsEziB8lN-390.webp&quot; alt=&quot;La petite sirène signant un contrat diabolique.&quot; width=&quot;250&quot; height=&quot;139&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;À l&#39;inverse, quand j&#39;utilise HTML et les standards du web, je me repose sur la connaissance partagée de développeurs de navigateurs expérimentés et des décennies de débats ayant pour but de faire du web une plate-forme de qualité.&lt;/p&gt;
&lt;p&gt;Et c&#39;est pour cela qu&#39;une connaissance profonde du HTML est infiniment précieuse : cela apporte tout simplement de la qualité à l&#39;utilisateur, ce qui au bout du compte est la seule chose d&#39;importance.&lt;/p&gt;
&lt;h2 id=&quot;resilience&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/#resilience&quot;&gt;Résilience&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dans une de mes meilleures lectures de cette année, Jeremy Keith nous raconte comment nous avons presque perdu l&#39;un des aspects les plus puissants de HTML à cause de XHTML 2.0 :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;[XHTML 2.0] avait aussi pour but d&#39;implémenter la draconienne gestion des erreurs de XML. S&#39;il y a la moindre erreur dans un document XML – un attribut sans guillemets ou un slash de fermeture manquant – alors le &lt;i&gt;parser&lt;/i&gt; doit s&#39;arrêter immédiatement et refuser de rendre quoi que ce soit.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Jeremy Keith, &lt;cite&gt;&lt;a href=&quot;https://resilientwebdesign.com/chapter4/&quot;&gt;Resilient Web Design&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Dieu merci, nous sommes passés à côté de cela.&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;XHTML 2.0 est mort prématurément. Sa pureté théorique fut fermement rejetée par les personnes qui vivaient de la création de sites web.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Jeremy Keith, &lt;cite&gt;&lt;a href=&quot;https://resilientwebdesign.com/chapter4/&quot;&gt;Resilient Web Design&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/3Qj-ctvoEP-390.avif 390w, https://bastiencalou.fr/img/3Qj-ctvoEP-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/3Qj-ctvoEP-390.webp 390w, https://bastiencalou.fr/img/3Qj-ctvoEP-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/3Qj-ctvoEP-390.webp&quot; alt=&quot;Un vaisseau rebelle de Star Wars fait chuter un chasseur robot de l&#39;empire.&quot; width=&quot;390&quot; height=&quot;219&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Source : &lt;a href=&quot;https://speakerdeck.com/elkraneo/html5&quot;&gt;https://speakerdeck.com/elkraneo/html5&lt;/a&gt;
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;html-est-il-difficile&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/#html-est-il-difficile&quot;&gt;HTML est-il difficile ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bien sûr, pour qu&#39;HTML soit un si bon langage, vous devez le connaître. Je veux dire, &lt;em&gt;vraiment&lt;/em&gt; le connaître.&lt;/p&gt;
&lt;p&gt;La sémantique, l&#39;accessibilité, le référencement, les compatibilités navigateurs et les styles par défaut, les nouvelles balises et les balises obsolètes, les attributs spécifiques liés au langage et au temps, les formulaires, l&#39;optimisation des performances, les métadonnées, les médias...&lt;/p&gt;
&lt;p&gt;Même sans parler des « soupes de balise » générées par certains frameworks, il y a une grande différence entre un bon code HTML et un code HTML excellent.&lt;/p&gt;
&lt;p&gt;Ce serait une erreur de considérer HTML (et CSS) comme la partie facile du développement web. Le problème est qu&#39;il faut bien connaître ces langages pour réaliser cela.&lt;/p&gt;
&lt;p&gt;JavaScript est difficile. Pourquoi tout le monde sait-il cela ? Parce qu&#39;avant de réussir à faire fonctionner quoi que ce soit, vous devrez affrontez une avalanche d&#39;erreurs rouges bloquant votre projet entier. Seul un pénible débuggage vous permettra d&#39;avoir un code fonctionnel.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/xyEgLx3olF-390.avif 390w, https://bastiencalou.fr/img/xyEgLx3olF-700.avif 700w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/xyEgLx3olF-390.webp 390w, https://bastiencalou.fr/img/xyEgLx3olF-700.webp 700w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/xyEgLx3olF-390.webp&quot; alt=&quot;Une présentatrice de télévision crie : tu a un console log... tu as un console log... tout le monde a un console log !&quot; width=&quot;350&quot; height=&quot;262&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;On ne peut pas échouer avec HTML. On peut écrire de la soupe de balises, des mauvais formulaires et ne suivre aucune bonne pratique, mais cela n&#39;échouera pas, à cause de la résilience fondamentale de HTML.&lt;/p&gt;
&lt;p&gt;La première fois que l&#39;on écrit du JavaScript, cela semble être un sacré bazar. La première fois que l&#39;on écrit du HTML, on se sent comme un génie du web.&lt;/p&gt;
&lt;p&gt;Ce n&#39;est qu&#39;avec le temps et les connaissances que l&#39;on réalise que le génie, ce n&#39;est pas soi : les concepteurs d&#39;HTML sont les génies, et ils nous ont donné un superbe outil qui nécessite beaucoup de pratique et de patience pour s&#39;en servir &lt;em&gt;vraiment&lt;/em&gt; correctement.&lt;/p&gt;
&lt;p&gt;La permissivité d&#39;HTML a donné l&#39;opportunité à beaucoup de personnes de contribuer au web et n&#39;est sans doute pas pour rien dans l&#39;expansion de l&#39;invention de Tim Berners-Lee. Mais pour les développeurs professionnels, cette permissivité vient avec la responsabilité de ne pas se reposer sur cette simplicité apparente et de vraiment apprendre à maîtriser ce puissant langage.&lt;/p&gt;
&lt;h2 id=&quot;la-crise-d&#39;identite-des-langages-web&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/#la-crise-d&#39;identite-des-langages-web&quot;&gt;La crise d&#39;identité des langages web&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La manière dont nous nommons les choses est importante. Il est très frustrant de voir la partie HTML/CSS d&#39;un projet dévaluée si souvent lorsqu&#39;on en connaît l&#39;aspect critique. Il est insoutenable d&#39;entendre des développeurs déclarer qu&#39;ils ne se &lt;q&gt;préoccupent pas du CSS&lt;/q&gt;, alors qu&#39;&lt;strong&gt;afficher des pixels sur un écran&lt;/strong&gt; est quasiment la définition de notre métier.&lt;/p&gt;
&lt;p&gt;Peut-être qu&#39;appeler HTML un langage de programmation le rend plus digne d&#39;attention pour certaines personnes ? Il serait naïf d&#39;ignorer les biais salariaux et même le sexisme liés à cette affaire. Car oui, HTML/CSS est la partie présentation et cela est plus... féminin ?&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/KVqfYCCogh-315.avif 315w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/KVqfYCCogh-315.webp 315w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/KVqfYCCogh-315.webp&quot; alt=&quot;Michael Scott se frotte le crâne avec sa main, visiblement très ennuyé.&quot; width=&quot;158&quot; height=&quot;113&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;D&#39;un autre côté, je comprends que lire que HTML est un langage de programmation peut ennuyer certains, moi compris. Pas parce que je pense que les langages de progammation sont meilleurs. Parce que &lt;strong&gt;je ne veux pas qu&#39;HTML soit un langage de programmation&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;nous-construisons-juste-des-choses&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/html-n-est-pas-un-langage-de-programmation-et-c-est-sa-plus-grande-qualite/#nous-construisons-juste-des-choses&quot;&gt;Nous construisons juste des choses&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Durant mes cours, j&#39;utilise souvent le terme « langage de développement ». Je ne le vois pas beaucoup utilisé en anglais, mais je trouve que c&#39;est un très bon terme.&lt;/p&gt;
&lt;p&gt;Avec cette appellation, on peut réunir HTML, CSS et JavaScript sans que tout le monde ne crie au scandale. D&#39;après le dictionnaire :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Développer : inventer quelque chose ou donner vie à quelque chose.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;&lt;cite&gt;&lt;a href=&quot;https://dictionary.cambridge.org/fr/dictionnaire/anglais/develop&quot;&gt;Cambridge dictionnary&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Alors que le débat autour d&#39;HTML/CSS étant ou non des langages de programmation semble pouvoir durer jusqu&#39;à la fin des temps, le fait qu&#39;ils sont utilisés, parfois aux côtés de JavaScript, pour &lt;q&gt;donner vie à quelque chose&lt;/q&gt;, ne semble pas être matière à controverse.&lt;/p&gt;
&lt;p&gt;Qui se soucie de si vous programmez ou non ? La seule chose d&#39;importance est la qualité de ce que vous construisez.&lt;/p&gt;
&lt;p&gt;Il va falloir remettre la non-programmation à la mode.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Pourquoi vous devriez toujours déclarer une background-color</title>
		<link href="https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/"/>
		<updated>2020-06-03T00:00:00Z</updated>
		<id>https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/</id>
		<content type="html">&lt;p&gt;Raphael Schweikert a commenté le premier article de cette série avec quelques points particulièrement intéressants :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Je me souviens des années 1990 où la plupart des navigateurs avaient une couleur de fond grise. Internet Explorer était le seul à avoir un fond blanc par défaut. Les autres ont suivi.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Raphael Schweikert, &lt;cite&gt;&lt;a href=&quot;https://dev.to/sabberworm/comment/pgbd&quot;&gt;Commentaire sur l&#39;article « Quelle est la couleur d&#39;une page blanche ? »&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/rdcl59vAvR-390.avif 390w, https://bastiencalou.fr/img/rdcl59vAvR-632.avif 632w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/rdcl59vAvR-390.webp 390w, https://bastiencalou.fr/img/rdcl59vAvR-632.webp 632w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/rdcl59vAvR-390.webp&quot; alt=&quot;Le navigateur Netscape et son fond gris.&quot; width=&quot;316&quot; height=&quot;238&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Même si comme moi vous n&#39;avez pas connu cette époque, vous avez probablement déjà croisé ces aperçus grisâtres du passé.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Internet Explorer a donc pris une décision fondatrice pour le web tel que nous le connaissons aujourd&#39;hui : le blanc.&lt;/p&gt;
&lt;h2 id=&quot;et-aujourd&#39;hui&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/#et-aujourd&#39;hui&quot;&gt;Et aujourd&#39;hui ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Raphael a aussi expliqué que cette couleur pouvait être modifiée. Dans Firefox, c&#39;est simple :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;ouvrez la page &lt;code&gt;about:config&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;cherchez le paramètre &lt;code&gt;browser.display.&lt;wbr /&gt;background_color&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;la valeur par défaut est &lt;code&gt;#ffffff&lt;/code&gt;. Changez-la !&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ce n&#39;est pas une option secrète de développeur : toutes les options mentionnées dans cet article peuvent être configurée par n&#39;importe qui, en utilisant &lt;a href=&quot;https://support.mozilla.org/en-US/kb/change-fonts-and-colors-websites-use&quot;&gt;une interface plus sympathique&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/hloBsHYNDe-390.avif 390w, https://bastiencalou.fr/img/hloBsHYNDe-570.avif 570w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/hloBsHYNDe-390.webp 390w, https://bastiencalou.fr/img/hloBsHYNDe-570.webp 570w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/hloBsHYNDe-390.webp&quot; alt=&quot;Une série de paramètres pour changer la couleur du texte et de l&#39;arrière-plan du navigateur.&quot; width=&quot;285&quot; height=&quot;176&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Le panneau de configuration des couleurs sous Firefox.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Tous les navigateurs ne gèrent pas cela de la même façon : Chrome, par exemple, vous encourage à utiliser des &lt;a href=&quot;https://support.google.com/chrome/answer/7040464?hl=en&quot;&gt;extensions et des thèmes&lt;/a&gt;. Dans tous les cas, voici l&#39;idée : l&#39;utilisateur n&#39;aura pas nécessairement un arrière-plan de navigateur blanc. Comme toujours, nos présuppositions sont nos ennemies. Nous ne savons rien.&lt;/p&gt;
&lt;h2 id=&quot;que-se-passe-t-il-lorsque-l&#39;arriere-plan-du-navigateur-n&#39;est-pas-blanc&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/#que-se-passe-t-il-lorsque-l&#39;arriere-plan-du-navigateur-n&#39;est-pas-blanc&quot;&gt;Que se passe-t-il lorsque l&#39;arrière-plan du navigateur n&#39;est pas blanc ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Imaginons que je sois fan des modes sombres et que je définisse la couleur de l&#39;arrière-plan de mon navigateur en utilisant la valeur &lt;code&gt;#000000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le premier effet, c&#39;est que lorsque rien n&#39;est montré, car je suis en train de passer d&#39;un site vers un autre en cours de chargement, mon écran est noir.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/switch.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : le passage d&#39;un site à un autre. Pendant le temps de chargement du second site, l&#39;écran est noir.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Un utilisateur de Reddit a expliqué cette astuce dans un post intitulé « &lt;a href=&quot;https://www.reddit.com/r/firefox/comments/e89nmg/how_to_not_get_blinded_by_white_light_when/&quot;&gt;Comment ne pas être aveuglé à l&#39;ouverture d&#39;un nouveau site ?&lt;/a&gt; » C&#39;est en effet une amélioration immédiate, mais l&#39;histoire n&#39;est pas si simple.&lt;/p&gt;
&lt;p&gt;Un autre post dont j&#39;adore le titre complète le tableau : « &lt;a href=&quot;https://support.mozilla.org/en-US/questions/1229066&quot;&gt;J&#39;ai changé l&#39;arrière-plan pour du noir. Je ne vois plus rien.&lt;/a&gt; »&lt;/p&gt;
&lt;p&gt;Oups ! En utilisant du noir pour la couleur d&#39;arrière-plan, cet utilisateur a rendu le web... invisible.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/--Gh1sLYgm-390.avif 390w, https://bastiencalou.fr/img/--Gh1sLYgm-640.avif 640w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/--Gh1sLYgm-390.webp 390w, https://bastiencalou.fr/img/--Gh1sLYgm-640.webp 640w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/--Gh1sLYgm-390.webp&quot; alt=&quot;Un ordinateur dont l&#39;écran est complètement invisible, laissant apparaître le mur derrière lui.&quot; width=&quot;320&quot; height=&quot;262&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Rappelons-nous de ce qu&#39;explique le W3C :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Si l&#39;arrière-plan du canvas n&#39;est pas opaque, ce qui est visible en dessous dépendra de l&#39;agent utilisateur.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#body-background&quot;&gt;The Canvas Background and the HTML &amp;lt;body&amp;gt; Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Cela signifie que si vous ne donnez pas de couleur d&#39;arrière-plan à votre page (couleur qui remplira le canvas), le fond du navigateur sera visible.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/UCR4o-nGNt-390.avif 390w, https://bastiencalou.fr/img/UCR4o-nGNt-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/UCR4o-nGNt-390.webp 390w, https://bastiencalou.fr/img/UCR4o-nGNt-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/UCR4o-nGNt-390.webp&quot; alt=&quot;Les quatres couches du navigateur : body, html, canvas et fond du navigateur.&quot; width=&quot;390&quot; height=&quot;358&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Il est possible de voir le fond du navigateur si le canvas est transparent à cause de l&#39;absence d&#39;une couleur de fond sur la page.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Bien qu&#39;une majorité de site déclare explicitement une couleur de fond blanche, ce n&#39;est pas toujours le cas, et c&#39;est ainsi que le web peut devenir invisible.&lt;/p&gt;
&lt;p&gt;Voici ce à quoi TechCrunch ressemble avec le fond de mon navigateur en noir :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/U0P0NOCzPY-390.avif 390w, https://bastiencalou.fr/img/U0P0NOCzPY-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/U0P0NOCzPY-390.webp 390w, https://bastiencalou.fr/img/U0P0NOCzPY-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/U0P0NOCzPY-390.webp&quot; alt=&quot;Le site de TechCrunch avec un arrière-plan noir. Le texte, noir également, est invisible.&quot; width=&quot;390&quot; height=&quot;193&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Le correctif est très simple :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/N7VGMRc9ao-390.avif 390w, https://bastiencalou.fr/img/N7VGMRc9ao-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/N7VGMRc9ao-390.webp 390w, https://bastiencalou.fr/img/N7VGMRc9ao-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/N7VGMRc9ao-390.webp&quot; alt=&quot;Le site de TechCrunch avec un arrière-plan blanc. Le texte noir est bien visible.&quot; width=&quot;390&quot; height=&quot;197&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Et voici donc un conseil de Raphael :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;J&#39;ai donné à mon navigateur une couleur d&#39;arrière-plan grise pour vérifier si je n&#39;ai pas accidentellement oublié de déclarer &lt;code&gt;background: white&lt;/code&gt; sur une page qui devrait avoir un fond blanc.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Raphael Schweikert, &lt;cite&gt;&lt;a href=&quot;https://dev.to/sabberworm/comment/pgbd&quot;&gt;Commentaire sur l&#39;article « Quelle est la couleur d&#39;une page blanche ? »&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Cela semble être une très bonne astuce et m&#39;a donné envie d&#39;écrire ce nouvel article.&lt;br /&gt;
Le désavantage est que vous verrez un fond gris sur TechChrunch et les autres « sites transparents » (sauf si vous utilisez un environnement différent pour le développement et la navigation classique, bien sûr).&lt;/p&gt;
&lt;h2 id=&quot;y-a-t-il-beaucoup-de-sites-transparents&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/#y-a-t-il-beaucoup-de-sites-transparents&quot;&gt;Y a-t-il beaucoup de sites transparents ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bien que cela ne soit pas représentatif du « web », j&#39;ai testé les 100 sites les plus visités, et &lt;strong&gt;14% d&#39;entre eux ont un canvas transparent&lt;/strong&gt;, laissant apparaître la couleur de fond jaune que j&#39;ai utilisée pour mener mon enquête.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/bVKVNZZgTA-390.avif 390w, https://bastiencalou.fr/img/bVKVNZZgTA-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/bVKVNZZgTA-390.webp 390w, https://bastiencalou.fr/img/bVKVNZZgTA-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/bVKVNZZgTA-390.webp&quot; alt=&quot;Le site de l&#39;organisation mondiale de la santé avec un fond jaune.&quot; width=&quot;390&quot; height=&quot;233&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Une couleur de fond pas si bonne que ça pour la santé.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Parmi eux : le Wall Street Journal, Paypal, Vimeo, AOL, la BBC...&lt;/p&gt;
&lt;p&gt;Cela fait quelques jours que je garde cet horrible fond jaune comme arrière-plan et ce chiffre de 14% me semble cohérent avec ma navigation quotidienne. Je peux vous assurer que lire du texte sur ce fond est une excellente motivation pour terminer cet article.&lt;/p&gt;
&lt;h2 id=&quot;et-l&#39;utilisateur-alors&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/#et-l&#39;utilisateur-alors&quot;&gt;Et l&#39;utilisateur, alors ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Vous pensez peut-être :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Si l&#39;utilisateur décide d&#39;avoir du noir en tant que couleur d&#39;arrière-plan, peut-être a t-il ses raisons et peut-être ne faut-il pas interférer ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;C&#39;est compliqué. Qui peut bien changer ce fond blanc « universel » ?&lt;/p&gt;
&lt;p&gt;Cela pourrait être l&#39;utilisateur. Cela pourrait être l&#39;agent utilisateur lui-même (qui pourrait être un ordinateur, un téléphone, mais aussi &lt;a href=&quot;https://deviceatlas.com/blog/which-devices-have-browsers&quot;&gt;tout un tas d&#39;autres choses&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Il est peut-être impossible d&#39;avoir des statistiques à ce propos, mais nous pouvons être sûr d&#39;une chose : une fraction indeterminée d&#39;utilisateurs n&#39;aura &lt;em&gt;pas&lt;/em&gt; un fond blanc. Et un site transparent ne s&#39;affichera pas correctement.&lt;/p&gt;
&lt;p&gt;Sauf si l&#39;utilisateur ou le navigateur change également la couleur par défaut du texte. Dans Firefox, c&#39;est simple : il faut changer le paramètre &lt;code&gt;browser.display.foreground_color&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tous les textes dont la couleur n&#39;est pas spécifiée en CSS utiliseront cette valeur. Retournons sur TechCrunch :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/0KozWqbLq7-390.avif 390w, https://bastiencalou.fr/img/0KozWqbLq7-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/0KozWqbLq7-390.webp 390w, https://bastiencalou.fr/img/0KozWqbLq7-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/0KozWqbLq7-390.webp&quot; alt=&quot;Le site de TechCrunch avec un arrière-plan noir. Une partie du texte est en blanc et donc lisible, mais une grande partie est toujours en noir et illisible.&quot; width=&quot;390&quot; height=&quot;195&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Ce n&#39;est pas génial. Oui, une partie du texte est désormais affichée en blanc. Mais il ne s&#39;agit que du texte dont la couleur n&#39;a pas été spécifiée en CSS. Et comme il est courant pour le texte d&#39;avoir une couleur légèrement différente du noir, il y a toujours une grande partie du contenu qui ne peut être lue.&lt;/p&gt;
&lt;p&gt;Pour que cela fonctionne, il faudrait un site &lt;strong&gt;sans couleur de fond ni couleur de texte explicite&lt;/strong&gt;.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/daBwx704Kv-390.avif 390w, https://bastiencalou.fr/img/daBwx704Kv-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/daBwx704Kv-390.webp 390w, https://bastiencalou.fr/img/daBwx704Kv-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/daBwx704Kv-390.webp&quot; alt=&quot;Un site présentant un texte simple, blanc sur noir et lisible.&quot; width=&quot;390&quot; height=&quot;231&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Il n&#39;y a pas de CSS sur &lt;a href=&quot;http://motherfuckingwebsite.com/&quot;&gt;motherfuckingwebsite.com&lt;/a&gt;, cela fonctionne donc très bien.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Notez que vous pouvez également définir la couleur des liens, du texte recevant le focus, etc... Mais la même règle s&#39;applique : cela ne fonctionnera que si aucun CSS ne s&#39;applique, ce qui est improbable sur la plupart des sites. Un clash de couleur est inévitable.&lt;/p&gt;
&lt;p&gt;Nous avons donc deux solutions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ne rien spécifier et avoir un design extrêmement simple qui s&#39;adaptera aux couleurs définies par le navigateur ;&lt;/li&gt;
&lt;li&gt;spécifier une couleur de fond &lt;strong&gt;et&lt;/strong&gt; une couleur de texte.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&#39;est pourquoi vous pourriez vouloir ajouter les lignes suivantes à votre kit de base :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela me semble rentrer dans la catégorie des situations « très spécifiques mais si simples à résoudre qu&#39;il serait bien dommage de ne pas le faire ». On ne sait jamais sur quelle étrange combinaison de caractéristiques navigateur notre site va tomber.&lt;/p&gt;
&lt;h2 id=&quot;alors-quel-est-l&#39;interet-de-changer-les-couleurs-du-navigateur&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/#alors-quel-est-l&#39;interet-de-changer-les-couleurs-du-navigateur&quot;&gt;Alors quel est l&#39;intérêt de changer les couleurs du navigateur ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je suis un grand partisan du fait de respecter les choix de l&#39;utilisateur (ou de son navigateur). Le CSS que nous écrivons ne devrait pas être une série d&#39;ordres impératifs pour générer une page au pixel près, mais un ensemble d&#39;indications que le navigateur peut utiliser, entre autres choses, pour savoir à quoi doit ressembler le résultat.&lt;/p&gt;
&lt;p&gt;D&#39;un autre côté, il me semble avoir établi qu&#39;il est plus sûr de « forcer » la couleur de l&#39;arrière-plan et du texte d&#39;un site, sans quoi il pourrait rapidement devenir illisible.&lt;/p&gt;
&lt;p&gt;Heureusement, les deux approches peuvent être réconciliées, car nos navigateurs sont malins. Et c&#39;est le dernier paramètre que je souhaite aborder : &lt;code&gt;browser.display.document_color_use&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Quand ce paramètre vaut &lt;code&gt;2&lt;/code&gt;, Firefox supplantera &lt;strong&gt;toutes les couleurs CSS&lt;/strong&gt; et utilisera celles définies par l&#39;utilisateur ou Firefox lui-même. En d&#39;autres termes :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Je me fiche de ton CSS, utilise ces couleurs !&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Essayons à nouveau ce mode sombre improvisé en donnant à Firefox un arrière-plan noir et des textes blancs. Cette fois, le CSS ne pourra pas écraser nos choix, grâce au paramètre &lt;code&gt;document_color_use&lt;/code&gt;.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/fKfreUG-OA-390.avif 390w, https://bastiencalou.fr/img/fKfreUG-OA-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/fKfreUG-OA-390.webp 390w, https://bastiencalou.fr/img/fKfreUG-OA-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/fKfreUG-OA-390.webp&quot; alt=&quot;Le site de TechCrunch avec un arrière-plan noir et un texte clair, bien lisible.&quot; width=&quot;390&quot; height=&quot;191&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Cela fonctionne enfin ! J&#39;ai même changé la couleur des liens pour utiliser quelque chose qui me convient mieux. Le CSS n&#39;a pas changé, mais Firefox l&#39;a supplanté.&lt;/p&gt;
&lt;p&gt;Maintenant que le navigateur ne peut qu&#39;utiliser l&#39;ensemble de couleurs que nous avons défini, il est plus probable que les sites s&#39;affichent de façon convenable.&lt;/p&gt;
&lt;p&gt;J&#39;ai testé les 14 sites transparents du top 100, et chacun d&#39;entre-eux s&#39;affichait correctement. J&#39;estime qu&#39;environ 95% du contenu présentait une très bonne lisibilité avec mes couleurs customisées. Mais bien sûr, cela n&#39;est pas parfait.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/rETzM0Tny--390.avif 390w, https://bastiencalou.fr/img/rETzM0Tny--780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/rETzM0Tny--390.webp 390w, https://bastiencalou.fr/img/rETzM0Tny--780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/rETzM0Tny--390.webp&quot; alt=&quot;La page d&#39;accueil de Vimeo. La plupart des contenus sont lisibles, blanc sur noir.&quot; width=&quot;390&quot; height=&quot;195&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      La page d&#39;accueil de Vimeo présente une bonne lisibilité... Avec des exceptions notables pour le logo et les liens en haut à droite.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Notez que lorsque vous utilisez le paramètre &lt;code&gt;document_color_use&lt;/code&gt;, tous les sites sont impactés, pas seulement les transparents.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/O5F7WuQtCQ-390.avif 390w, https://bastiencalou.fr/img/O5F7WuQtCQ-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/O5F7WuQtCQ-390.webp 390w, https://bastiencalou.fr/img/O5F7WuQtCQ-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/O5F7WuQtCQ-390.webp&quot; alt=&quot;Le site dev.to avec un fond noir et un texte clair.&quot; width=&quot;390&quot; height=&quot;249&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Le site dev.to a une couleur d&#39;arrière-plan, qui est supplantée par mes paramètres Firefox.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Cela ne remplacera pas un mode sombre intégré (et &lt;a href=&quot;http://dev.to/&quot;&gt;dev.to&lt;/a&gt; en possède un), mais la plupart du temps le résultat est correct.&lt;/p&gt;
&lt;p&gt;De manière plus générale, cette option est également très intéressante pour l&#39;accessibilité. Voici TechCrunch avec le paramètre &lt;code&gt;document_color_use&lt;/code&gt; activé et les couleurs par défaut de Firefox :&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/4qhCyFL6ZR-390.avif 390w, https://bastiencalou.fr/img/4qhCyFL6ZR-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/4qhCyFL6ZR-390.webp 390w, https://bastiencalou.fr/img/4qhCyFL6ZR-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/4qhCyFL6ZR-390.webp&quot; alt=&quot;La page d&#39;accueil de TechChrunch. Les liens sont bleus (couleur par défaut de Firefox) et ressortent très bien.&quot; width=&quot;390&quot; height=&quot;192&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Wow, ça fait beaucoup de liens. Presque tout le texte se trouve dans une balise &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;, d&#39;où la couleur bleue. Scrollons un peu et comparons l&#39;original avec ce que nous avons désormais :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/mKo0alVxzW-390.avif 390w, https://bastiencalou.fr/img/mKo0alVxzW-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/mKo0alVxzW-390.webp 390w, https://bastiencalou.fr/img/mKo0alVxzW-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/mKo0alVxzW-390.webp&quot; alt=&quot;Le schéma de couleurs par défaut de Firefox force les textes à s&#39;afficher en noir plus lisible que le gris original, et les liens en bleu, ce qui permet de les différencier du texte.&quot; width=&quot;390&quot; height=&quot;225&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      En haut : l&#39;affichage par défaut. En bas : les couleurs par défaut de Firefox.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Quand les couleurs par défaut de Firefox sont imposées, on voit du pur noir pour le texte (au lieu du gris léger du design original) et du bleu pour les liens. C&#39;est un peu brutal mais excellent pour l&#39;accessibilité.&lt;/p&gt;
&lt;p&gt;En fait, c&#39;est ce que fait automatiquement Windows si vous activez le mode « contraste élevé » du système d&#39;exploitation. Aucune manipulation sur le navigateur n&#39;est nécessaire.&lt;/p&gt;
&lt;p&gt;Ceci étant dit, &lt;strong&gt;cela ne peut pas remplacer un design pensé pour l&#39;accessibilité&lt;/strong&gt;. On pourrait dire que c&#39;est &lt;em&gt;parce que&lt;/em&gt; le web n&#39;est pas très accessible que de telles options sont nécessaires.&lt;/p&gt;
&lt;h2 id=&quot;montrez-toujours-votre-vraie-couleur&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/pourquoi-vous-devriez-toujours-declarer-une-background-color/#montrez-toujours-votre-vraie-couleur&quot;&gt;Montrez toujours votre vraie couleur&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici donc ce que nous avons appris :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;toujours spécifier une couleur de fond et une couleur de texte sur les pages car les « valeurs universelles » n&#39;existent pas ;&lt;/li&gt;
&lt;li&gt;si un utilisateur ou un appareil a besoin de les supplanter, ils le peuvent et c&#39;est très bien !&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quant à moi, je jure que je ne regarderai plus le moindre pixel blanc de la même façon.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Le problème avec Chrome, les iframes et mix-blend-mode</title>
		<link href="https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/"/>
		<updated>2020-05-26T00:00:00Z</updated>
		<id>https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/</id>
		<content type="html">&lt;div class=&quot;postAside&quot;&gt;
Mise à jour 2024 : le bug décrit dans cet article semble ne plus exister. La probabilité que cet article soit d&#39;un quelconque intérêt s&#39;approche donc dangereusement de zéro. Adieu petit bug.
&lt;/div&gt;
&lt;p&gt;Dans cet article, je vais décrire un bug très spécifique de Chrome, et explorer ce qu&#39;il nous apprend sur le comportement du canvas, que j&#39;ai décrit dans l&#39;article initial.&lt;/p&gt;
&lt;p&gt;Si vous le pouvez, je vous recommande d&#39;utiliser Chrome pour la lecture de cet article, afin de voir ce qu&#39;il se passe.&lt;/p&gt;
&lt;h2 id=&quot;quel-est-le-bug&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/#quel-est-le-bug&quot;&gt;Quel est le bug ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dans Chrome, &lt;strong&gt;au sein d&#39;une &lt;code&gt;iframe&lt;/code&gt;, un élément ne peut pas se mélanger avec le canvas de l&#39;&lt;code&gt;iframe&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour montrer cela, CodePen est parfait : en effet, tout ce que vous voyez dans un CodePen se trouve à l&#39;intérieur d&#39;une &lt;code&gt;iframe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Reprenons l&#39;exemple du post original, dans lequel nous souhaitons mélanger le &lt;code&gt;h1&lt;/code&gt; vert avec l&#39;arrière-plan blanc du &lt;code&gt;body&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; green&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;mix-blend-mode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; difference&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ce CSS est valide et devrait produire un titre rose (rose étant la différence entre vert et blanc).&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;RwWdKXe&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/RwWdKXe&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;À l&#39;heure où j&#39;écris ces lignes (mai 2020) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firefox passe le test (titre rose) ;&lt;/li&gt;
&lt;li&gt;Safari passe le test (titre rose) ;&lt;/li&gt;
&lt;li&gt;Chrome échoue (titre vert) – je l&#39;ai fait fonctionner dans le post original avec une astuce que j&#39;expliquerai par la suite.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;D&#39;après ce que nous avons appris dans l&#39;article initial, voici ce qui se passe :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;le &lt;code&gt;body&lt;/code&gt; est transparent (&lt;code&gt;white&lt;/code&gt; est défini dans le CSS, mais la valeur est « volée » par le canvas) ;&lt;/li&gt;
  &lt;li&gt;le &lt;code&gt;html&lt;/code&gt; est transparent (valeur par défaut de &lt;code&gt;background-color&lt;/code&gt;) ;&lt;/li&gt;
  &lt;li&gt;le canvas est blanc (la valeur est issue du &lt;code&gt;body&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dans Firefox et Safari, le &lt;code&gt;h1&lt;/code&gt; n&#39;a aucun problème pour se mélanger au canvas blanc. Mais cela ne fonctionne pas sous Chrome.&lt;/p&gt;
&lt;p&gt;Comme je l&#39;ai précisé, cela se produit car CodePen présente notre code dans une &lt;code&gt;iframe&lt;/code&gt; : &lt;a href=&quot;https://css-experiments.netlify.app/chrome_debug.html&quot;&gt;le même code fonctionne très bien en isolation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;comment-corriger-cela&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/#comment-corriger-cela&quot;&gt;Comment corriger cela ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C&#39;est très simple. Mais c&#39;est ce que ce correctif révèle qui m&#39;intéresse. Vous rappelez-vous du mécanisme du canvas « volant » l&#39;arrière-plan du &lt;code&gt;body&lt;/code&gt;, et du &lt;code&gt;body&lt;/code&gt; ne repeignant pas la même couleur, finissant donc transparent ?&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Le fond de l&#39;élément racine devient le fond du canvas. L&#39;élément racine ne peint pas son arrière-plan de nouveau, ce qui signifie que la valeur effective de son arrière-plan est transparente.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;WC3, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#root-background&quot;&gt;The Canvas Background and the Root Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Il se trouve que Chrome n&#39;a pas de problème pour mélanger un élément avec l&#39;arrière-plan du &lt;code&gt;body&lt;/code&gt; de l&#39;&lt;code&gt;iframe&lt;/code&gt;. Mais le vol de l&#39;arrière-plan par le canvas provoque une erreur.&lt;/p&gt;
&lt;p&gt;Peut-on empêcher le canvas de commetre un tel crime ?&lt;/p&gt;
&lt;p&gt;Oui, en donnant une couleur de fond à l&#39;élément &lt;code&gt;html&lt;/code&gt; également :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;html,
body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;GRpeWra&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/GRpeWra&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Cela fonctionne désormais partout !&lt;/p&gt;
&lt;p&gt;J&#39;avais déjà utilisé ce correctif, mais je comprends seulement maintenant pourquoi il fonctionne : c&#39;est parce qu&#39;il empêche le canvas de voler l&#39;arrière-plan du &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Vous rappelez-vous de notre petit algorithme ?&lt;/p&gt;
&lt;pre&gt;&lt;code tabindex=&quot;0&quot;&gt;if (le html possède une background-color) {
  on l&#39;utilise pour peindre le canvas
}
else if (le body possède une background-color) {
  on l&#39;utilise pour peindre le canvas
}
else {
  le canvas demeure transparent
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela va à l&#39;encontre des bonnes pratiques dictées par le W3C, mais si vous donnez une couleur de fond à l&#39;élément &lt;code&gt;html&lt;/code&gt;, elle sera utilisée par le canvas. Le &lt;code&gt;body&lt;/code&gt; sera laissé tranquille.&lt;/p&gt;
&lt;p&gt;Voici donc ce qui se passe :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;le &lt;code&gt;body&lt;/code&gt; est blanc (valeur spécifiée en CSS. La valeur ne peut plus être volée, grâce au &lt;code&gt;html&lt;/code&gt; faisant office de leurre) ;&lt;/li&gt;
  &lt;li&gt;le &lt;code&gt;html&lt;/code&gt; est transparent (&lt;code&gt;white&lt;/code&gt; spécifiée en CSS, mais volé par le canvas) ;&lt;/li&gt;
  &lt;li&gt;le canvas est blanc (valeur récupérée du &lt;code&gt;html&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;En quelque sorte, nous posons un appât avec la couleur du fond du &lt;code&gt;html&lt;/code&gt;, pour que le &lt;code&gt;body&lt;/code&gt; puisse conserver son propre arrière-plan et que le titre puisse se mélanger correctement.&lt;/p&gt;
&lt;p&gt;Un point contre-intuitif est que n&#39;importe quel fond fera l&#39;affaire, même un fond quasiment invisible :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 0.01&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;L&#39;arrière plan déclaré avec &lt;code&gt;rgba&lt;/code&gt; est pratiquement invisible, mais le résultat est le même.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;bGVZqaE&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/bGVZqaE&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Cela était assez confus pour moi. La valeur n&#39;a pas d&#39;impact ?&lt;/p&gt;
&lt;p&gt;Il est plus facile de comprendre pourquoi, désormais. La valeur n&#39;a aucune importance : la seule chose qui compte, &lt;em&gt;c&#39;est qu&#39;il y ait une valeur&lt;/em&gt;, et que cette valeur distrait le canvas, qui ne viendra pas voler celle du &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Penchons-nous maintenant sur un cas encore plus spécifique et voyons ce qu&#39;il peut nous apprendre sur la relation entre le &lt;code&gt;body&lt;/code&gt; et le canvas.&lt;/p&gt;
&lt;h2 id=&quot;ca-va-trop-loin&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/#ca-va-trop-loin&quot;&gt;Ça va trop loin&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le correctif de la couleur de fond sur l&#39;élément &lt;code&gt;html&lt;/code&gt; est simple, mais il y a un cas intéressant que ce correctif ne couvre pas.&lt;/p&gt;
&lt;p&gt;Ajoutons un pseudo-élément avec une position &lt;code&gt;absolute&lt;/code&gt; à notre titre :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;h1::after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello from the other side&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comme vous pouvez le voir, le pseudo-élément va atterir en bas à droite de notre page, &lt;em&gt;en dehors&lt;/em&gt; des éléments &lt;code&gt;body&lt;/code&gt; et &lt;code&gt;html&lt;/code&gt;. Je ne pense pas que les dieux du CSS aient voulu cette situation, mais oups, je viens de la produire.&lt;/p&gt;
&lt;p&gt;Quelle sera donc la couleur du pseudo-élément ?&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;RwWdgpx&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/RwWdgpx&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Si vous utilisez Chrome, vous pouvez voir que l&#39;élément est vert. Cela illustre bien le bug : à l&#39;intérieur d&#39;une &lt;code&gt;iframe&lt;/code&gt;, un élément peut se mélanger au &lt;code&gt;body&lt;/code&gt;, mais pas au canvas, bien que les deux soient blancs.&lt;/p&gt;
&lt;p&gt;Et maintenant, la touche finale : vous pouvez clairement voir la distinction entre le &lt;code&gt;body&lt;/code&gt; blanc et le canvas blanc en redimensionnant le viewport pour amener le pseudo-élément au dessus du &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;video class=&quot;picture&quot; controls=&quot;&quot; playsinline=&quot;&quot; src=&quot;https://bastiencalou.fr/webm/resize.webm&quot;&gt;&lt;/video&gt;
    &lt;figcaption&gt;
      Vidéo : lorsque l&#39;élément flotte en dehors du body, la fusion n&#39;est pas appliquée et il reste vert. Lorsque la hauteur de la fenêtre est réduite et que l&#39;élément ré-intègre le body, la fusion fonctionne et il devient rose comme prévu.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Analysons la situation :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le texte se mélange avec le &lt;code&gt;body&lt;/code&gt; (valeur &lt;code&gt;white&lt;/code&gt; dans le CSS) ;&lt;/li&gt;
&lt;li&gt;le texte ne se mélange pas avec le &lt;code&gt;html&lt;/code&gt; (valeur &lt;code&gt;white&lt;/code&gt; dans le CSS volée par le canvas, donc transparent) ;&lt;/li&gt;
&lt;li&gt;le texte ne se mélange pas avec le canvas, bien qu&#39;il soit blanc, à cause du bug de l&#39;&lt;code&gt;iframe&lt;/code&gt; sous Chrome.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;pourquoi-cela-m&#39;importe-t-il-tant&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/#pourquoi-cela-m&#39;importe-t-il-tant&quot;&gt;Pourquoi cela m&#39;importe-t-il tant ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Il peut paraître exagéré de se pré-occuper de situations si extrêmes. Ce n&#39;est pas le genre de problème que vous risquez de rencontrer au quotidien. Pensez-y : pour reproduire ce que montre le gif ci-dessus par accident, il vous faudrait :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;utiliser Chrome ;&lt;/li&gt;
&lt;li&gt;utiliser une &lt;code&gt;iframe&lt;/code&gt; (créée par CodePen, par exemple) ;&lt;/li&gt;
&lt;li&gt;utiliser &lt;code&gt;mix-blend-mode&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;l&#39;utiliser sur un élément dont tous les parents sont dépourvus d&#39;arrière-plan ;&lt;/li&gt;
&lt;li&gt;l&#39;utiliser sur un élément en position &lt;code&gt;absolute&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;travailler avec un &lt;code&gt;body&lt;/code&gt; suffisamment petit pour que l&#39;élément en position &lt;code&gt;absolute&lt;/code&gt; passe en-dehors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eh bien, croyez-le ou non, c&#39;est exactement ce qui m&#39;est arrivé il y a quelques temps.&lt;/p&gt;
&lt;p&gt;J&#39;aidais un de mes étudiants à créer un effet avec &lt;code&gt;mix-blend-mode&lt;/code&gt;. J&#39;ai innocemment créé une démo sur CodePen, en utilisant Firefox. Tout était parfait. Affaire classée. Jusqu&#39;à ce que mon étudiant m&#39;informe que cela ne fonctionnait pas sous Chrome.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/aa1ZfMql-M-390.avif 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/aa1ZfMql-M-390.webp 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/aa1ZfMql-M-390.webp&quot; alt=&quot;Un homme plein de désillusion retire ses lunettes.&quot; width=&quot;195&quot; height=&quot;110&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Je ne suis plus digne d&#39;être ton professeur.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Il m&#39;a fallu pas mal de temps pour comprendre tout ce que j&#39;ai expliqué dans ces deux articles. Pour être honnête, j&#39;ai d&#39;abord fonctionné en mode « corriger maintenant, comprendre plus tard ». J&#39;ai ajouté une couleur d&#39;arrière-plan à l&#39;élément &lt;code&gt;html&lt;/code&gt;, forcé la hauteur du &lt;code&gt;body&lt;/code&gt; à &lt;code&gt;100vh&lt;/code&gt;, et voilà !&lt;/p&gt;
&lt;p&gt;Quelques mois plus tard, je me pose pour analyser le problème... Et me voilà pris dans cette spirale infernale.&lt;/p&gt;
&lt;h2 id=&quot;ameliorer-les-choses&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/#ameliorer-les-choses&quot;&gt;Améliorer les choses&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bien que le correctif de la couleur de fond sur l&#39;élément &lt;code&gt;html&lt;/code&gt; soit simple, et bien que la situation décrite plus haut est hautement improbable, il s&#39;agit toujours d&#39;un bug.&lt;/p&gt;
&lt;p&gt;En réalité, il s&#39;agissait même d&#39;un bug qui se produisait en dehors des &lt;code&gt;iframes&lt;/code&gt; ! Un &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=711955&quot;&gt;ticket Chromium a été ouvert en 2017&lt;/a&gt;. Il a été marqué comme résolu en 2020.&lt;/p&gt;
&lt;p&gt;Réalisant que le bug se produisait toujours dans les &lt;code&gt;iframes&lt;/code&gt;, je me suis permis de le signaler dans &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=711955#c16&quot;&gt;un commentaire&lt;/a&gt;, ce qui a conduit à la création d&#39;un &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=711955&quot;&gt;ticket dédié&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;mefiez-vous-de-vos-habitudes-de-test&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/le-probleme-avec-chrome-les-iframes-et-mix-blend-mode/#mefiez-vous-de-vos-habitudes-de-test&quot;&gt;Méfiez-vous de vos habitudes de test&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je suis amoureux de CodePen. Je pense que je n&#39;ai pas besoin d&#39;expliquer pourquoi. Je m&#39;en sers presque tous les jours.&lt;/p&gt;
&lt;p&gt;Mais dans ce cas précis, CodePen m&#39;a mis dans une situation qui n&#39;était &lt;strong&gt;pas&lt;/strong&gt; la même que celle que je tentais de débloquer. J&#39;aidais un étudiant à créer une page qui ne contenait pas d&#39;&lt;code&gt;iframe&lt;/code&gt;. En utilisant un outil présentant mon code dans une &lt;code&gt;iframe&lt;/code&gt;, j&#39;ai changé les conditions initiales. Et comme nous l&#39;avons vu, c&#39;est un changement non négligeable lorsqu&#39;on parle de Chrome et de &lt;code&gt;mix-blend-mode&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Notez que CodePen n&#39;est pas à blâmer : c&#39;est Chrome qui est en faute ici, et CodePen n&#39;a pas d&#39;autre choix que de présenter mon code dans une &lt;code&gt;iframe&lt;/code&gt; – sauf si vous utilisez la vue &lt;em&gt;debug&lt;/em&gt; !&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/ICsb0k7nYg-390.avif 390w, https://bastiencalou.fr/img/ICsb0k7nYg-560.avif 560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/ICsb0k7nYg-390.webp 390w, https://bastiencalou.fr/img/ICsb0k7nYg-560.webp 560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/ICsb0k7nYg-390.webp&quot; alt=&quot;Le menu de CodePen permettant d&#39;accéder à la vue debug.&quot; width=&quot;280&quot; height=&quot;309&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Utilisez la vue &lt;i&gt;debug&lt;/i&gt; pour éxécuter votre code dans une vraie page – sans &lt;code&gt;iframe&lt;/code&gt; !
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Je suis aussi à blâmer : j&#39;avais une telle confiance aveugle en CodePen que j&#39;ai inconsciemment écarté l&#39;hypothèse que l&#39;utiliser pouvait affecter mon résultat.&lt;/p&gt;
&lt;p&gt;Alors, comme disait l&#39;autre : ne tombez pas amoureux de vos outils. Rien ne vaut un vrai test.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Quelle est la couleur d&#39;une page blanche ?</title>
		<link href="https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/"/>
		<updated>2020-05-22T00:00:00Z</updated>
		<id>https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/</id>
		<content type="html">&lt;p&gt;Imaginez le HTML suivant dans votre tête :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hello World&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous ouvrez ce HTML dans votre navigateur. Quel est la couleur de la page ?&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/MSA2IfGUOZ-390.avif 390w, https://bastiencalou.fr/img/MSA2IfGUOZ-666.avif 666w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/MSA2IfGUOZ-390.webp 390w, https://bastiencalou.fr/img/MSA2IfGUOZ-666.webp 666w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/MSA2IfGUOZ-390.webp&quot; alt=&quot;It&#39;s a CSS trap!&quot; width=&quot;333&quot; height=&quot;188&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Vous pouvez penser que c&#39;est une question piège, car le blanc n&#39;est pas réellement une couleur, mais la page n&#39;est de toute façon pas blanche : elle est &lt;em&gt;transparente&lt;/em&gt;. Oui, le navigateur est blanc, mais la page présentée au sein du navigateur est transparente.&lt;/p&gt;
&lt;h2 id=&quot;prouve-moi-que-la-page-n&#39;est-pas-blanche-car-elle-me-semble-tout-de-meme-pas-mal-blanche&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/#prouve-moi-que-la-page-n&#39;est-pas-blanche-car-elle-me-semble-tout-de-meme-pas-mal-blanche&quot;&gt;Prouve-moi que la page n&#39;est pas blanche, car elle me semble tout de même pas mal blanche&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Mode philosophe activé :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Qu&#39;est ce qu&#39;une page ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Deux éléments doivent être considérés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l&#39;élement &lt;code&gt;body&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;l&#39;élement &lt;code&gt;html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si l&#39;on souhaite obtenir un fond jaune, on utilise la propriété &lt;code&gt;background-color&lt;/code&gt; sur le &lt;code&gt;body&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; yellow&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;WNQggzY&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/WNQggzY&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;À partir de cet exemple, on peut imaginer que le &lt;code&gt;body&lt;/code&gt; remplit l&#39;intégralité du viewport, car désormais tout est jaune.&lt;/p&gt;
&lt;p&gt;C&#39;est faux. Ajoutons une bordure au &lt;code&gt;body&lt;/code&gt; :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;PoPddaR&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/PoPddaR&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Vous pouvez voir qu&#39;en réalité le &lt;code&gt;body&lt;/code&gt; n&#39;utilise que l&#39;espace dont il a besoin pour afficher le contenu « Hello world ».&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mais alors, pourquoi tout ce jaune ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Il faut demander cela au w3c :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;L&#39;arrière-plan de l&#39;élément racine devient l&#39;arrière-plan du canvas et sa zone de peinture s&#39;étend pour couvrir le canvas en entier.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#root-background&quot;&gt;The Canvas Background and the Root Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Traduction humaine : vous spécifiez une couleur de fond sur le &lt;code&gt;body&lt;/code&gt;. Le navigateur l&#39;utilisera comme couleur de fond du canvas.&lt;/p&gt;
&lt;p&gt;Le canvas, dites-vous ?&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Le canvas du document est la surface infinie sur laquelle le document est rendu.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#special-backgrounds&quot;&gt;Backgrounds of Special Elements&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Une surface infinie, rien que ça.&lt;/p&gt;
&lt;p&gt;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&#39;il s&#39;agisse d&#39;un composant très important du navigateur. Comme nous venons de le voir, en se basant sur le &lt;code&gt;body&lt;/code&gt;, il fourni un arrière-plan pour l&#39;ensemble du viewport.&lt;/p&gt;
&lt;p&gt;Avec cette nouvelle information, nous pouvons mettre à jour notre représentation mentale de la page, de haut en bas :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;body&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;html&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;le canvas.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pendant longtemps, j&#39;ai pensé que le canvas était jaune parce que le &lt;code&gt;body&lt;/code&gt; &lt;em&gt;était&lt;/em&gt; le canvas. Mais non : le canvas ne fait qu&#39;utiliser une information provenant du &lt;code&gt;body&lt;/code&gt; et peut être bien plus grand que le &lt;code&gt;body&lt;/code&gt; lui-même.&lt;/p&gt;
&lt;p&gt;Il est intéressant de noter que bien que l&#39;on demande au &lt;code&gt;body&lt;/code&gt; d&#39;être jaune, il est en réalité transparent. Comme l&#39;explique le W3C :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Le fond de l&#39;élément racine devient le fond du canvas. L&#39;élément racine ne peint pas son arrière-plan de nouveau, ce qui signifie que la valeur effective de son arrière-plan est transparente.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;WC3, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#root-background&quot;&gt;The Canvas Background and the Root Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Il est inutile pour le navigateur de peindre le &lt;code&gt;body&lt;/code&gt;, qui a la même couleur que le canvas : il est donc traité comme étant transparent.&lt;/p&gt;
&lt;p&gt;En d&#39;autres termes, lorsque vous donnez une couleur de fond au &lt;code&gt;body&lt;/code&gt;, vous stylisez en réalité le canvas (qui ne peut pas être ciblé directement en CSS). Le canvas « vole » la valeur du &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;au-dela-du-body&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/#au-dela-du-body&quot;&gt;Au-delà du body&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Mode philosophe activé :&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Qu&#39;est ce que le &lt;code&gt;body&lt;/code&gt; ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;D&#39;après le W3C, le &lt;code&gt;body&lt;/code&gt; &lt;q cite=&quot;https://html.spec.whatwg.org/multipage/sections.html#the-body-element&quot;&gt;représente les contenus du document&lt;/q&gt;.&lt;/p&gt;
&lt;p&gt;Si le &lt;code&gt;body&lt;/code&gt; est le contenu, il semble honnête de dire que ce qui est en dehors du &lt;code&gt;body&lt;/code&gt; n&#39;est pas le contenu.&lt;/p&gt;
&lt;p&gt;Dans ce cas, utiliser &lt;code&gt;background-color&lt;/code&gt; sur l&#39;élément &lt;code&gt;html&lt;/code&gt; ne devrait pas avoir d&#39;effet, puisqu&#39;il ne fait pas partie du contenu ?&lt;/p&gt;
&lt;p&gt;Pensez-y un instant : à quoi ressemblerait notre page avec ce CSS ?&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; green&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; yellow&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Quelle est la couleur de la page maintenant ? Est-elle verte, est-elle jaune, est-elle les deux ? Bien sûr qu&#39;elle est les deux.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;oNjPPNj&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/oNjPPNj&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Que voyons-nous ?&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;le jaune est désormais limité au &lt;code&gt;body&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;html&lt;/code&gt; semble remplir l&#39;ensemble du viewport.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Faux ! Une fois de plus, nous sommes trompés par les apparences.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mais si, il remplit le viewport, toute la page est verte !&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Je sais. Mais ajoutons des bordures à l&#39;élément &lt;code&gt;html&lt;/code&gt; pour comprendre ce qui se passe :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;zYvJJzY&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/zYvJJzY&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Il est intéressant de noter que le navigateur n&#39;a pas de problème pour appliquer des styles (tels que nos bordures) en dehors du &lt;code&gt;body&lt;/code&gt;. Mais continuons.&lt;/p&gt;
&lt;p&gt;Donc, en réalité, le &lt;code&gt;html&lt;/code&gt; se comporte comme le &lt;code&gt;body&lt;/code&gt; : il ne prend que la place nécessaire à la présentation de son contenu, c&#39;est à dire le &lt;code&gt;body&lt;/code&gt; et ses &lt;code&gt;8px&lt;/code&gt; de marge, qui viennent des styles par défaut du navigateur.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mais alors pourquoi tout ce vert ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Même réponse du W3C :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Le fond de l&#39;élément racine devient le fond du canvas.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;WC3, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#root-background&quot;&gt;The Canvas Background and the Root Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;On apprend également que l&#39;élément racine peut être le &lt;code&gt;body&lt;/code&gt; ou le &lt;code&gt;html&lt;/code&gt; :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Il est recommandé aux auteurs de documents HTML de spécifier le fond du canvas sur l&#39;élément &lt;code&gt;body&lt;/code&gt; plutôt que sur l&#39;élement &lt;code&gt;html&lt;/code&gt;.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#body-background&quot;&gt;The Canvas Background and the HTML &amp;lt;body&amp;gt; Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Bien que le W3C recommande de ne pas utiliser l&#39;élément &lt;code&gt;html&lt;/code&gt; pour faire cela, c&#39;est ce que l&#39;on vient de faire, et c&#39;est de là que le canvas tire sa couleur verte.&lt;/p&gt;
&lt;p&gt;Comme dans le premier exemple, l&#39;élément &lt;code&gt;html&lt;/code&gt; est traité come transparent : son vert est « volé » par le canvas.&lt;/p&gt;
&lt;p&gt;Nous avons maintenant l&#39;algorithme complet que le navigateur utilise pour choisir la couleur du canvas :&lt;/p&gt;
&lt;pre&gt;&lt;code tabindex=&quot;0&quot;&gt;if (le html possède une background-color) {
  on l&#39;utilise pour peindre le canvas
}
else if (le body possède une background-color) {
  on l&#39;utilise pour peindre le canvas
}
else {
  le canvas demeure transparent
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bien, cela fait un mystère de résolu, et ce n&#39;est pas si étrange, finalement. Il est même assez heureux que nous n&#39;ayons pas à donner des dimensions explicites à l&#39;élément racine pour que la couleur de fond remplisse le viewport.&lt;/p&gt;
&lt;h2 id=&quot;pourquoi-est-ce-important-et-c&#39;est-quoi-cette-histoire-de-blanc-vs-transparent&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/#pourquoi-est-ce-important-et-c&#39;est-quoi-cette-histoire-de-blanc-vs-transparent&quot;&gt;Pourquoi est-ce important ? Et c&#39;est quoi cette histoire de blanc VS transparent ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Comprendre qu&#39;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.&lt;/p&gt;
&lt;p&gt;Amusons-nous avec &lt;code&gt;mix-blend-mode&lt;/code&gt;. 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.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/S3-8NWJaNL-390.avif 390w, https://bastiencalou.fr/img/S3-8NWJaNL-780.avif 780w, https://bastiencalou.fr/img/S3-8NWJaNL-1200.avif 1200w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/S3-8NWJaNL-390.webp 390w, https://bastiencalou.fr/img/S3-8NWJaNL-780.webp 780w, https://bastiencalou.fr/img/S3-8NWJaNL-1200.webp 1200w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/S3-8NWJaNL-390.webp&quot; alt=&quot;Une série d&#39;exemples d&#39;utilisation de mix-blend-mode pour créer différents effets visuels.&quot; width=&quot;600&quot; height=&quot;219&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Quelques exemples d&#39;utilisation de mix-blend-mode.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Commençons avec un exemple simple : notre &lt;code&gt;h1&lt;/code&gt; sera vert, et nous souhaitons changer son apparence avec &lt;code&gt;mix-blend-mode: difference&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; green&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;mix-blend-mode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; difference&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La valeur &lt;code&gt;difference&lt;/code&gt; signifie que la couleur du texte sera la différence entre la couleur originale (vert) et la couleur de l&#39;arrière-plan.&lt;/p&gt;
&lt;p&gt;La différence entre vert et blanc est rose. On espère donc que notre titre sera rose.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;YzyOJEO&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/YzyOJEO&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Il n&#39;est pas rose. Je répète, il n&#39;est pas rose.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mais il devrait devenir rose, l&#39;arrière-plan est blanc !&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Non, il n&#39;est pas blanc. Il est transparent.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/q6Ckh4Bmhs-390.avif 390w, https://bastiencalou.fr/img/q6Ckh4Bmhs-650.avif 650w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/q6Ckh4Bmhs-390.webp 390w, https://bastiencalou.fr/img/q6Ckh4Bmhs-650.webp 650w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/q6Ckh4Bmhs-390.webp&quot; alt=&quot;Bien vu !&quot; width=&quot;325&quot; height=&quot;183&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;La différence entre vert et transparent est vert, et c&#39;est pour cela que la couleur du titre reste inchangée.&lt;/p&gt;
&lt;p&gt;Récapitulons :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;le &lt;code&gt;body&lt;/code&gt; est transparent (valeur par défaut de &lt;code&gt;background-color&lt;/code&gt;) ;&lt;/li&gt;
  &lt;li&gt;le &lt;code&gt;html&lt;/code&gt; est transparent (valeur par défaut de &lt;code&gt;background-color&lt;/code&gt;) ;&lt;/li&gt;
  &lt;li&gt;le canvas est transparent (aucune valeur fournie par &lt;code&gt;html&lt;/code&gt; ou &lt;code&gt;body&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notre pauvre titre n&#39;a donc rien avec quoi se mélanger.&lt;/p&gt;
&lt;p&gt;Le correctif est facile : donnez un arrière-plan blanc au &lt;code&gt;body&lt;/code&gt; !&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et maintenant, ça fonctionne !&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;wvKEYGO&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/wvKEYGO&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Récapitulons à nouveau :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;le &lt;code&gt;body&lt;/code&gt; est transparent (&lt;code&gt;white&lt;/code&gt; est défini dans le CSS, mais la valeur est « volée » par le canvas) ;&lt;/li&gt;
  &lt;li&gt;le &lt;code&gt;html&lt;/code&gt; est transparent (valeur par défaut de &lt;code&gt;background-color&lt;/code&gt;) ;&lt;/li&gt;
  &lt;li&gt;le canvas est blanc (la valeur est issue du &lt;code&gt;body&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Et c&#39;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 &lt;code&gt;body&lt;/code&gt; (ou n&#39;importe quel élément contenant notre cible) &lt;em&gt;doit&lt;/em&gt; posséder un arrière-plan (on pourrait également donner une couleur de fond à l&#39;élément &lt;code&gt;html&lt;/code&gt; pour y parvenir, mais ce n&#39;est pas standard).&lt;/p&gt;
&lt;p&gt;Notre périple touche à sa fin, mais une question demeure...&lt;/p&gt;
&lt;h2 id=&quot;quelle-est-la-couleur-d&#39;un-canvas-vide&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/#quelle-est-la-couleur-d&#39;un-canvas-vide&quot;&gt;Quelle est la couleur d&#39;un canvas vide ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Notre modèle mental d&#39;une page est ainsi :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;body&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;html&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;le canvas.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;D&#39;après ce que nous venons d&#39;apprendre, si le &lt;code&gt;body&lt;/code&gt; et le &lt;code&gt;html&lt;/code&gt; sont transparents, le canvas sera transparent aussi.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Mais comment la dernière couche peut-elle être transparente ? Si c&#39;était le cas, on verrait le bureau et les autres fenêtres au travers du navigateur, tu es fou !&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Laissez-moi vous expliquer. Et s&#39;il y avait une &lt;em&gt;autre&lt;/em&gt; couche, réellement blanche, plus bas que le canvas ?&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/8ZHwlzaW0Y-390.avif 390w, https://bastiencalou.fr/img/8ZHwlzaW0Y-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/8ZHwlzaW0Y-390.webp 390w, https://bastiencalou.fr/img/8ZHwlzaW0Y-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/8ZHwlzaW0Y-390.webp&quot; alt=&quot;Un homme explique frénétiquement une théorie farfelue.&quot; width=&quot;390&quot; height=&quot;158&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Encore une fois, le W3C nous donne la réponse :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Si l&#39;arrière-plan du canvas n&#39;est pas opaque, ce qui est visible en dessous dépendra de l&#39;agent utilisateur.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;W3C, &lt;cite&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/#body-background&quot;&gt;The Canvas Background and the HTML &amp;lt;body&amp;gt; Element&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Traduction humaine : il y a quelque chose &lt;em&gt;derrière&lt;/em&gt; le canvas. Vous pouvez voir cette chose si le canvas est transparent. Ce que vous voyez dépend du navigateur.&lt;/p&gt;
&lt;p&gt;Sur tous les navigateurs auxquels je peux penser, cette dernière couche est blanche. Mais théoriquement, elle pourrait aussi montrer l&#39;image d&#39;un cheval en train de manger une pizza à l&#39;ananas. Quel web étrange cela serait.&lt;/p&gt;
&lt;p&gt;Bref, cela m&#39;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 &lt;em&gt;preuve&lt;/em&gt; que le canvas est transparent par défaut ? Je demande pour un ami.&lt;/p&gt;
&lt;h2 id=&quot;l&#39;indice-de-l&#39;iframe&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/quelle-est-la-couleur-d-une-page-blanche/#l&#39;indice-de-l&#39;iframe&quot;&gt;L&#39;indice de l&#39;iframe&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Revenons à un CSS très simple :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;html,
body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3px dashed black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;ExVdbgE&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/ExVdbgE&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Incluons cette page dans une autre grâce à une balise &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;iframe&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;300px&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;iframe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Voici ce que l&#39;on obtient :&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;GRpYOjV&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/GRpYOjV&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;La question est donc : l&#39;&lt;code&gt;iframe&lt;/code&gt; possède-t-elle un canvas transparent ou blanc ?&lt;/p&gt;
&lt;p&gt;Nous pouvons obtenir la réponse en donnant un arrière-plan à la page parente :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; lightblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;ExVdbNL&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/ExVdbNL&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Comme vous pouvez le constater, l&#39;&lt;code&gt;iframe&lt;/code&gt; est transparente. Son &lt;code&gt;body&lt;/code&gt;, son &lt;code&gt;html&lt;/code&gt; et son canvas. On peut voir la page parente au travers.&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Cela prouve-t-il vraiment que le canvas est transparent ? Peut-être que les iframes n&#39;ont pas de canvas ?&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;C&#39;est une question légitime. Pour y répondre, ajoutons un fond blanc à l&#39;élément &lt;code&gt;body&lt;/code&gt; de l&#39;&lt;code&gt;iframe&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;mdezqON&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/mdezqON&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Si l&#39;&lt;code&gt;iframe&lt;/code&gt; n&#39;avait pas de canvas, la zone en dehors de son élément &lt;code&gt;body&lt;/code&gt; ne serait pas remplie. Mais grâce au mécanisme du canvas, la couleur de fond du &lt;code&gt;body&lt;/code&gt; peut être utilisée pour couvrir l&#39;ensemble du viewport de l&#39;&lt;code&gt;iframe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et c&#39;est ainsi que l&#39;on montre que sur n&#39;importe quelle page, &lt;strong&gt;le canvas par défaut n&#39;est pas blanc mais transparent&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ce que vous voyez quand vous ouvrez une page vide n&#39;est donc pas un canvas blanc. C&#39;est juste le « fond » du navigateur, l&#39;arrière-plan du logiciel, en dehors du monde du CSS, qui n&#39;interagit aucunement avec quoi que ce soit.&lt;/p&gt;
&lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/LKv_0cqpCc-390.avif 390w, https://bastiencalou.fr/img/LKv_0cqpCc-594.avif 594w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/LKv_0cqpCc-390.webp 390w, https://bastiencalou.fr/img/LKv_0cqpCc-594.webp 594w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/LKv_0cqpCc-390.webp&quot; alt=&quot;C&#39;est vraiment profond...&quot; width=&quot;297&quot; height=&quot;251&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
&lt;p&gt;Et voici donc notre modèle (final ?) de ce que nous voyons :&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;body&lt;/code&gt; (transparent par défaut) ;&lt;/li&gt;
  &lt;li&gt;l&#39;élément &lt;code&gt;html&lt;/code&gt; (transparent par défaut) ;&lt;/li&gt;
  &lt;li&gt;le canvas (dépend du &lt;code&gt;html&lt;/code&gt; et du &lt;code&gt;body&lt;/code&gt;, donc transparent par défaut) ;&lt;/li&gt;
  &lt;li&gt;les fondations innaccessibles du logiciel (souvent un fond blanc).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Oh, et j&#39;ai essayé d&#39;en faire un dessin :&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/anztRr7cZZ-390.avif 390w, https://bastiencalou.fr/img/anztRr7cZZ-780.avif 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/anztRr7cZZ-390.webp 390w, https://bastiencalou.fr/img/anztRr7cZZ-780.webp 780w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/anztRr7cZZ-390.webp&quot; alt=&quot;Les quatres couches du navigateur : body, html, canvas et fond du navigateur.&quot; width=&quot;390&quot; height=&quot;358&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      It&#39;s a small &lt;em&gt;Hello World&lt;/em&gt; after all.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;C&#39;était sympa, ce petit voyage. Et oui, j&#39;ai une vie.&lt;/p&gt;
&lt;p&gt;CSS tourne beaucoup autour de ce que l&#39;on voit, mais aussi beaucoup autour de ce que l&#39;on ne voit pas.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Je ne suis pas « artisan développeur »</title>
		<link href="https://bastiencalou.fr/je-ne-suis-pas-artisan-developpeur/"/>
		<updated>2019-08-03T00:00:00Z</updated>
		<id>https://bastiencalou.fr/je-ne-suis-pas-artisan-developpeur/</id>
		<content type="html">&lt;p&gt;Il y a quelques jours, j&#39;ai reçu un message dans ma boîte de réception LinkedIn. Cette fois, pas d&#39;offre sous forme de poème, pas de blagounette pseudo-disruptive. Même pas de &lt;em&gt;Ninja&lt;/em&gt; ou de &lt;em&gt;Rockstar developer&lt;/em&gt; à l&#39;horizon. Mais un terme que je ne connaissais pas : celui de &lt;strong&gt;software craftsmanship&lt;/strong&gt; (comprenez « artisanat du développement »).&lt;/p&gt;
&lt;p&gt;Après m&#39;être imaginé quelques instants artisan développeur, accueillant les touristes dans ma petite boutique à Saint-Paul-de-Vence (&lt;q&gt;Entrez messieurs dames, attention où vous mettez les pieds, il y a des frameworks un peu partout je n&#39;ai pas encore eu le temps de ranger !&lt;/q&gt;), j&#39;ai quand même demandé à Google ce qu&#39;il en pensait.&lt;/p&gt;
&lt;p&gt;Et là, il y avait une fiche Wikipédia. Et si c&#39;est sur Wikipédia, c&#39;est bien que ça existe et que ça n&#39;est pas une invention de RH en manque de sensations fortes. Quand on remonte à la source, on trouve un &lt;a href=&quot;http://manifesto.softwarecraftsmanship.org/#/fr-fr&quot;&gt;manifeste&lt;/a&gt; : celui des artisans du logiciel.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/82pfez_v8o-390.avif 390w, https://bastiencalou.fr/img/82pfez_v8o-780.avif 780w, https://bastiencalou.fr/img/82pfez_v8o-1560.avif 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/82pfez_v8o-390.webp 390w, https://bastiencalou.fr/img/82pfez_v8o-780.webp 780w, https://bastiencalou.fr/img/82pfez_v8o-1560.webp 1560w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/82pfez_v8o-390.webp&quot; alt=&quot;Capture d&#39;écran du manifeste de l&#39;artisan développeur.&quot; width=&quot;780&quot; height=&quot;705&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Le manifeste, publié en 2009 d&#39;après le texte, 1450 d&#39;après le design.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Ce qu&#39;il est important de dire d&#39;entrée de jeu, c&#39;est que je suis &lt;strong&gt;parfaitement d&#39;accord&lt;/strong&gt; avec les principes énoncés ci-dessus. Je suis à peu près sûr que vous aussi. Alors pourquoi me fendre d&#39;un article, me direz-vous ?&lt;/p&gt;
&lt;p&gt;Prenez une seconde pour les lire. Avez-vous sourcillé une seule seconde ? Je parie que non. Est-ce que ce n&#39;est pas étrange, un manifeste aussi évident ? Est-ce que ça ne cache pas un petit malaise quelque part ?&lt;/p&gt;
&lt;p&gt;Pour moi, c&#39;est simple : si ce manifeste est si banal, c&#39;est parce que nous savons tous qu&#39;il énonce ce que devrait être le &lt;strong&gt;développement&lt;/strong&gt; tout court, et que &lt;em&gt;l&#39;artisanat&lt;/em&gt; n&#39;a rien à faire là-dedans. Nous savons tous que si nous travaillons sans suivre ces principes, notre code ne vaut pas un clou.&lt;/p&gt;
&lt;p&gt;Ce manifeste est un aveu d&#39;échec : il prend acte de la situation médiocre de l&#39;industrie, et invente un terme tout beau tout nouveau pour déplacer les bonnes pratiques dans un monde mythologique où les développeurs vivent en harmonie avec le client, les tests unitaires, le vaisseau de la Vierge Marie et le Christ Cosmique.&lt;/p&gt;
&lt;p&gt;Qu&#39;est ce qui peut bien amener une industrie à se voiler autant la face ? Ce n&#39;est pas sur ce manifeste que j&#39;ai envie de tirer, car je serai bien malhonnête de prétendre que je n&#39;ai pas fantasmé moi-même sur ce terme d&#39;&lt;em&gt;artisan développeur&lt;/em&gt;. C&#39;est plutôt sur ce qu&#39;il dit de la situation.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/51HXndx60U-390.avif 390w, https://bastiencalou.fr/img/51HXndx60U-780.avif 780w, https://bastiencalou.fr/img/51HXndx60U-1460.avif 1460w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/51HXndx60U-390.webp 390w, https://bastiencalou.fr/img/51HXndx60U-780.webp 780w, https://bastiencalou.fr/img/51HXndx60U-1460.webp 1460w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/51HXndx60U-390.webp&quot; alt=&quot;La couverture du livre The Software Craftsman.&quot; width=&quot;730&quot; height=&quot;666&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Du calme les gens s&#39;il-vous-plaît, ce n&#39;est pas un logiciel c&#39;est la volute d&#39;un violoncelle, faut redescendre là.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Intéressons-nous au premier point, qui stipule le niveau de qualité attendu :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Pas seulement des logiciels opérationnels, mais aussi des logiciels bien conçus.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;&lt;cite&gt;&lt;a href=&quot;http://manifesto.softwarecraftsmanship.org/#/fr-fr&quot;&gt;Manifeste pour l&#39;artisan logiciel&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Une recherche &lt;s&gt;approfondie&lt;/s&gt; Wikipédia nous permet de préciser ce qui est ici entendu : clean code, refactoring, tests automatiques, domain driven developement... Beaucoup de choses que peu de développeurs avec un minimum d&#39;expérience remettront en cause.&lt;/p&gt;
&lt;p&gt;Par exemple, les tests, c&#39;est bien. C&#39;est doux. C&#39;est soyeux, même. Si vous n&#39;êtes pas d&#39;accord, on peut en discuter, mais on ne va pas en discuter, parce que vous êtes d&#39;accord, non ?&lt;/p&gt;
&lt;p&gt;Maintenant, deux situations personnelles :&lt;/p&gt;
&lt;h2 id=&quot;des-fois-ca-se-passe-bien&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/je-ne-suis-pas-artisan-developpeur/#des-fois-ca-se-passe-bien&quot;&gt;Des fois, ça se passe bien&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;J&#39;ai travaillé sur un projet de développement front de plus d&#39;un an, donc nécessairement assez complexe, avec des règles métier dans tous les sens, 12 zillions d&#39;interfaces... Mais un client au top, qui savait reconnaître l&#39;investissement temporel (et donc financier) nécessaire à l&#39;élaboration d&#39;une telle structure.&lt;/p&gt;
&lt;p&gt;Et ce n&#39;est pas facile de trouver un client qui accepte pendant quelques mois, au début, de ne pas voir grand chose, parce qu&#39;un tiers du temps est passé à mettre en place des fondations solides, un autre tiers à écrire des tests, et qu&#39;il ne reste qu&#39;un tiers pour faire émerger le produit « visible ».&lt;/p&gt;
&lt;p&gt;Et donc des tests, j&#39;en ai écrit des centaines. J&#39;ai profité de ce contexte pour en faire une contrainte forte du projet. Pas un seul composant ne serait écrit sans être accompagné de sa batterie de test (il faut aussi savoir ne pas être dogmatique, en vertu de la &lt;a href=&quot;https://fr.wikipedia.org/wiki/Principe_de_Pareto&quot;&gt;loi de Pareto&lt;/a&gt;, mais c&#39;est une autre histoire).&lt;/p&gt;
&lt;p&gt;J&#39;ai quitté le projet il y a un an, et son développement suit son cours, avec plus de 2000 tests au compteur. Bien sûr je ne dis pas que les tests seuls font la qualité d&#39;un projet, c&#39;est un exemple. Mais dans ce cas précis, ils ont permis d&#39;atteindre une vitesse de développement élevée une fois la mise en place effectuée, et surtout d&#39;assurer la stabilité du produit.&lt;/p&gt;
&lt;p&gt;Le projet n&#39;a pas explosé quand je suis parti, même si j&#39;ai fait quelques incantations sur le côté pour me rassurer, il est vrai. Il n&#39;a rencontré, à ma connaissance, aucune régression majeure. Et les personnes qui l&#39;ont repris ont le confort de savoir que, malgré l&#39;ampleur du projet, si les tests passent, c&#39;est qu&#39;elles n&#39;ont probablement rien cassé. Elles peuvent continuer à le faire évoluer dans les conditions les plus saines possibles.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/Gbhp-RguxB-390.avif 390w, https://bastiencalou.fr/img/Gbhp-RguxB-780.avif 780w, https://bastiencalou.fr/img/Gbhp-RguxB-1396.avif 1396w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/Gbhp-RguxB-390.webp 390w, https://bastiencalou.fr/img/Gbhp-RguxB-780.webp 780w, https://bastiencalou.fr/img/Gbhp-RguxB-1396.webp 1396w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/Gbhp-RguxB-390.webp&quot; alt=&quot;Un homme levant ses bras vers le ciel.&quot; width=&quot;698&quot; height=&quot;249&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Cette image vient d&#39;un site sur Dieu, mais pour moi Dieu et 2000 tests au vert c&#39;est pareil, donc ça passe.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;des-fois-ca-se-passe-moins-bien&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/je-ne-suis-pas-artisan-developpeur/#des-fois-ca-se-passe-moins-bien&quot;&gt;Des fois, ça se passe moins bien&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;J&#39;ai travaillé sur un projet (comprendre : plusieurs projets) où les contraintes étaient telles que tout cela n&#39;avait aucune chance d&#39;émerger. Où chaque deadline était remplacée par une autre, où tout ce qui ne contribuait pas à facturer le client au plus vite était vu comme un mal au mieux nécessaire, au pire dispensable.&lt;/p&gt;
&lt;p&gt;Ce genre de situation où, vous le savez bien, les tests sont les premiers sacrifiés. Où mentionner la possibilité d&#39;en écrire, bien que ce soit notre responsabilité professionnelle, semble blasphématoire, et nous poserait presque en ennemi du livrable, en ayatollah de la qualité, en fauteur de troubles.&lt;/p&gt;
&lt;p&gt;On osera peut-être vous répondre que les tests seront écrits plus tard, ce qui doit convaincre principalement ceux qui n&#39;en n&#39;ont jamais écrit. On osera peut-être remplacer dans votre esprit le Père Noël par ce fameux « sprint de stabilisation », mais si, il existe j&#39;en suis sûr, il faut juste être patient.&lt;/p&gt;
&lt;p&gt;Bref, ces situations existent, pour mille raisons, et il faut alors s&#39;accrocher à son slip, car tests ou pas (et encore une fois ce n&#39;est qu&#39;une mince partie des bonnes pratiques), un rendu de qualité est attendu. Et donc ces bonnes pratiques, on jongle rapidement avec.&lt;/p&gt;
&lt;p&gt;Si j&#39;ai vite compris que certains projets ne feraient pas de place aux tests, j&#39;ai pour ma part fait « vœu » de ne rien lâcher vis-à-vis des &lt;i&gt;code review&lt;/i&gt; approfondies, dernier rempart contre le &lt;i&gt;spaghetti code&lt;/i&gt; à mes yeux. Chacun sa technique pour sauver la qualité du projet en situation extrême.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/QsQSCMZDBo-390.avif 390w, https://bastiencalou.fr/img/QsQSCMZDBo-780.avif 780w, https://bastiencalou.fr/img/QsQSCMZDBo-1366.avif 1366w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/QsQSCMZDBo-390.webp 390w, https://bastiencalou.fr/img/QsQSCMZDBo-780.webp 780w, https://bastiencalou.fr/img/QsQSCMZDBo-1366.webp 1366w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/QsQSCMZDBo-390.webp&quot; alt=&quot;Strip : comment faire une bonne revue de code.&quot; width=&quot;683&quot; height=&quot;862&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Source : &lt;a href=&quot;http://geek-and-poke.com/&quot;&gt;Geek and Poke&lt;/a&gt;
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;spoiler-alert&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/je-ne-suis-pas-artisan-developpeur/#spoiler-alert&quot;&gt;Spoiler alert&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La première situation semble malheureusement bien rare. Et des projets frustrants qui ne me permettront pas d&#39;appliquer ce que je sais sur les tests, le clean coding, la performance, l&#39;accessibilité... Il y en aura bien d&#39;autres.&lt;/p&gt;
&lt;p&gt;Étais-je pour autant « artisan » développeur dans une situation, simple développeur dans l&#39;autre ? Aurais-je dû être payé différement ? Étais-je &lt;em&gt;meilleur&lt;/em&gt; ? Je ne crois pas.&lt;/p&gt;
&lt;p&gt;À lire mes &lt;a href=&quot;https://www.jesuisundev.com/pourquoi-les-developpeureuses-codent-avec-le-cul/&quot;&gt;collègues&lt;/a&gt;, il semblerait que notre industrie ait le chic pour créer ces situations ubuesques, où la qualité est attendue côté résultat sans être considérée côté production. Alors forcément, il est tentant de fantasmer sur un monde meilleur, et ce n&#39;est pas parce que j&#39;attaque ce terme que j&#39;attaque ceux qui l&#39;ont inventé : j&#39;ai bien l&#39;impression qu&#39;ils partagent mon sentiment.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/bTm6k7YDeC-390.avif 390w, https://bastiencalou.fr/img/bTm6k7YDeC-600.avif 600w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/bTm6k7YDeC-390.webp 390w, https://bastiencalou.fr/img/bTm6k7YDeC-600.webp 600w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/bTm6k7YDeC-390.webp&quot; alt=&quot;Une imagerie soviétique de l&#39;artisan développeur.&quot; width=&quot;300&quot; height=&quot;139&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Mais quand même, je vous avais dit que ça allait trop loin cette histoire.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;h2 id=&quot;developpeur-un-noble-terme&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/je-ne-suis-pas-artisan-developpeur/#developpeur-un-noble-terme&quot;&gt;Développeur, un noble terme ?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Mais non, je ne suis pas artisan développeur. Je suis développeur, et mon métier est de réaliser des applications dans des contextes parfois difficiles, mais sans jamais perdre de vue la qualité.&lt;/p&gt;
&lt;p&gt;Et je pardonnerai les codes les plus sales à un développeur, car je connais les conditions qui le produisent, et peut-être même qu&#39;un &lt;code&gt;git blame&lt;/code&gt; révélera que j&#39;en étais l&#39;auteur, et que mon cerveau traumatisé aura effacé ce souvenir, par dignité.&lt;/p&gt;
&lt;p&gt;Je pardonnerai moins le fatalisme, le jemenfoutisme, le relativisme, tous les trucs en « isme ».&lt;/p&gt;
&lt;div class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;De toute façon, vu le projet…&lt;/p&gt;
      &lt;/blockquote&gt;
    &lt;/div&gt;
&lt;p&gt;Non.&lt;/p&gt;
&lt;p&gt;Le projet, il est peut-être réalisé dans des conditions apocalyptiques, mais c&#39;est notre travail. C&#39;est notre protégé, c&#39;est ce PNJ qu&#39;on doit amener en sécurité, même s&#39;il se prend un coup de sniper toutes les 30 secondes, même si on a envie de lui tirer dessus nous-même.&lt;/p&gt;
&lt;p&gt;Je ne suis pas fier de tous les projets que j&#39;ai réalisés, mais je n&#39;ai pas à rougir de l&#39;effort que j&#39;y ai mis et des objectifs de qualité que j&#39;ai toujours gardé près de moi (sauf une fois mais j&#39;avais mal dormi).&lt;/p&gt;
&lt;p&gt;Peut-être que l&#39;industrie va mal – je n&#39;en sais rien, j&#39;ai peu de repères. Mais tant qu&#39;il y aura des articles de blog, des discussions à la machine à café pour savoir quel est le meilleur design pattern qu&#39;on n&#39;utilisera jamais, des sondages Twitter pour connaître la meilleure convention de codage, des conversations à rallonge sur Github, bref, tant que cette industrie continuera à employer des gens qui veulent bien faire parce qu&#39;ils aiment cela, il y aura de l&#39;espoir.&lt;/p&gt;
&lt;p&gt;Le slogan des artisans développeurs est &lt;q&gt;Élever le niveau&lt;/q&gt;. Alors oui, élevons-le, tous ensemble, pour que le développement garde ses lettres de noblesse et reste, qu&#39;il soit artisanal, industriel, rigolo, ennuyeux, innovant ou profondément inutile, synonyme de qualité.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Amis développeurs, artisans ou non, unissez-vous !&lt;/strong&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Layout CSS : empêchez les frameworks d&#39;englober vos composants</title>
		<link href="https://bastiencalou.fr/layout-css-empechez-les-frameworks-d-englober-vos-composants/"/>
		<updated>2019-06-26T00:00:00Z</updated>
		<id>https://bastiencalou.fr/layout-css-empechez-les-frameworks-d-englober-vos-composants/</id>
		<content type="html">&lt;p&gt;CSS est difficile, à ce qu&#39;il paraît. Mais avez-vous déjà essayé d&#39;écrire du CSS en vous battant contre un framework qui modifie votre DOM ?&lt;/p&gt;
&lt;h2 id=&quot;le-probleme&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/layout-css-empechez-les-frameworks-d-englober-vos-composants/#le-probleme&quot;&gt;Le problème&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je travaille sur une interface simple : header, contenu, footer. Le header et le footer ont une taille fixe, et je souhaite positionner le contenu au centre de l&#39;espace restant.&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Ah, flexbox, mon vieil ami, ainsi nous nous retrouvons !&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Moi-même (pas vraiment, c&#39;est juste pour l&#39;ambiance)&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Me voilà donc avec cette implémentation simple :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-direction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; column&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; space-between&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/JQ5_suVr2I-390.avif 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/JQ5_suVr2I-390.webp 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/JQ5_suVr2I-390.webp&quot; alt=&quot;Le main correctement placé au centre de l&#39;espace vide.&quot; width=&quot;195&quot; height=&quot;399&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Chacun des trois descendants directs du &lt;code&gt;body&lt;/code&gt; a une bordure bleue. Jusqu&#39;ici, tout va bien.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Je suis donc heureux, comme tout développeur front quand les choses s&#39;alignent correctement.&lt;/p&gt;
&lt;p&gt;Mais alors que l&#39;application grandit, je réalise que je vais avoir besoin d&#39;englober le &lt;code&gt;main&lt;/code&gt; et le &lt;code&gt;footer&lt;/code&gt; à l&#39;intérieur d&#39;un composant Angular unique, pour des raisons structurelles propres à l&#39;application.&lt;/p&gt;
&lt;p&gt;C&#39;est alors que ma belle page se brise, et vous pouvez comprendre pourquoi en regardant la structure générée par l&#39;apparition de ce nouveau composant :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;my-component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;my-component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hélas ! Flexbox ne s&#39;intéresse à rien d&#39;autre qu&#39;à ses propres enfants directs, qui sont maintenant &lt;code&gt;header&lt;/code&gt; et &lt;code&gt;my-component&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/fewaY2D75e-390.avif 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/fewaY2D75e-390.webp 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/fewaY2D75e-390.webp&quot; alt=&quot;Le header est placé en haut, le main et le footer sont ensembles, collés en bas.&quot; width=&quot;195&quot; height=&quot;399&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      Regardez les bordures bleues : le &lt;code&gt;body&lt;/code&gt; n&#39;a plus que deux enfants directs.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Ma première idée fut de faire de &lt;code&gt;my-component&lt;/code&gt; un conteneur flex lui-même, mais je n&#39;allai pas très loin avec cette idée.&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;my-component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-direction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; column&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; space-between&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;figure&quot;&gt;
    &lt;picture class=&quot;picture&quot;&gt;
    &lt;source type=&quot;image/avif&quot; srcset=&quot;https://bastiencalou.fr/img/5ikEQEL6Tp-390.avif 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://bastiencalou.fr/img/5ikEQEL6Tp-390.webp 390w&quot; sizes=&quot;(max-width: 48em) 100vw, 48rem&quot; /&gt;
    &lt;img src=&quot;https://bastiencalou.fr/img/5ikEQEL6Tp-390.webp&quot; alt=&quot;Le main est collé sous le header, avec un grand espace entre le main et le footer.&quot; width=&quot;195&quot; height=&quot;399&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
  &lt;/picture&gt;
    &lt;figcaption&gt;
      &lt;code&gt;my-component&lt;/code&gt; est un conteneur flex lui-même... Mais cela ne centre pas le bloc &lt;code&gt;main&lt;/code&gt; pour autant.
    &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;p&gt;Pensez-y un instant : comment vous y prendriez-vous ?&lt;/p&gt;
&lt;h2 id=&quot;une-methode-douteuse&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/layout-css-empechez-les-frameworks-d-englober-vos-composants/#une-methode-douteuse&quot;&gt;Une méthode douteuse&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Je sais que vous n&#39;y avez pas pensé un instant et que vous avez continué votre lecture. Je ne vous en veux pas.&lt;/p&gt;
&lt;p&gt;Une méthode à laquelle je n&#39;avais pas pensé avant d&#39;écrire cet article est d&#39;ajouter un pseudo-élément à &lt;code&gt;my-component&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;my-component::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;my-component&lt;/code&gt; a désormais trois enfants : le pseudo-élément &lt;code&gt;before&lt;/code&gt;, le &lt;code&gt;main&lt;/code&gt; et le &lt;code&gt;footer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Voici le résultat en action !&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;GaJyXZ&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/GaJyXZ&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Il n&#39;y a qu&#39;à remplacer le contenu du pseudo-élément par une chaîne vide, et voilà ! Parfois, une solution un peu sournoise comme celle-ci est si simple qu&#39;elle en devient attractive...&lt;/p&gt;
&lt;h2 id=&quot;une-methode-plus-propre&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/layout-css-empechez-les-frameworks-d-englober-vos-composants/#une-methode-plus-propre&quot;&gt;Une méthode plus propre&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Mais ajouter un pseudo-élément juste pour tromper flexbox ne me paraît pas extrêmement propre !&lt;/p&gt;
&lt;p&gt;Il y a quelques semaines, j&#39;ai lu cet excellent article de Rachel Andrews : &lt;a href=&quot;https://www.smashingmagazine.com/2019/05/display-box-generation/&quot;&gt;Digging Into The Display Property: Box Generation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En lisant les informations à propos de &lt;code&gt;display: content&lt;/code&gt;, j&#39;avais deux pensées parallèles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ça alors, c&#39;est fort intéressant...&lt;/li&gt;
&lt;li&gt;...mais je ne vais jamais m&#39;en servir.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mais en travaillant sur mon problème de layout, l&#39;article me revint à l&#39;esprit. En voici un extrait :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;La valeur &lt;code&gt;display: contents&lt;/code&gt; retire la boîte (&lt;em&gt;box&lt;/em&gt;) à laquelle elle est appliquée de l&#39;arbre des boîtes (&lt;em&gt;box tree&lt;/em&gt;), de la même façon que &lt;code&gt;display: none&lt;/code&gt;, mais en laissant les enfants en place.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Rachel Andrews, &lt;cite&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2019/05/display-box-generation/#display-contents&quot;&gt;Digging Into The Display Property: Box Generation&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;En d&#39;autres termes, cela sera équivalent (dans notre cas !) à ce qu&#39;il se passerait si l&#39;on commentait l&#39;élément (mais pas ses enfants) :&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- &amp;lt;my-component&gt; --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;footer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- &amp;lt;/my-component&gt; --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voici comment procéder dans les faits :&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;my-component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; contents&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;postAside&quot;&gt;Note : En réalité, certaines propriétés CSS (&lt;code&gt;font-size&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;...) appliquées à l&#39;élément impactent toujours ses enfants. Donc commenter l&#39;élément n&#39;est pas strictement équivalent, mais vous avez l&#39;idée.&lt;/div&gt;
&lt;p&gt;Donc... Cela signifie-t-il que du point de vue de flexbox, &lt;code&gt;main&lt;/code&gt; et &lt;code&gt;footer&lt;/code&gt; sont de nouveau des enfants directs du &lt;code&gt;body&lt;/code&gt; ? Oui ! &lt;code&gt;my-component&lt;/code&gt; n&#39;a plus besoin d&#39;être un conteneur flex lui-même. La propriété &lt;code&gt;justify-content: space-between&lt;/code&gt; appliquée au &lt;code&gt;body&lt;/code&gt; fonctionne de nouveau.&lt;/p&gt;
&lt;p&gt;C&#39;est la solution la plus courte présentée dans cet article : un sélecteur et une propriété. Presque magique.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;xNJVWG&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/xNJVWG&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;Notez que la bordure bleue qui entourait &lt;code&gt;my-component&lt;/code&gt; a disparu : en effet, la boîte n&#39;est plus rendue, donc les propriétés correspondantes (&lt;code&gt;margin&lt;/code&gt;, &lt;code&gt;padding&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt;...) n&#39;ont plus d&#39;effet.&lt;/p&gt;
&lt;p&gt;Bien que j&#39;aime la belle simplicité de cette solution, &lt;code&gt;display: contents&lt;/code&gt; possède ses inconvénients.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;display: contents&lt;/code&gt; peut provoquer des &lt;strong&gt;problèmes d&#39;accessibilité&lt;/strong&gt;, car l&#39;élément est caché de l&#39;arbre d&#39;accessibilité. Si vous l&#39;utilisez sur un élément &lt;code&gt;ul&lt;/code&gt;, l&#39;information qu&#39;il s&#39;agit d&#39;une liste sera perdue dans de nombreux navigateurs.&lt;/p&gt;
&lt;p&gt;Ce n&#39;est pas un problème dans notre cas, cependant, puisque &lt;code&gt;my-component&lt;/code&gt; ne véhicule pas de sens sémantique particulier. Mais l&#39;on pourrait toutefois se méfier du &lt;strong&gt;support navigateur&lt;/strong&gt;, qui est dans cette zone grise que j&#39;appelerai la zone &lt;q&gt;meh...&lt;/q&gt;.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : &lt;code&gt;display: contents&lt;/code&gt; est désormais largement supporté, bien que &lt;a href=&quot;https://caniuse.com/?search=display%3A%20contents&quot;&gt;caniuse.com&lt;/a&gt; rapporte toujours de nombreux problèmes d&#39;accessibilité. À juger au cas par cas, donc.&lt;/div&gt;
&lt;h2 id=&quot;une-methode-encore-plus-propre&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;directLink&quot; href=&quot;https://bastiencalou.fr/layout-css-empechez-les-frameworks-d-englober-vos-composants/#une-methode-encore-plus-propre&quot;&gt;Une méthode encore plus propre&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici donc la technique &lt;code&gt;margin: auto&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ce n&#39;est qu&#39;en rédigeant cet article que je me suis souvenu d&#39;un autre article, un des meilleurs que j&#39;ai lu sur le sujet: &lt;a href=&quot;https://hackernoon.com/flexbox-s-best-kept-secret-bd3d892826b6&quot;&gt;Flexbox&#39;s Best Kept Secret&lt;/a&gt;, de Sam Provenza. Il date de 2015 et j&#39;ai utilisé ce « secret » un grand nombre de fois depuis.&lt;/p&gt;
&lt;p&gt;Quatre ans plus tard, je ne suis pas sûr qu&#39;il soit bien connu. Mais vous pouvez utiliser &lt;code&gt;margin-left: auto&lt;/code&gt;, pas exemple, pour « pousser » un élément flexbox aussi loin que possible vers la droite.&lt;/p&gt;
&lt;p&gt;Voyez plutôt ce Codepen. L&#39;élément de prix possède la propriété &lt;code&gt;margin-left: auto&lt;/code&gt;.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;YzomaaP&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/YzomaaP&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;C&#39;est extrèmement utile ! Avec cette technique, il devient possible de pousser un élément dans n&#39;importe quelle direction, horizontale ou verticale.&lt;/p&gt;
&lt;p&gt;Mais il y avait une partie de l&#39;article que j&#39;avais oubliée :&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
      &lt;blockquote&gt;
        &lt;p&gt;Si vous ne spécifiez pas de direction et que vous appliquez simplement &lt;code&gt;margin: auto&lt;/code&gt;, l&#39;élément distribura l&#39;espace disponible des deux cotés, équitablement.&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;figcaption&gt;Sam Provenza, &lt;cite&gt;&lt;a href=&quot;https://hackernoon.com/flexbox-s-best-kept-secret-bd3d892826b6&quot;&gt;Flexbox&#39;s Best Kept Secret&lt;/a&gt;&lt;/cite&gt;&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;p&gt;Ainsi, le « secret » fonctionne aussi avec plusieurs marges &lt;code&gt;auto&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et la voici donc, cette merveilleuse solution à notre problème : faire de &lt;code&gt;my-component&lt;/code&gt; un conteneur flex de nouveau, et utiliser &lt;code&gt;margin: auto 0&lt;/code&gt; sur l&#39;élément &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;postAside&quot;&gt;Mise à jour 2024 : Utiliser la propriété logique &lt;code&gt;margin-block: auto&lt;/code&gt; nous éviterait d&#39;avoir à spécifier le &lt;code&gt;0&lt;/code&gt;, qui m&#39;a toujours un peu gêné...&lt;/div&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code tabindex=&quot;0&quot; class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;my-component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; flex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;flex-direction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; column&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; space-between&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voici le résultat en action.&lt;/p&gt;
&lt;p class=&quot;codepen&quot; data-height=&quot;415&quot; data-default-tab=&quot;result&quot; data-theme-id=&quot;dark&quot; data-slug-hash=&quot;ZNjWRN&quot; data-user=&quot;bcalou&quot; style=&quot;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 2px solid;
      margin: 1em 0;
      padding: 1em;
    &quot;&gt;
    &lt;span&gt;
      &lt;a href=&quot;https://codepen.io/bcalou/pen/ZNjWRN&quot;&gt;Voir le code sur CodePen&lt;/a&gt;.
    &lt;/span&gt;
  &lt;/p&gt;
  &lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;
  &lt;/script&gt;
&lt;p&gt;L&#39;espace libre est distribué équitablement entre le dessus et le dessous de l&#39;élément &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Pas de pseudo-élément magique. Moins de risque d&#39;accessibilité et de compatibilité. Simplement la majestueuse et toute puissante flexpower™.&lt;/p&gt;
&lt;p&gt;L&#39;épopée du centrage vertical ne s&#39;achève jamais.&lt;/p&gt;
</content>
	</entry>
</feed>
