Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/EmielH/tale-hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlberki <lberki@users.noreply.github.com>2022-05-05 12:12:10 +0300
committerGitHub <noreply@github.com>2022-05-05 12:12:10 +0300
commit776f966edfbc33120d61edef0e65ddcdba44263a (patch)
tree43b753af14fbcfa2cbdba373139bda0397a5804a
parentc95051b93d756d5653ebe36a8f5f2d556b3843a0 (diff)
Add dark modeHEADmaster
Add dark mode See #65
-rw-r--r--assets/scss/tale/_base.scss12
-rw-r--r--assets/scss/tale/_catalogue.scss12
-rw-r--r--assets/scss/tale/_code.scss14
-rw-r--r--assets/scss/tale/_layout.scss29
-rw-r--r--assets/scss/tale/_pagination.scss12
-rw-r--r--assets/scss/tale/_post.scss8
-rw-r--r--assets/scss/tale/_toc.scss15
-rw-r--r--assets/scss/tale/_variables.scss54
-rw-r--r--layouts/_default/baseof.html1
-rw-r--r--layouts/partials/darkmode.html3
-rw-r--r--layouts/partials/head.html2
-rw-r--r--static/js/darkmode.js65
12 files changed, 179 insertions, 48 deletions
diff --git a/assets/scss/tale/_base.scss b/assets/scss/tale/_base.scss
index 6c2471b..c096ebb 100644
--- a/assets/scss/tale/_base.scss
+++ b/assets/scss/tale/_base.scss
@@ -5,8 +5,8 @@
html,
body {
- color: $default-color;
- background-color: #fff;
+ color: var(--default-color);
+ background-color: var(--background-color);
margin: 0;
padding: 0;
}
@@ -31,19 +31,19 @@ h3,
h4,
h5,
h6 {
- color: $default-shade;
+ color: var(--default-shade);
font-family: $sans-serif;
line-height: normal;
}
a {
- color: $blue;
+ color: var(--blue);
text-decoration: none;
}
blockquote {
- border-left: .25rem solid $grey-2;
- color: $grey-1;
+ border-left: .25rem solid var(--grey-2);
+ color: var(--grey-1);
margin: .8rem 0;
padding: .5rem 1rem;
diff --git a/assets/scss/tale/_catalogue.scss b/assets/scss/tale/_catalogue.scss
index 0587bc5..ec065a1 100644
--- a/assets/scss/tale/_catalogue.scss
+++ b/assets/scss/tale/_catalogue.scss
@@ -1,7 +1,7 @@
.catalogue {
&-item {
- border-bottom: 1px solid $grey-2;
- color: $default-color;
+ border-bottom: 1px solid var(--grey-2);
+ color: var(--default-color);
display: block;
padding: 2rem 0;
@@ -16,13 +16,13 @@
}
&-time {
- color: $default-tint;
+ color: var(--default-tint);
font-family: $serif-secondary;
letter-spacing: .5px;
}
&-title {
- color: $default-shade;
+ color: var(--default-shade);
display: block;
font-family: $sans-serif;
font-size: 2rem;
@@ -31,8 +31,8 @@
}
&-line {
- @include transition(all .3s ease-out);
- border-top: .2rem solid $default-shade;
+ @include transition($color-transition, width .3s ease-out);
+ border-top: .2rem solid var(--default-shade);
display: block;
width: 2rem;
}
diff --git a/assets/scss/tale/_code.scss b/assets/scss/tale/_code.scss
index 11f1c53..6d97161 100644
--- a/assets/scss/tale/_code.scss
+++ b/assets/scss/tale/_code.scss
@@ -4,9 +4,9 @@ code {
}
code {
- background-color: $grey-4;
+ background-color: var(--grey-4);
border-radius: 3px;
- color: $code-color;
+ color: var(--code-color);
font-size: 85%;
padding: .25em .5em;
white-space: pre-wrap;
@@ -23,8 +23,14 @@ pre code {
padding: 0;
}
+pre code > span {
+ // This isn't very pretty, but the precise RGB values are generated
+ // server-side, the usual trick of putting the colors in CSS variables does
+ // not quite work and this is the best I could come up with.
+ filter: var(--code-filter);
+}
.highlight {
- background-color: $grey-4;
+ background-color: var(--grey-4);
border-radius: 3px;
line-height: 1.4;
margin: 0 0 1rem;
@@ -36,7 +42,7 @@ pre code {
}
.lineno {
- color: $default-tint;
+ color: var(--default-tint);
display: inline-block; // Ensures the null space also isn't selectable
padding: 0 .75rem 0 .25rem;
// Make sure numbers aren't selectable
diff --git a/assets/scss/tale/_layout.scss b/assets/scss/tale/_layout.scss
index 8d56834..c459510 100644
--- a/assets/scss/tale/_layout.scss
+++ b/assets/scss/tale/_layout.scss
@@ -1,3 +1,7 @@
+* {
+ @include transition($color-transition);
+}
+
.container {
margin: 0 auto;
max-width: 800px;
@@ -17,8 +21,19 @@ footer,
width: 80%;
}
+#darkModeToggle {
+ float: right;
+ position: sticky;
+ top: 2rem;
+ margin-right: 2rem;
+ margin-top: 2rem;
+ font-size: 2rem;
+
+ cursor: pointer;
+}
+
.nav {
- box-shadow: 0 2px 2px -2px $shadow-color;
+ box-shadow: 0 2px 2px -2px var(--shadow-color);
overflow: auto;
&-container {
@@ -28,8 +43,8 @@ footer,
}
&-title {
- @include transition(all .2s ease-out);
- color: $default-color;
+ @include transition($color-transition, opacity .2s ease-out);
+ color: var(--default-color);
display: inline-block;
margin: 0;
padding-right: .2rem;
@@ -48,8 +63,8 @@ footer,
}
li {
- @include transition(all .2s ease-out);
- color: $default-color;
+ @include transition($color-transition, opacity .2s ease-out);
+ color: var(--default-color);
display: inline-block;
opacity: .6;
padding: 0 2rem 0 0;
@@ -65,7 +80,7 @@ footer,
}
a {
- color: $default-color;
+ color: var(--default-color);
font-family: $sans-serif;
}
}
@@ -90,7 +105,7 @@ footer {
text-align: center;
span {
- color: $default-color;
+ color: var(--default-color);
font-size: .8rem;
}
}
diff --git a/assets/scss/tale/_pagination.scss b/assets/scss/tale/_pagination.scss
index 3700e15..8b391b5 100644
--- a/assets/scss/tale/_pagination.scss
+++ b/assets/scss/tale/_pagination.scss
@@ -1,18 +1,18 @@
.pagination {
- border-top: .5px solid $grey-2;
+ border-top: .5px solid var(--grey-2);
font-family: $serif-secondary;
padding-top: 2rem;
position: relative;
text-align: center;
span {
- color: $default-shade;
+ color: var(--default-shade);
font-size: 1.1rem;
}
.top {
- @include transition(all .3s ease-out);
- color: $default-color;
+ @include transition($color-transition, opacity .3s ease-out);
+ color: var(--default-color);
font-family: $sans-serif;
font-size: 1.1rem;
opacity: .6;
@@ -23,8 +23,8 @@
}
.arrow {
- @include transition(all .3s ease-out);
- color: $default-color;
+ @include transition($color-transition, opacity .3s ease-out);
+ color: var(--default-color);
position: absolute;
&:hover,
diff --git a/assets/scss/tale/_post.scss b/assets/scss/tale/_post.scss
index 3680d80..61cff18 100644
--- a/assets/scss/tale/_post.scss
+++ b/assets/scss/tale/_post.scss
@@ -2,7 +2,7 @@
padding: 3rem 0;
&-info {
- color: $default-tint;
+ color: var(--default-tint);
font-family: $serif-secondary;
letter-spacing: 0.5px;
text-align: center;
@@ -13,7 +13,7 @@
}
&-title {
- color: $default-shade;
+ color: var(--default-shade);
font-family: $sans-serif;
font-size: 4rem;
margin: 1rem 0;
@@ -21,7 +21,7 @@
}
&-line {
- border-top: 0.4rem solid $default-shade;
+ border-top: 0.4rem solid var(--default-shade);
display: block;
margin: 0 auto 3rem;
width: 4rem;
@@ -41,7 +41,7 @@
}
img + em {
- color: $default-tint;
+ color: var(--default-tint);
display: block;
font-family: $sans-serif;
font-size: 0.9rem;
diff --git a/assets/scss/tale/_toc.scss b/assets/scss/tale/_toc.scss
index 6492ba7..08ccd47 100644
--- a/assets/scss/tale/_toc.scss
+++ b/assets/scss/tale/_toc.scss
@@ -17,6 +17,10 @@ aside.toc {
float: left;
height: 0;
overflow: display;
+
+ // This is apparenty necessary so that the table of contents covers elements
+ // with the "filter:" property set.
+ z-index: 1;
}
#tocTitle {
@@ -34,7 +38,7 @@ aside.toc {
}
#tocContainer {
- background: $grey-3;
+ background-color: var(--grey-3);
border-radius: 1rem;
margin: 2rem;
padding: 1rem;
@@ -54,11 +58,14 @@ aside.toc {
width: calc(2rem + var(--measured-title-width));
--measured-title-width: 2.4rem;
- @include transition(all .1s ease-out);
+@include transition(
+ $color-transition,
+ width .1s ease-out,
+ height .1s ease-out);
}
#tocContainer > div {
- border-left: 0.4rem solid black;
+ border-left: 0.4rem solid var(--default-shade);
padding-left: 1rem;
}
@@ -72,7 +79,7 @@ aside.toc {
// No transition on width so that there is no re-wrapping during the
// opening/closing transition
- @include transition(height .1s ease-out);
+ @include transition($color-transition, height .1s ease-out);
}
nav#TableOfContents ul {
diff --git a/assets/scss/tale/_variables.scss b/assets/scss/tale/_variables.scss
index 92d1114..43914ba 100644
--- a/assets/scss/tale/_variables.scss
+++ b/assets/scss/tale/_variables.scss
@@ -1,15 +1,47 @@
// Colors
-$default-color: #555;
-$default-shade: #353535;
-$default-tint: #aaa;
-$grey-1: #979797;
-$grey-2: #e5e5e5;
-$grey-3: #f0f0f0;
-$grey-4: #f9f9f9;
-$white: #fff;
-$blue: #4a9ae1;
-$shadow-color: rgba(0, 0, 0, .2);
-$code-color: #bf616a;
+// This is necessary because some elements want to set transitions themselves,
+// which would result in deleting the color transitions specified in less
+// specific selectors.
+$color-transition:
+ background-color .4s ease-out,
+ color .4s ease-out,
+ border-color .4s ease-out,
+ box-shadow .4s ease-out;
+
+
+// Make the default be dark mode. That way, the more complicated case is the
+// default and thus bugs are discovered earlier.
+:root.light {
+ --default-color: #555;
+ --background-color: #fff;
+ --default-shade: #353535;
+ --default-tint: #aaa;
+ --grey-1: #979797;
+ --grey-2: #e5e5e5;
+ --grey-3: #f0f0f0;
+ --grey-4: #f9f9f9;
+ --white: #fff;
+ --blue: #4a9ae1;
+ --shadow-color: rgba(0, 0, 0, .2);
+ --code-color: #bf616a;
+ --code-filter: ;
+}
+
+:root:not(.light) {
+ --default-color: #888;
+ --background-color: #000;
+ --default-shade: #989898;
+ --default-tint: #555;
+ --grey-1: #606060;
+ --grey-2: #404040;
+ --grey-3: #202020;
+ --grey-4: #181818;
+ --white: #fff;
+ --blue: #1d6baf;
+ --shadow-color: rgba(0, 0, 0, .2);
+ --code-color: #a3434c;
+ --code-filter: contrast(0.4) brightness(0.9);
+}
// Fonts
$serif-primary: 'Libre Baskerville', 'Times New Roman', Times, serif;
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index 866a593..4bf1dc8 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -3,6 +3,7 @@
{{ partial "head.html" . }}
<body>
{{ partial "header.html" . }}
+ {{ partial "darkmode.html" . }}
{{ block "main" . }}{{ end }}
{{ partial "footer.html" . }}
</body>
diff --git a/layouts/partials/darkmode.html b/layouts/partials/darkmode.html
new file mode 100644
index 0000000..1016b53
--- /dev/null
+++ b/layouts/partials/darkmode.html
@@ -0,0 +1,3 @@
+<div id="darkModeToggle" onclick="toggleDarkMode()">
+ &#9680; <!-- Circle with left half black -->
+</div>
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index fe10a91..0d9b512 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -30,4 +30,6 @@
<!-- RSS -->
<link href="{{ with .OutputFormats.Get "RSS" }}{{ .RelPermalink }}{{ end }}" rel="alternate" type="application/rss+xml" title="{{ .Site.Title }}" />
+
+ <script src="{{ "js/darkmode.js" | relURL }}"></script>
</head>
diff --git a/static/js/darkmode.js b/static/js/darkmode.js
new file mode 100644
index 0000000..8161f9a
--- /dev/null
+++ b/static/js/darkmode.js
@@ -0,0 +1,65 @@
+"use strict";
+
+const LOCALSTORAGE_KEY = "color-scheme";
+const LIGHT_CLASS = "light";
+let mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
+
+// true means "dark scheme", false means "light scheme". Ugly, bit simple.
+function storedToBool(s) {
+ if (s === "dark") {
+ return true;
+ } else if (s === "light") {
+ return false;
+ } else {
+ return null;
+ }
+}
+
+function ensureScheme(desiredScheme) {
+ let osScheme = mediaQuery.matches;
+
+ // Only store the preference if it's not the same as the OS one.
+ if (desiredScheme === osScheme) {
+ localStorage.removeItem(LOCALSTORAGE_KEY);
+ } else {
+ localStorage.setItem(LOCALSTORAGE_KEY, desiredScheme ? "dark" : "light");
+ }
+
+ if (desiredScheme) {
+ document.documentElement.classList.remove(LIGHT_CLASS);
+ } else {
+ document.documentElement.classList.add(LIGHT_CLASS);
+ }
+}
+
+function initDarkMode() {
+ let storedScheme = storedToBool(localStorage.getItem(LOCALSTORAGE_KEY));
+ let osScheme = mediaQuery.matches;
+
+ // When the class of the document element is changed from a script running in the <HEAD>
+ // element, no CSS transition defined on the changed properties takes place.
+ ensureScheme(storedScheme === null ? osScheme : storedScheme);
+ mediaQuery.addEventListener("change", osDarkModeChanged);
+}
+
+function osDarkModeChanged(query) {
+ let osScheme = query.matches;
+ let pageScheme = !document.documentElement.classList.contains(LIGHT_CLASS);
+
+ // If the current preference is the same as that of the OS, we assume that the user also wants
+ // to change the color scheme of the web page. If not, we assume that they consciously overrode
+ // the OS and we don't change anything.
+ if (pageScheme != osScheme) {
+ ensureScheme(!pageScheme);
+ }
+}
+
+function toggleDarkMode() {
+ // The easiest is to decide based on the current color scheme.
+ let currentScheme = !document.documentElement.classList.contains(LIGHT_CLASS);
+ ensureScheme(!currentScheme);
+}
+
+// Doing this in an onload handler would let the initial color appear for a
+// split second.
+initDarkMode();