Still working on this website
reader@yggdrasil ~/posts/2024/still-working-on-this $ ls tags/
website css javascript
reader@yggdrasil ~/posts/2024/still-working-on-this $ stat -c %.10w content
2024-09-22
reader@yggdrasil ~/posts/2024/still-working-on-this $ cat content
This time I made some improvements to the website.
> Watch out, construction site!
Ever since I've bought my domain, I've been putting all the actual content of my website to thematic subdomains. Since I had nothing to put to the main domain I just used it as a sort of dead-end for the website, with the following game over text from the Legend of Zelda: Majora's Mask:
"
You've met with a terrible fate, haven't you?
"
-- Majora's Mask, 2000
After creating more and more silly little projects on the site, I soon realized it was time for me to create at least some sort of menu where a random visitor can check all the subdomains out (especially since I myself was starting to forget just what all the current projects/subdomains were).
So a few days ago I've put together this horrible abomination of a webpage for my main domain. I'm going to include a screenshot of it, in case I ever decide to change it to something less a crime against humanity:
> Starting to feel like an icon (would look good on the sidebar)
I also added a few more links to the sidebar, like my Mastodon which I'm planning to start using more frequently again. So I had to add a few icons for these entries (and the Arch Linux logo btw). Luckily iconify had some really cute Apache license icons which suited my purpose perfectly.
> Return of the light theme
Though the first iteration of the blog had white background, it was hardly what you could call a light theme. You can check out how it looked in the first blogpost. After I received some advice that I should actually implement a light theme (and I myself experienced just how hard it is to read anything on the blog while sitting outdoors on a platform of the train station with my laptop on my lap during daytime), I've felt it might actually be a good idea to do it.
My first question was how to do it. Luckily I was already working with a predefined palette of colors for the 8 ANSI color (plus foreground and background). These were defined in the :root of the css file, so the only thing I had to do was change those when another theme was set.
I know that prefers-color-scheme: light is a thing in css, but I was not fond of only using that for setting the preferred theme for multiple reasons:
- I may want to change the theme manually even if I have a system preference (like on the train station; see above); dark mode is sometimes called night mode for a reason
- <foreshadowing> I might want more than two color schemes </foreshadowing> let's get the most out of the system if I implement it anyway
- totally personal reason: I prefer dark mode, but I use Firefox with fingerprintingProtection, so my agent always lies light mode preference :)
So of course my other choice was good old javascript. I wanted to avoid using javascript on the blog for as long as I can. Three blogposts was the limit as it turns out.
> Setting theme with "shell scripts"
I wanted the theme changing section of the sidebar to look thematically similar to the rest of the blog. So just like the tag listing, I went with a listing of "shell scripts" for the themes, and colored them green (the color for files with execute permission in ls). So while they essentially work like buttons, they look more like links. That's because they are:
<a href="javascript:void(0);" class="icon-text theme-selector-light" onclick="setTheme('light')"> <img src="/assets/image/sun.svg" class="svg-icon"> <span>sweet-celestial.sh</span> </a>
I know this goes a bit against visual clarity, but I liked the idea, so I went with it anyway.
The current theme is stored in localStorage and the data-theme attribute is applied to the root html element when loading the page or changing the theme:
const THEME_KEY = "data-theme";
function updateTheme() { let theme = localStorage.getItem(THEME_KEY); if (theme != null) { document.documentElement.setAttribute(THEME_KEY, theme) } }
function setTheme(theme) { localStorage.setItem(THEME_KEY, theme); updateTheme(); }
The root colors in the .css file are then looked up in the [data-theme="light"] section, if light theme was selected.
> Coloring the icons
Some of the svg icons on the blog use specific "hardcoded" colors. For example the Arch Linux logo has the official #1793d1 blue color. But other icons, like the ones for the Website and the E-mail are using the same color scheme as the rest of the blog. So when changing theme, I need them to change color as well. I was able to achieve this with tagging them with the filter-yellow class, and then styling it for each theme separately:
.filter-yellow { filter: brightness(0) saturate(100%) invert(91%) sepia(86%) saturate(596%) hue-rotate(314deg) brightness(96%) contrast(97%); }
For the conversion from hex color to css filter, I used the tool on Isotropic's website. I only have yellow colored icons now, obviously I will need to generate the rest of the palette if I want to use them.
> Flash bang out!
After this... everything was ready. Or so I thought. I was getting the good old white flickering effect on almost every page load. In the end I realized I was only applying the theme on window.onload, instead of just calling it immediately at the end of the script file. I changed it and this solved the bulk of the problem. Also, the font was loading a bit slow, but separating it into a different .css file and loading it first seemed to help with that as well.
> Theme summary
Light theme is opt-in currently. I may use prefers-color-scheme: light later as a fallback, if no preference was set by the user, but luna-eclipsed (dark mode) is the default color scheme for now. If however you are one of those guys who like their retinas burned to crisp, feel free to use sweet-celestial (light mode). Both of them can be found on the side panel under I want different colors.
While I was making the light theme, I just had to reuse the system and make a hidden easter egg theme as well. It's not really usable for reading, but it's fun. Try finding it!
- Hint 1:
- Hint 2:
- Hint 3:
> Blogpostception
I also had to implement a few things for writing this post. For example, I styled some new elements, like lists or the quote at the top of the post. I made marko extensions for the quote, the fake html tags (<whisper>psst... hey... like this one!</whisper>), and for the spoiler tags.
The spoiler text was tricky, because I wanted them to be clickable (rather than using some hover event) without the usage of javascript. In the end I used a hidden checkbox with two labels, of which only one is displayed at a time. This way for the hidden text I could display a series of rectangles (▉ [<- this is not a spoiler]), so you can't accidentally spoil yourself with selection. Try selecting the following text, without clicking on it: However I had to keep the whitespaces so that the lines still wrap the same way as if they had normal content.
Here's the html code for the spoiler above:
<span> <input type="checkbox" class="spoiler" id="spoiler5"> <label class="spoiler-on" for="spoiler5"> <span>▉▉▉ ▉▉▉ ▉▉▉ ▉▉▉</span> </label> <label class="spoiler-off" for="spoiler5"> <span>Now you see me!</span> </label> </span>
And the css:
.spoiler { position: absolute; left: -10000px; }
.spoiler:checked ~ label.spoiler-on, .spoiler:not(:checked) ~ label.spoiler-off { display: none; }
label.spoiler-on { background-color: var(--term-fg); }
label.spoiler-off { background-color: var(--term-black); }
I had to use an ugly workaround for the checkbox (.spoiler). When I set it to display: none it was sometimes scrolling around on the page, trying to find the position of the checkbox. By keeping it "visible" (just -10000 pixels to the left of the screen), the browser thinks it's on the screen, so it does not start to jump around.
> Afterwords
I still have some things to do on the blog, and especially on the other subdomains, but this blogpost is getting too long already. And I'm tired.
So see you in the next one, I guess!
reader@yggdrasil ~/posts/2024/still-working-on-this $ find other_posts/ -type f -exec head {} +
Making this blog
This is the story of how I was finally able to create my first normal looking webpage, this blog.
Let there be light theme...
...and there was light theme.