Post

Perfect dark mode theme for GitHub Pages with Jekyll

Original guide

Watch Video and read Meet Jekyll - The Static Site Generator by Techno Tim.

Fixes and workarounds

Sign in to GitHub and use this template to generate a brand new repository and name it USERNAME.github.io, where USERNAME represents your GitHub username.

Then change version in Gemfile to work around a recent issue:

1
gem "jekyll-theme-chirpy", "~> 6.4.2"

Add the following steps between Setup Ruby and Build site to avoid local clone & bundle.

1
2
3
4
5
      - name: Bundle
        run: bundle

      - name: Lock
        run: cat Gemfile.lock

You can later commit Gemfile.lock to lock the dependencies and can always see the versions in action run history.

Also, choose Page deploy via workflow to avoid double action run.

Customize favicons

Better code blocks

Create /assets/css/jekyll-theme-chirpy.scss to use some opinionated syntax highlighting improvements.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
---
---

@import 'main';

/* append your custom style below */

@media (prefers-color-scheme: dark) {
  html:not([data-mode]), html[data-mode=dark], * {
    .highlight {
      pre {
        font-size: .70rem;
      }
      .nf {
        color: #079bd9;
      }
      .o, .mi, .mf {
        color: #3792b8 !important;
      }
      .p {
        color: #69a1b9 !important;
      }
      .k, .kn, .kr, .kp, .kv, .ow {
        color: rgb(255, 123, 114) !important;
      }
      .c, .c1, .cm {
        color: #525252 !important;
      }
    }
  }
}

.code-header button:hover {
  background-color: transparent !important;
}
.code-header button {
  border: none !important;
}

.highlight .lineno {
  opacity: 0.2;
}

.sidebar-bottom {
  .icon-border {
    opacity: 0;
  }
}

.embed-video {
  max-width: 500px;
}

References:

Example of Python code syntax highlighting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import re
import wsgiref.simple_server as ss
import urllib.parse

1.0  # float

def match_route(path, routes):
    for pattern, handler in routes.items():
        if path == pattern:
            return handler, {}
        elif pattern.startswith('^') and (match := re.match(pattern, path)):
            return handler, {"match": match}


def respond(handler, status=200, **kwargs):
    args = ()
    if isinstance(handler, tuple):
        status, response, *args = handler
    elif callable(handler):
        response = handler(**kwargs)
        if isinstance(response, tuple):
            status, response, *args = response
    else:
        response = handler
    return status, response, *args

Comment on

This post is licensed under CC BY 4.0 by the author.