Skip to content

Commit 5ab03c6

Browse files
Support for dark mode (#48)
* Turn all colors into variables This turns each color into a $elem(-$pseudo)-$attribute named variable on the :root element and replaces their usage by calling the var() function instead. * Add dark mode colors This overrides the colors when prefers-color-scheme is set to dark, indicating the user has configured their OS or user-agent to prefer a light text on dark background instead. It includes a way to manually toggle dark mode by using a data attribute on the html element. The syntax highlight colors are also updated to support dark mode. * feat: improve dark mode implementation and docs - Dark mode based on classes, with three options - light mode (default, no changes needed) - auto dark mode (based on prefers-color-scheme; latex-dark-auto class on body) - dark mode (latex-dark class on body) - Removed the mention of dark mode from the lead and moved it to the getting started section - Moved the dark mode section up, since it is a pretty important feature imo. - Added a dark mode toggle button for demo - Added a CSS filter to the proof symbol so that it shows up as dark grey instead of white - Built the project to generate the minified css file Co-authored-by: Vincent Dörig <[email protected]>
1 parent 0624ef7 commit 5ab03c6

4 files changed

Lines changed: 150 additions & 30 deletions

File tree

index.html

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ <h2>Contents</h2>
8080
<ol>
8181
<li><a href="#scroll-overflow">Scroll Overflow</a></li>
8282
<li><a href="#syntax-highlighting">Syntax Highlighting</a></li>
83+
<li><a href="#dark-mode">Dark Mode</a></li>
8384
</ol>
8485
</li>
8586
</ol>
@@ -100,6 +101,11 @@ <h2 id="getting-started">Getting Started</h2>
100101
(optional) Add any classes to elements described in the
101102
<a href="#class-based-elements">next section</a>.
102103
</li>
104+
<li>
105+
(optional) Add dark mode by adding the <code>latex-dark-auto</code> class to the <code
106+
class="language-html">&lt;body&gt;</code>.
107+
More infos <a href="#dark-mode">here</a>.
108+
</li>
103109
<li>
104110
(optional) If you need support for
105111
<span class="latex">L<span>a</span>T<span>e</span>X</span> math, add
@@ -231,6 +237,24 @@ <h2 id="sidenotes">Sidenotes</h2>
231237
<!-- <blockquote>You could also have sidenotes inside blockquotes just like this one <label for="sn-quote"
232238
class="sidenote-toggle">🔖</label><input type="checkbox" id="sn-quote" class="sidenote-toggle" /><span
233239
class="sidenote">Hello there!</span>.</blockquote> -->
240+
241+
<h2 id="dark-mode">Dark Mode</h2>
242+
<p>There is built-in support for dark mode. By default, the document is in light mode. To enable dark mode, add
243+
the
244+
<code>latex-dark</code> class to the <code class="language-html">&lt;body&gt;</code> element. This will force
245+
the document to be in dark mode.
246+
</p>
247+
<p>If you want enable dark mode based on the
248+
<code>prefers-color-scheme</code> CSS media query, then use the <code>latex-dark-auto</code> class instead.
249+
</p>
250+
<p>You can also add a dark mode toggle to your site by adding a button and a tiny bit of JavaScript:</p>
251+
<pre><code class="language-html">&lt;button id="dark-mode-toggle"&gt;Toggle dark mode&lt;/button&gt;</code></pre>
252+
<pre><code class="language-javascript">document
253+
.querySelector("#dark-mode-toggle")
254+
.addEventListener('click', () => {
255+
document.body.classList.toggle("latex-dark");
256+
});</code></pre>
257+
<p>Like this: <button id="dark-mode-toggle">Toggle dark mode</button></p>
234258

235259
<h2 id="alternative-typeface">Alternative Typeface</h2>
236260
<p><span class="latex">L<span>a</span>T<span>e</span>X</span>.css uses Latin Modern by default. If you don't like this typeface (hard to read, too thin, etc.), you can switch to the <a href="https://github.com/alerque/libertinus"><code>Libertinus</code></a> font family by adding a class of <code>libertinus</code> to the <code class="language-html">&lt;body&gt;</code> tag. Click the button below to switch between Latin Modern and Libertinus.</p>
@@ -451,12 +475,17 @@ <h3 id="syntax-highlighting">Syntax Highlighting</h3>
451475
inlineMath: [['$', '$'],],
452476
},
453477
}
454-
const toggle = document.getElementById('typeface-toggle')
478+
const typeFaceToggle = document.getElementById('typeface-toggle')
455479
const typeface = document.getElementById('typeface')
456-
toggle.addEventListener('click', () => {
480+
typeFaceToggle.addEventListener('click', () => {
457481
document.body.classList.toggle('libertinus')
458482
typeface.textContent = document.body.classList.contains('libertinus') ? 'Libertinus' : 'Latin Modern'
459483
})
484+
485+
const darkModeToggle = document.getElementById('dark-mode-toggle')
486+
darkModeToggle.addEventListener('click', () => {
487+
document.body.classList.toggle('latex-dark')
488+
})
460489
</script>
461490
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
462491
<script async src="prism/prism.js"></script>

prism/prism.css

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,56 @@
66
* Licensed under MIT (https://github.com/vincentdoerig/latex-css/blob/master/LICENSE)
77
*/
88

9+
:root {
10+
--bg-color: #F0F0F0;
11+
--color: black;
12+
--token-teal: #407f80;
13+
--token-black: #000000;
14+
--token-grey: #666666;
15+
--token-green: #007f00;
16+
--token-lime: #7d8f29;
17+
--token-brown: #9a6e3a;
18+
--token-red: #ba2121;
19+
--token-fuchsia: #dd4a68;
20+
--token-orange: #e90;
21+
--token-pink: #BA6687;
22+
}
23+
24+
.latex-dark {
25+
--bg-color: #2d2d2d;
26+
--color: #ccc;
27+
--token-teal: #90D0D0;
28+
--token-black: #ccc;
29+
--token-grey: #999;
30+
--token-green: #51B53F;
31+
--token-lime: #B4C55D;
32+
--token-brown: #D3A26B;
33+
--token-red: #FA5E4F;
34+
--token-fuchsia: #FF839B;
35+
--token-orange: #FFCF4C;
36+
--token-pink: #F49BBC;
37+
}
38+
39+
@media (prefers-color-scheme: dark) {
40+
.latex-dark-auto {
41+
--bg-color: #2d2d2d;
42+
--color: #ccc;
43+
--token-teal: #90D0D0;
44+
--token-black: #ccc;
45+
--token-grey: #999;
46+
--token-green: #51B53F;
47+
--token-lime: #B4C55D;
48+
--token-brown: #D3A26B;
49+
--token-red: #FA5E4F;
50+
--token-fuchsia: #FF839B;
51+
--token-orange: #FFCF4C;
52+
--token-pink: #F49BBC;
53+
}
54+
}
55+
956
code[class*='language-'],
1057
pre[class*='language-'] {
11-
color: black;
58+
color: var(--color);
1259
background: none;
1360
text-align: left;
1461
white-space: pre;
@@ -35,7 +82,7 @@ pre[class*='language-'] {
3582
}
3683

3784
pre[class*='language-'] {
38-
background: #F0F0F0;
85+
background: var(--bg-color);
3986
}
4087

4188
/* Inline code */
@@ -49,18 +96,18 @@ pre[class*='language-'] {
4996
.token.prolog,
5097
.token.doctype,
5198
.token.cdata {
52-
color: #407f80;
99+
color: var(--token-teal);
53100
}
54101

55102
.token.punctuation,
56103
.token.constant {
57-
color: #000000;
104+
color: var(--token-black);
58105
}
59106

60107
.token.punctuation.attr-equals,
61108
.token.number,
62109
.token.operator {
63-
color: #666666;
110+
color: var(--token-grey);
64111
}
65112

66113
.token.namespace {
@@ -73,42 +120,42 @@ pre[class*='language-'] {
73120
.token.symbol,
74121
.token.deleted,
75122
.token.keyword {
76-
color: #007f00;
123+
color: var(--token-green);
77124
}
78125

79126
.token.selector,
80127
.token.attr-name,
81128
.token.char,
82129
.token.builtin,
83130
.token.inserted {
84-
color: #7d8f29;
131+
color: var(--token-lime);
85132
}
86133

87134
.token.entity,
88135
.token.url,
89136
.language-css .token.string,
90137
.style .token.string {
91-
color: #9a6e3a;
138+
color: var(--token-brown);
92139
}
93140

94141
.token.atrule,
95142
.token.attr-value,
96143
.token.string,
97144
.token.attr-value .punctuation:not(.attr-equals) {
98-
color: #ba2121;
145+
color: var(--token-red);
99146
}
100147

101148
.token.class-name {
102-
color: #dd4a68;
149+
color: var(--token-fuchsia);
103150
}
104151

105152
.token.important,
106153
.token.variable {
107-
color: #e90;
154+
color: var(--token-orange);
108155
}
109156

110157
.token.regex {
111-
color: #BA6687;
158+
color: var(--token-pink);
112159
}
113160

114161
.token.important,

style.css

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,49 @@
100100
box-sizing: border-box;
101101
}
102102

103+
:root {
104+
--body-color: hsl(0, 5%, 10%);
105+
--body-bg-color: hsl(210, 20%, 98%);
106+
--link-visited: hsl(0, 100%, 33%);
107+
--link-focus-outline: hsl(220, 90%, 52%);
108+
--pre-bg-color: hsl(210, 28%, 93%);
109+
--kbd-bg-color: hsl(210, 5%, 100%);
110+
--kbd-border-color: hsl(210, 5%, 70%);
111+
--table-border-color: black;
112+
--sidenote-target-border-color: hsl(55, 55%, 70%);
113+
--footnotes-border-color: hsl(0, 0%, 39%);
114+
}
115+
116+
.latex-dark {
117+
--body-color: hsl(0, 0%, 86%);
118+
--body-bg-color: hsl(0, 0%, 16%);
119+
--link-visited: hsl(196 80% 77%);
120+
--link-focus-outline: hsl(215, 63%, 73%);
121+
--pre-bg-color: hsl(0, 1%, 25%);
122+
--kbd-bg-color: hsl(0, 0%, 16%);
123+
--kbd-border-color: hsl(210, 5%, 70%);
124+
--table-border-color: white;
125+
--sidenote-target-border-color: hsl(0, 0%, 59%);
126+
--footnotes-border-color: hsl(0, 0%, 59%);
127+
--proof-symbol-filter: invert(80%);
128+
}
129+
130+
@media (prefers-color-scheme: dark) {
131+
.latex-dark-auto {
132+
--body-color: hsl(0, 0%, 86%);
133+
--body-bg-color: hsl(0, 0%, 16%);
134+
--link-visited: hsl(196 80% 77%);
135+
--link-focus-outline: hsl(215, 63%, 73%);
136+
--pre-bg-color: hsl(0, 1%, 25%);
137+
--kbd-bg-color: hsl(0, 0%, 16%);
138+
--kbd-border-color: hsl(210, 5%, 70%);
139+
--table-border-color: white;
140+
--sidenote-target-border-color: hsl(0, 0%, 59%);
141+
--footnotes-border-color: hsl(0, 0%, 59%);
142+
--proof-symbol-filter: invert(80%);
143+
}
144+
}
145+
103146
/* Remove default margin */
104147
body,
105148
h1,
@@ -143,8 +186,8 @@ body {
143186

144187
counter-reset: theorem definition sidenote-counter;
145188

146-
color: hsl(0, 5%, 10%);
147-
background-color: hsl(210, 20%, 98%);
189+
color: var(--body-color);
190+
background-color: var(--body-bg-color);
148191

149192
text-rendering: optimizeLegibility;
150193
}
@@ -166,12 +209,12 @@ a:not([class]) {
166209
/* Make links red */
167210
a,
168211
a:visited {
169-
color: #a00;
212+
color: var(--link-visited);
170213
}
171214

172215
a:focus {
173216
outline-offset: 2px;
174-
outline: 2px solid hsl(220, 90%, 52%);
217+
outline: 2px solid var(--link-focus-outline);
175218
}
176219

177220
/* Make images easier to work with */
@@ -212,15 +255,15 @@ pre {
212255
max-width: 100%;
213256
overflow: auto;
214257
border-radius: 4px;
215-
background: hsl(210, 28%, 93%);
258+
background: var(--pre-bg-color);
216259
}
217260
pre code {
218261
font-size: 95%;
219262
position: relative;
220263
}
221264
kbd {
222-
background: hsl(210, 5%, 100%);
223-
border: 1px solid hsl(210, 5%, 70%);
265+
background: var(--kbd-bg-color);
266+
border: 1px solid var(--kbd-border-color);
224267
border-radius: 2px;
225268
padding: 2px 4px;
226269
font-size: 75%;
@@ -232,28 +275,28 @@ table {
232275
border-spacing: 0;
233276
width: auto;
234277
max-width: 100%;
235-
border-top: 2.27px solid black;
236-
border-bottom: 2.27px solid black;
278+
border-top: 2.27px solid var(--table-border-color);
279+
border-bottom: 2.27px solid var(--table-border-color);
237280
/* display: block; */
238281
overflow-x: auto; /* does not work because element is not block */
239282
/* white-space: nowrap; */
240283
counter-increment: caption;
241284
}
242285
/* add bottom border on column table headings */
243286
table tr > th[scope='col'] {
244-
border-bottom: 1.36px solid black;
287+
border-bottom: 1.36px solid var(--table-border-color);
245288
}
246289
/* add right border on row table headings */
247290
table tr > th[scope='row'] {
248-
border-right: 1.36px solid black;
291+
border-right: 1.36px solid var(--table-border-color);
249292
}
250293
table > tbody > tr:first-child > td,
251294
table > tbody > tr:first-child > th {
252-
border-top: 1.36px solid black;
295+
border-top: 1.36px solid var(--table-border-color);
253296
}
254297
table > tbody > tr:last-child > td,
255298
table > tbody > tr:last-child > th {
256-
border-bottom: 1.36px solid black;
299+
border-bottom: 1.36px solid var(--table-border-color);
257300
}
258301

259302
th,
@@ -351,6 +394,7 @@ dl dd {
351394
}
352395
.proof:after {
353396
content: '◾️';
397+
filter: var(--proof-symbol-filter);
354398
position: absolute;
355399
right: -12px;
356400
bottom: -2px;
@@ -395,7 +439,7 @@ dl dd {
395439

396440
/* (WIP) add border when a sidenote is clicked on */
397441
.sidenote:target {
398-
border: hsl(55, 55%, 70%) 1.5px solid;
442+
border: var(--sidenote-target-border-color) 1.5px solid;
399443
padding: 0 .5rem;
400444
scroll-margin-block-start: 10rem;
401445
}
@@ -476,7 +520,7 @@ input.sidenote-toggle {
476520
margin-bottom: 0.4rem;
477521
}
478522
.footnotes {
479-
border-top: 1px solid hsl(0, 0%, 39%);
523+
border-top: 1px solid var(--footnotes-border-color);
480524
}
481525

482526
/* Center title and paragraph */

0 commit comments

Comments
 (0)