A mirror of my website's source code.

By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

 creating_a_theme_switch.html

View raw Download
text/html • 15.25 kiB
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
49
href="/blog"
50
>Blog Index</a>
51
</li>
52
53
<li >
54
<a
55
aria-current="location"
56
href="/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">&lt;</span><span class="nt">button</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;theme-switch&quot;</span><span class="p">&gt;</span>Switch Theme<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</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">&quot;light&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;dark&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;clown&quot;</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">&quot;#theme-switch&quot;</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">&quot;click&quot;</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 &quot;themes&quot; 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">&gt;=</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&#39;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>