Cammy's Big Rambly Journal

Hello! I notice you're using Netscape (or other CSS-noncompliant user agent—in which case, consider this an easter egg) to view this journal. Because Netscape is so titanically shit, I have disabled image viewing on Netscape specifically. If I didn't, you would notice random images being replaced with each other and similar such strangeness. The posts are still visible, but you'll be missing the images, which are half the context of these posts.

You should use RetroZilla if you can; it runs on Windows 95 and up and gives you a perfect cammy.somnol viewing experience, plus more comfortable Web browsing on retrocomputers in general. Failing that, Internet Explorer 3 (which amusingly also displays this message, since it doesn't support the display CSS property) and up will also work perfectly fine for seeing my journal posts.


May 04, 2025
The hifi style selector

So that, when you tire of one side, the other serves you best


I've had a bit of a second wind with mari.somnol recently! There was talk on Aftersleep about other people implementing theme switchers on their sites, and it reminded me I put up something similar on hifi and then only gave people two themes to play with. I've now added two more and made a whole ton of improvements to how the style selector works as a whole and how the site loads assets based on the current theme.

As one of those projects I intended to get back to when I had more time (and now I do), let me take you through how the hifi style selector works. I always used to be curious how people implement these on their sites, so if you're not sure yourself, hopefully you can gleam something from my setup. (I'm gonna assume you know a bit about Web pages, how they're put together, and how they're scripted. Mostly, it's just terminology.)

There's three basic components to a theme switcher:

  1. Different stylesheets/assets for each theme, of course
  2. A mechanism to add and remove stylesheets to the page DOM as necessary
  3. A way for the browser to remember the selected theme

Working backwards, the third one is pretty much always going to involve cookies. Cookies always felt to me like a fancy "big site" thing I'd never play with, but they're super straightforward, literally just a line of text stored by the browser with various bits of information inside of it. The cookie for hifi stores the preferred theme, the paths over which the cookie data applies to (so, the whole site), and an expiration date, which I set to be a year past when the cookie is first set.

The second one involves a "frontend" way to select themes and a "backend" way to add and remove them from the DOM, which is just a fancy way of saying the page as seen by programming languages. You can technically use PHP for this, but even as a huge PHP acolyte, I can't really recommend it. PHP is a serverside language, so you'd have to submit an HTML form with the selected theme in the dropdown, parse it on the server, and send back the page with the new theme baked into the markup. I dunno, you don't bring a KitchenAid mixer to a gunfight. If it involves styling the client, you should script the client and use JavaScript for it, even if it is the Devil's Language.

And the first? Here's my setup for that:

The way theme assets are organized on hifi

Each style is given its own folder in my site files with fonts, images, and stylesheets that pertain only to that style. It's almost like a WordPress theme in execution, and it's very clean and self-contained. It's also really easy to make child versions of other themes. I have a dark version of Clean and Tidy, the default hifi theme, which was as simple as @importing in the clean.css in the dark stylesheet and then overwriting a couple of its rules to change the colors and background of the page. Any updates to Clean and Tidy also get applied to the dark version completely automatically.

Making a new theme is actually a lot simpler than I expected it to be. hifi's markup is very theme-agnostic, and the individual page components can be rearranged any which way using CSS grid. The markup is organized so the page collapses into a scrollable tower for phones without the desktop CSS rules, and then above a certain page width, the desktop CSS rules are loaded in using a media query and the layout takes shape. If there's any elements I don't want to appear on certain themes, I mark them with a [theme]_hide class in the markup, and then set that class to display: none; in the theme stylesheet. There is a little bit of duplicating elements on each page, and I could clean that up, but it doesn't seriously impact speed or functionality, so I don't really care to.

styleswitcher.js is where all the magic happens. I've commented up the code, and I guess it's not doing anything too crazy, but in case reading JavaScript makes you break out in hives (me too), I'll give you the rundown in plain English.

  1. readStyleFromCookie() gets called first—if the cookie exists, get the preferred style from it, if not, set the preferred style to the default, Clean and Tidy.
  2. Both of these options pass the preferred style to the setStyle() function, which does the actual heavy lifting of setting up the new stylesheet on the page.
  3. setStyle() starts by nuking all stylesheets from the page DOM. In other words, the page is now completely plain HTML.
  4. setStyle() then adds a new stylesheet to the head of the page by constructing a brand new element and setting it to load the stylesheet at /styles/[preferred style]/[preferred style].css.
  5. I also determine the date one year from now and set a variable to it. This is what we'll put in the cookie for an expiration date. If I don't set it, the cookie only seems to last a few days, which is annoying.
  6. I create/update the cookie. Whatever style is preferred, whether it's the default or an existing preference, is now set as the preference once again.
  7. The style selector dropdown gets set to the value of the preferred style as soon as the page is fully done loading, so that way the name in the box matches the name of the active theme.
  8. One more step! There's a function called loadStyleExtras() that the preferred style gets passed to. This is a big catch-all function for making elements that only exist on certain themes. Nostalgiamining Away (the minerteaux theme) and The Platypus Years (the mari_nc1 theme) load in header images. The Platypus Years also loads in a script of rotating footer lyrics from songs like mari_nc1 had. These would be unnecessary on other themes and add page bloat, so they're loaded in only if you're using that theme. Some themes have no extras at all.

Say the user then sets a new style from the style selector dropdown in the footer of my site. There's an onChange attribute attached to this dropdown that calls readStyleFromSelect(). This reads the value of the dropdown, passes its value to setStyle(), and the process begins from step three anew.

I've said it too many times now, but it bears repeating: this is so fucking satisfying to me. For one thing, it just works well. Modern HTML and CSS have enabled me to completely transmogrify any page into any layout; this kind of thing would simply not be possible on lofi, where the markup is far more closely tethered to the layout and functionality of the page. (And nofi doesn't use CSS at all! Or have much of a layout to change!) Beyond that, each theme is based on an older site I've had, and at any moment, I can just look at my modern, 2025 work and art and album reviews in any old random Cammy site layout, like the most bonkers kind of alternate reality time travel. My favorite at the moment has to be the minerteaux theme—for a site that was literally only up for a week at the time, I'm strangely attached to it. Must be those XFader textures. Pleasing to use and to look at.

I always thought that hifi and returning to mariteaux.somnolescent.net would come with a feeling of my identity online being solidified again, and it really has. I've just been feeling a lot more confident in myself and how I look to the world lately. It's lovely.

If you're curious about further themes—I think I've run out of Cammy sites to turn into themes, really. mari_v1 is now a theme. mari_v2 became lofi, so it doesn't really need to also be a theme on hifi. mari_v3 is the default hifi theme in light and dark variants. mari_nc1 is a theme now. mari_nc2 is a little too basic to turn into a theme. minerteaux is a theme now. I could do some meme layouts based on other Somnolians' sites, but those would date potentially with redesigns. I was thinking of doing a Bootstrap version of hifi a la dcb_bootstrap, but when I started adding Bootstrap grid classes to the markup, it started breaking the other themes, so that's a no, sadly.

I'm happy with this, honestly! If there do come more opportunities for theme fun, it's dead simple to make new ones and add them, but for now, the current set pleases me greatly. The final frontier of hifi work is honestly just to get my stories on there again. I've finally been poking at DocBook and XSLT, and as overwhelming as it is at first blush, I think it'll be everything I need to keep six (!) different versions of each story in harmony. That'll be a journal post for a day when I have that figured out, though.