creating_a_theme_switch.html
HTML document, ASCII text, with very long lines (979)
1<!DOCTYPE html> 2<html lang="en-us" prefix="og: https://ogp.me/ns# article: http://ogp.me/ns/article# profile: https://ogp.me/ns/profile#"> 3 4<head> 5 6 7<meta charset="UTF-8" /> 8<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 9<title>Create a Theme Switch - S0G</title> 10<link rel="stylesheet" href="/src/global.css" /> 11<meta property="og:locale" content="en_US" /> 12<meta property="og:site_name" content="Steve0Greatness" /> 13<meta property="og:image" content="/OG-Image.png" /> 14 15<link rel="stylesheet" href="/src/code-blocks.css" /> 16<link rel="stylesheet" href="/src/blog.css" /> 17<link rel="alternate" href="/blog/creating_a_theme_switch.txt" type="text/plain" title="Post source" /> 18<meta property="og:title" content="Create a Theme Switch" /> 19<meta property="og:type" content="article" /> 20<meta property="article:published_time" content="2021-12-08T00:00:00Z" /> 21<meta property="article:author" content"https://steve0greatness.github.io" /> 22<meta property="article:modified_time" content="2024-02-03T00:00:00Z" /> 23<meta property="profile:first_name" content="Steve0Greatness" /> 24<meta property="profile:username" content="Steve0Greatness" /> 25<meta property="profile:gender" content="male" /> 26<meta property="og:url" content="https://steve0greatness.github.io/blog/creating_a_theme_switch.html" /> 27 28</head> 29 30<body> 31<header> 32<h2><a href="/"><img src="/SteveLogo.webp" height="35" width="215" alt="Steve0Greatness" /></a></h2> 33<nav> 34<a href="/blog">Blog</a> 35<a href="/list/link-tree.html">Link Tree</a> 36</nav> 37</header> 38 39<nav aria-label="breadcrumbs" aria-roledescription="Site breadcrumb"> 40<ol class="breadcrumbs"> 41 42<li> 43<a href="/">Index</a> 44</li> 45 46<li > 47<a 48 49href="/blog" 50>Blog Index</a> 51</li> 52 53<li > 54<a 55aria-current="location" 56href="/blog/creating_a_theme_switch.html" 57>Create a Theme Switch</a> 58</li> 59 60 61</ol> 62</nav> 63<main> 64<h1>Create a Theme Switch</h1> 65<article> 66<header> 67<div role="toolbar" class="toolbar"> 68<strong>Share</strong> 69<a href="https://toot.kytta.dev/?text=Take a look at this article by @S0G@mastodon.social: https://steve0greatness.github.io/blog/creating_a_theme_switch.html" title="Share to Mastodon"> 70<img src="/toot-kytta-dev-icon.png" width="16" height="16" aria-hidden="true" title="Share to Mastodon" /> 71</a> 72<a href="/blog/creating_a_theme_switch.html" title="Direct link"> 73<img src="/link-icon.png" width="16" height="16" aria-hidden="true" title="Direct link" /> 74</a> 75<a href="/blog/creating_a_theme_switch.txt" title="Markdown source"> 76<img src="/md-src.png" width="16" height="16" aria-hidden="true" /> 77</a> 78</div> 79<div class="time-stamps"> 80<time datetime="2021-12-08T00:00:00-08:00">2021 Dec 08 PST</time> 81- <span aria-hidden="true" style="font-style:italic">Revision as of: </span> <time datetime="2024-02-03T00:00:00-08:00" aria-label="Revision">2024 Feb 03 PST</time> 82 83</div> 84</header> 85<p>This is a simple tutorial on how to make a simple theme switcher.</p> 86 87<p>First step is to create the themes you'll want on your site. You may just want a light and dark mode, however, you may also want other themes. As an example: a clown theme that makes the page absurdly colorful, like a GeoCities site in the early 2000s. For these themes, you can use CSS variables set on the <code>html</code> parent tag(all other elements are considered children of <code>html</code>). Variables can be set in CSS using double hyphens followed by a sequence of text that can use numbers(but not at the start), letters(capital or lowercase), underscores, and hyphens; these variables can then be accessed within your text using the <code>var()</code> function with the name of the variable(including the starting hyphens). You can change out the CSS variables using different selectors on the <code>html</code> tag within the CSS, for me: I'm using the <code>[data-theme]</code> attribute; however, you can use classes if you want. Here is the CSS I wrote:</p> 88 89<div class="codehilite"> 90<pre><span></span><code><span class="nt">html</span><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="nt">light</span><span class="o">]</span><span class="w"> </span><span class="p">{</span> 91<span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="mh">#fff</span><span class="p">;</span> 92<span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="mh">#000</span><span class="p">;</span> 93<span class="w"> </span><span class="nv">--buttonBackground</span><span class="p">:</span><span class="w"> </span><span class="mh">#fefefe</span><span class="p">;</span> 94<span class="w"> </span><span class="nv">--buttonBorder</span><span class="p">:</span><span class="w"> </span><span class="mh">#ccc</span><span class="p">;</span> 95<span class="w"> </span><span class="nv">--buttonColor</span><span class="p">:</span><span class="w"> </span><span class="mh">#001</span><span class="p">;</span> 96<span class="p">}</span> 97<span class="nt">html</span><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="nt">dark</span><span class="o">]</span><span class="w"> </span><span class="p">{</span> 98<span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="mh">#000</span><span class="p">;</span> 99<span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="mh">#fff</span><span class="p">;</span> 100<span class="w"> </span><span class="nv">--buttonBackground</span><span class="p">:</span><span class="w"> </span><span class="mh">#101010</span><span class="p">;</span> 101<span class="w"> </span><span class="nv">--buttonBorder</span><span class="p">:</span><span class="w"> </span><span class="mh">#333</span><span class="p">;</span> 102<span class="w"> </span><span class="nv">--buttonColor</span><span class="p">:</span><span class="w"> </span><span class="mh">#fff</span><span class="p">;</span> 103<span class="p">}</span> 104<span class="nt">html</span><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="nt">clown</span><span class="o">]</span><span class="w"> </span><span class="p">{</span> 105<span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="mh">#f00</span><span class="p">;</span> 106<span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="mh">#00f</span><span class="p">;</span> 107<span class="w"> </span><span class="nv">--buttonBackground</span><span class="p">:</span><span class="w"> </span><span class="mh">#050</span><span class="p">;</span> 108<span class="w"> </span><span class="nv">--buttonBorder</span><span class="p">:</span><span class="w"> </span><span class="mh">#0a0</span><span class="p">;</span> 109<span class="w"> </span><span class="nv">--buttonColor</span><span class="p">:</span><span class="w"> </span><span class="mh">#0f0</span><span class="p">;</span> 110<span class="p">}</span> 111<span class="nt">button</span><span class="w"> </span><span class="p">{</span> 112<span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--buttonBackground</span><span class="p">);</span> 113<span class="w"> </span><span class="k">border</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--buttonBorder</span><span class="p">)</span><span class="w"> </span><span class="kc">solid</span><span class="w"> </span><span class="mi">3</span><span class="kt">px</span><span class="p">;</span> 114<span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--buttonColor</span><span class="p">);</span> 115<span class="p">}</span> 116</code></pre> 117</div> 118 119<p>Now we need to create a button that we will use to change the <code>[data-theme]</code> attribute. You (probably) already know what buttons are, so I won't go in depth about then. However: you will need to add an <code>[id]</code> to the button, this will come in play shortly.</p> 120 121<div class="codehilite"> 122<pre><span></span><code><span class="p"><</span><span class="nt">button</span> <span class="na">id</span><span class="o">=</span><span class="s">"theme-switch"</span><span class="p">></span>Switch Theme<span class="p"></</span><span class="nt">button</span><span class="p">></span> 123</code></pre> 124</div> 125 126<p>Now, it is time to write the JavaScript. First, you'll want to make a constant with the themes you filled into your CSS, for me, that was <code>dark</code>, <code>light</code>, and <code>clown</code>. I'll name this <code>themes</code>.</p> 127 128<div class="codehilite"> 129<pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">themes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">"light"</span><span class="p">,</span><span class="w"> </span><span class="s2">"dark"</span><span class="p">,</span><span class="w"> </span><span class="s2">"clown"</span><span class="p">];</span> 130</code></pre> 131</div> 132 133<p>We now need to query the <abbr title="Document Object Model">DOM</abbr> for our theme switch button. This can be done in 2 ways: <code>document.querySelector</code> or <code>document.getElementById</code>; personally, I prefer <code>querySelector</code>, as it allows you to write a CSS selector to get an element from the DOM, allowing for shorter, more digestible, code.</p> 134 135<p>We have to add a click event to the button. This can be done in 2 ways within JavaScript: <code>addEventListener("click", ...)</code> and <code>onclick</code>. I personally like <code>addEventListener</code> more, so I'll use that. Within the <code>addEventListener</code> function, you need to put a function. This function will control the logic of our theme switch. I'll call this function <code>SwitchTheme</code>, to reflect it's functionality.</p> 136 137<div class="codehilite"> 138<pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">ThemeSwitchButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">"#theme-switch"</span><span class="p">);</span> 139<span class="nx">ThemeSwitchButton</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">"click"</span><span class="p">,</span><span class="w"> </span><span class="nx">SwitchTheme</span><span class="p">());</span> 140<span class="kd">function</span><span class="w"> </span><span class="nx">SwitchTheme</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span> 141</code></pre> 142</div> 143 144<p>Explaining each part of this function as it's written out would take awhile, so instead, I'll add comments to the ends of each line giving a short explanation. Also, for the sake of shortness, I've placed <code>document.documentElement</code> inside the constant <code>HTML</code>, giving us access to the root element in the DOM(<code>html</code>).</p> 145 146<div class="codehilite"> 147<pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="nx">CurrentTheme</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">themes</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">HTML</span><span class="p">.</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">theme</span><span class="p">);</span><span class="w"> </span><span class="c1">// Gets how far in the current theme is into the "themes" constant.</span> 148<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">CurrentTheme</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="nx">themes</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// Checks if it's at the end of the array,</span> 149<span class="w"> </span><span class="nx">HTML</span><span class="p">.</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">theme</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">themes</span><span class="p">[</span><span class="mf">0</span><span class="p">];</span><span class="w"> </span><span class="c1">// If so, reset at the start.</span> 150<span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w"> </span><span class="c1">// Ends the function here, preventing next bit of code from running.</span> 151<span class="p">}</span> 152<span class="nx">HTML</span><span class="p">.</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">theme</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">themes</span><span class="p">[</span><span class="nx">CurrentTheme</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// Goes to the next theme.</span> 153</code></pre> 154</div> 155 156<p>Now we have a finished product. Here's the expected output:</p> 157 158<iframe id="finalProduct" src="/blog-files/theme-change-final.html" style="border:none"></iframe> 159 160<p><a href="/blog-files/theme-change-final.txt">See Code</a></p> 161 162</article> 163</main> 164<footer> 165<div class="footer-link-list-holder" role="group"> 166<span aria-hidden="true" id="footer-label-site-details" class="footer-link-list-label">Site Meta</span> 167<ol class="footer-link-list" aria-labelledby="footer-label-site-details"> 168<li><a href="/list/website-sources-mirrors.html">Source Code and Mirrors</a></li> 169<li><a href="https://steve0greatness.github.io/extras">Extras</a></li> 170</ol> 171</div> 172<div class="footer-link-list-holder" role="group"> 173<span aria-hidden="true" id="footer-label-social-accounts" class="footer-link-list-label">Social Accounts</span> 174<ol class="footer-link-list" aria-labelledby="footer-label-social-accounts"> 175<li><a href="https://mastodon.social/@S0G" rel="me">Mastodon</a></li> 176<li><a href="https://youtube.com/@s0g">YouTube</a></li> 177<li><a href="/list/link-tree.html">More...</a></li> 178</ol> 179</div> 180</footer> 181</body> 182 183</html>