<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="https://chierchia.fr/wp-content/plugins/pretty-rss-feeds/xslt/pretty-feed.xsl" type="text/xsl" media="screen" ?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dark mode - Ange Chierchia</title>
	<atom:link href="https://chierchia.fr/tag/dark-mode/feed/" rel="self" type="application/rss+xml" />
	<link>https://chierchia.fr/tag/dark-mode/</link>
	<description>Développeur Web full-stack</description>
	<lastBuildDate>Sun, 13 Oct 2024 10:59:14 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://chierchia.fr/wp-content/uploads/cropped-16350293-SSDKVqo3-32x32.jpg</url>
	<title>dark mode - Ange Chierchia</title>
	<link>https://chierchia.fr/tag/dark-mode/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
					<title>Mettre en place un « dark mode » simplement</title>
					<link>https://chierchia.fr/2023/09/mettre-en-place-un-dark-mode-simplement/</link>
					<comments>https://chierchia.fr/2023/09/mettre-en-place-un-dark-mode-simplement/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Wed, 20 Sep 2023 21:13:36 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dark mode]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2023/09/mettre-en-place-un-dark-mode-simplement</guid>

					<description><![CDATA[Cela fait un moment que j’avais mis en place la possibilité de choisir entre un thème sombre et un thème clair pour lire mon blog. Et ça fait presque aussi longtemps qu’il était éclaté au sol, dans le sens où même si on choisissait l’un des modes, les préférences du système prenaient de nouveau le [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Cela fait un moment que j’avais mis en place la possibilité de choisir entre un thème sombre et un thème clair pour lire mon blog. Et ça fait presque aussi longtemps qu’il était éclaté au sol, dans le sens où même si on choisissait l’un des modes, les préférences du système prenaient de nouveau le dessus au rechargement de page. On va voir ensemble ce qui n’allait pas et donc ce qu’il ne faut pas faire.<span id="more-1314"></span></p>
<h2 id="conditionner-le-mode-sombre-en-javascript-et-via-les-styles-css">Conditionner le mode sombre en JavaScript ET via les styles CSS</h2>
<p>Si il y a bien une chose à éviter, c’est celle-ci. En effet, il est préférable de décider qui, de JavaScript ou CSS, va gérer le mode sombre et de s’y tenir, afin d’éviter que des conditions définies en JavaScript soient écrasées par une feuille de style. C’est le soucis que j’avais ici : je définissais à la fois des règles CSS ciblées par un attribut <code class="language-plaintext highlighter-rouge">html[data-theme="dark"]</code> qui était ensuite modifié via JavaScript ainsi que des règles ciblées par une media query <code class="language-plaintext highlighter-rouge">@media (prefers-color-scheme: dark)</code>.</p>
<div class="language-css highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nt">html</span><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="s1">"dark"</span><span class="o">]</span> <span class="nt">body</span> <span class="p">{</span>
    <span class="nl">background-color</span><span class="p">:</span> <span class="m">#222222</span><span class="p">;</span>
    <span class="nl">color</span><span class="p">:</span> <span class="m">#ffffff</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">@media</span> <span class="p">(</span><span class="n">prefers-color-scheme</span><span class="p">:</span> <span class="n">dark</span><span class="p">)</span> <span class="p">{</span>
  <span class="nt">body</span> <span class="p">{</span>
    <span class="nl">background-color</span><span class="p">:</span> <span class="m">#222222</span><span class="p">;</span>
    <span class="nl">color</span><span class="p">:</span> <span class="m">#ffffff</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p>Et voici ce que je faisais en JavaScript :</p>
<p>Je sauvegardais dans un booléen <code class="language-plaintext highlighter-rouge">isDarkMode</code> le résultat de la condition media query <code class="language-plaintext highlighter-rouge">(prefers-color-scheme: dark)</code> ou de l’attribut <code class="language-plaintext highlighter-rouge">[data-theme="dark"]</code>.</p>
<p>Au chargement de la page, le thème était défini sur “dark” ou “light” suivant la valeur du booléen <code class="language-plaintext highlighter-rouge">isDarkMode.</code> Puis lorsque un changement au niveau de la media query était détecté, j’appelai à nouveau ma fonction <code class="language-plaintext highlighter-rouge">switchTheme()</code>.</p>
<div class="language-javascript highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="kd">var</span> <span class="nx">themeToggle</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">.site-theme-switcher</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">useDark</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">matchMedia</span><span class="p">(</span><span class="dl">"</span><span class="s2">(prefers-color-scheme: dark)</span><span class="dl">"</span><span class="p">)</span>
<span class="kd">var</span> <span class="nx">isDarkMode</span> <span class="o">=</span> <span class="nx">useDark</span><span class="p">.</span><span class="nx">matches</span> <span class="o">||</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">html</span><span class="dl">'</span><span class="p">).</span><span class="nx">getAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-theme</span><span class="dl">'</span><span class="p">)</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">dark</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">var</span> <span class="nx">switchTheme</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">darkModeState</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="nx">darkModeState</span><span class="p">)</span> <span class="p">{</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">html</span><span class="dl">'</span><span class="p">).</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-theme</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">dark</span><span class="dl">'</span><span class="p">);</span>
		<span class="nx">themeToggle</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-switch-theme</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">light</span><span class="dl">'</span><span class="p">);</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">html</span><span class="dl">'</span><span class="p">).</span><span class="nx">removeAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-theme</span><span class="dl">'</span><span class="p">);</span>
		<span class="nx">themeToggle</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-switch-theme</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">dark</span><span class="dl">'</span><span class="p">);</span>
	<span class="p">}</span>
<span class="p">};</span>

<span class="nb">document</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">DOMContentLoaded</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
	<span class="nx">switchTheme</span><span class="p">(</span><span class="nx">isDarkMode</span><span class="p">);</span>
	<span class="nx">useDark</span><span class="p">.</span><span class="nx">addListener</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
		<span class="nx">switchTheme</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">matches</span><span class="p">);</span>
	<span class="p">});</span>
<span class="p">});</span>
</code></pre>
</div>
</div>
<p>En soit, cette méthode n’est pas mauvaise, mais à aucun moment elle ne prend en compte la volonté de l’utilisateur de visionner votre site Web en version sombre ou non. C’est le système d’exploitation de l’ordinateur qui prend la main.</p>
<h2 id="ne-pas-utiliser-de-cookie">Ne pas utiliser de cookie</h2>
<p>Une autre erreur à ne pas faire, si on veut que l’utilisateur garde la main, c’est de ne pas enregistrer son choix. C’est tout bête, mais je ne m’en suis rendu compte que ce soir en me penchant enfin sur le problème…</p>
<p>La correction est simple à mettre en place, il suffit de modifier la fonction <code class="language-plaintext highlighter-rouge">switchTheme()</code> comme suit :</p>
<div class="language-javascript highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="kd">var</span> <span class="nx">switchTheme</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">darkModeState</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="nx">darkModeState</span><span class="p">)</span> <span class="p">{</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">html</span><span class="dl">'</span><span class="p">).</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-theme</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">dark</span><span class="dl">'</span><span class="p">);</span>
		<span class="nx">themeToggle</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-switch-theme</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">light</span><span class="dl">'</span><span class="p">);</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">cookie</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">darktheme=true; expires=Fri, 31 Dec 9999 23:59:59 GMT;</span><span class="dl">"</span><span class="p">;</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">html</span><span class="dl">'</span><span class="p">).</span><span class="nx">removeAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-theme</span><span class="dl">'</span><span class="p">);</span>
		<span class="nx">themeToggle</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-switch-theme</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">dark</span><span class="dl">'</span><span class="p">);</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">cookie</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">darktheme=false; expires=Fri, 31 Dec 9999 23:59:59 GMT;</span><span class="dl">"</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">};</span>
</code></pre>
</div>
</div>
<p>Il conviendra ensuite de modifier l’écouteur de l’évènement <code class="language-plaintext highlighter-rouge">DOMContentLoaded</code> comme ceci :</p>
<div class="language-javascript highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">DOMContentLoaded</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">cookie</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="dl">"</span><span class="s2">;</span><span class="dl">"</span><span class="p">).</span><span class="nx">some</span><span class="p">((</span><span class="nx">item</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">item</span><span class="p">.</span><span class="nx">trim</span><span class="p">().</span><span class="nx">startsWith</span><span class="p">(</span><span class="dl">"</span><span class="s2">darktheme=true</span><span class="dl">"</span><span class="p">)))</span> <span class="p">{</span>
		<span class="nx">switchTheme</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
	<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">cookie</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="dl">"</span><span class="s2">;</span><span class="dl">"</span><span class="p">).</span><span class="nx">some</span><span class="p">((</span><span class="nx">item</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">item</span><span class="p">.</span><span class="nx">trim</span><span class="p">().</span><span class="nx">startsWith</span><span class="p">(</span><span class="dl">"</span><span class="s2">darktheme=false</span><span class="dl">"</span><span class="p">)))</span> <span class="p">{</span>
		<span class="nx">switchTheme</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="nx">switchTheme</span><span class="p">(</span><span class="nx">useDark</span><span class="p">.</span><span class="nx">matches</span><span class="p">);</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p>Et voilà !</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2023/09/mettre-en-place-un-dark-mode-simplement/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
