The site uses cookies that you may not want. Continued use means acceptance. For more information see our privacy policy.

Ink Cream, the New Theme

Finally a fresh coat of paint on this old heap! Sit and read some of how it came to be.

For a while now the site has used the default theme, Twenty Twenty One. I liked it okay, but one thing that bothered me was that the dark mode wasn’t customizable, was kind of bland.

The other thing to know is that I use Stylus to clean up or modify styles on various websites I visit. For some time I’ve been using a semi-dark theme (the same light gray background as the light mode background here) on many news sites, and occasionally a dark version on others (again, same background as the dark theme here). That kind of daily testing led me to find it preferable, and so I wanted to bring that design to this site.

Browsing through Google’s selection, many fonts come close to being great but had at least one or two flaws I couldn’t abide.

The basic premise of the light theme is that websites don’t need to be white-backgrounds. We have shades of gray to use here. And that dark modes don’t need to be white-on-black. Again, we have shades. For the most part, I would be happy to use light themes if they weren’t pure white. All the web designers that shook their fists at the need to create dark variants could have made a compromise, but I haven’t seen any of them do so.

Even at night, the light theme of this site isn’t particularly bad to my eyes, though the dark mode is certainly nicer.

I found, a starter theme. It provided a solid base to build on. I later found out that WordPress is soon (sometime next year) to release a “Block theme” built for their new Gutenberg blocks system. I may eventually rebuild for that, or switch to it. It offers “full site editing,” which may kill off traditional themes. I’m not entirely sold yet, but I’m keeping an open mind and waiting to try it out and see what it offers.

I tried to add some functionality with plugins, but they mostly don’t offer an off-switch for their default styles, and trying to dequeue their styles is hit-or-miss, so I built more functionality into the theme itself. If I end up migrating to the new system, I may have to rework that functionality into plugins.

The one decision that skipped a plugin but I didn’t implement myself is code highlighting. After looking at client-side (JavaScript) options and server-side (plugin) options for code highlighting, I decided to go with neither. I can run code through pygmentize when I compose an article, and then I can add the markup directly to the post. I already self-handle other elements, like images. So if I get the itch to actually highlight code, that’s what I’ll do.

One of the big non-technical challenges was finding good typefaces. I opted to use Google Fonts to load nicer typefaces here. (I load them with WebFontLoader.) Browsing through Google’s selection, many fonts come close to being great but had at least one or two flaws I couldn’t abide. One had an inverted at-symbol (@), another had a capital C that looked too much like a G. Most sans-serif fonts don’t properly distinguish between uppercase I and lowercase L.

In the end, I dropped trying to have a separate serif face for headings, in part to keep the site light, and in part because trying to find two faces was too much.


Having not done much web development in a long while, here are some of the newer things I used in building the stylesheet.


Having been out of the loop, I didn’t realize :is() and :where() existed. I only use the latter, as it doesn’t influence the scoring of selectors. It lets you do things like:

    .recipe :where(.ingredient, .tool, .container) {
        font-weight: bold;

This saves you creating three separate selectors if you want all “important” items under a recipe to be boldfaced.


I knew that math functions existed, but clamp() is really nice. You give it three values:

  • minimum
  • variable
  • maximum

And it will let the outcome vary only within the bounds you set. Most of the time the variable will involve something with vw units, so that the outcome varies based on the screen width, but there are other ways to use it.

Custom property fallbacks

I’ve used custom properties in my user styles for awhile, so that I don’t have to recreate things like colors for every site I create a custom style for. But I didn’t know there are fallbacks. I only use them for filling the SVGs in the social media buttons:

    html:not([dark]) .soc-fill,
    html[dark] .soc-link:focus-visible .soc-fill {
        fill: var(--ic-soc-c0, #000);

    html[dark] .soc-fill,
    html:not([dark]) .soc-link:focus-visible .soc-fill {
        fill: var(--ic-soc-c1, #FFF);

I set fill values (--ic-soc-cN) for some icons, if the service calls for a particular color in their brand guide, but if not I can fallback to black or white (depending on the dark or light theme and whether or not keyboard focus is happening).

Other small bits

Testing in chromium taught me about will-change that hints the browser to expect repaints of an element. It probably isn’t that necessary given it’s only for the theme-mode toggle in the upper right, but it’s cool to know about. I was also able to use a media query for prefers-reduced-motion to stop that animation if someone has a relevant OS setting turned on.

I tried to get accessibility correct. Some of that was helped by WordPress itself, other parts helped by the underscores base. Proper accessibility design helps everyone, including people in early stages of a sight disorder or even someone who’s stressed or drunk or tired.

To improve accessibility, I removed placeholder text in form inputs. After trouble finding good colors that were within the contrast bounds, I did some thinking and reading. I decided that the only real purpose of placeholder text is to make forms look less plain. Multi-field forms need visible labels anyway, and with those the placeholders don’t really add anything to the design.

If you’re relying on hidden labels being read by screen-readers, that leaves people who may have some accessibility needs out in the cold. The exception is single-field forms (like search), where the button next to the field provides enough information for people without screen readers.

I also tried to make keyboard navigation work correctly and with good focus coverage. I actually like how the focus looks more than the lesser design like hovering. I might eventually collapse them into the same design, though I have slight concerns that could be too confusing. Having separate styles for :hover and :focus-visible seems cleaner.


The darkmode toggle button and its JavaScript is slightly modified from Henry Egloff: “How to Code a Simple Dark Mode Toggle”.

After looking at the options, I went with remedy.css for a “reset” (github: Jen Simmons: cssremedy). I still didn’t use most of it. I’m not targeting Internet Explorer. In general I don’t want to target browsers more than a few years old.

I got a lot of help from the usual:

(Probably forgot some others. It’s the Internet, lots of good and helpful stuff around! Many thanks!)

I’m sure there’s other things I forgot. But that’s enough words for now. Hope visitors enjoy the new look.

The Less You Code, the Better

Post about reducing code complexity for the good of the web and its developers.

It’s a well-known fact that the less code one has to maintain independent of other projects, the better the project, all things being equal. In some fields, it’s even considered a liability to use your own code, such as cryptography. But on the web there is a major tendency for every site to have its own front-end, back-end, CSS, and so on.

Some of that goes away with new versions of the HTML specification, such as where new widgets like <input type="number"/> supplant the need for different platforms and libraries to create their own version. But a lot of it doesn’t, as the bigger picture isn’t tackled.

This creates problems, such as the well-documented use of CSS vendor prefixes breaking the mobile web. In this famous case, a ton of mobile sites use WebKit-specific CSS rules, and non-WebKit mobile browsers don’t render those sites as nicely.

There are varied proposals for how to fix that situation. My favorite is for Vendor Prefixes to have a built-in timestamp after which they do not function for any browser. But even the best proposals are working around the larger problem of websites having too much of their own code.

The more code, the more problems. The harder it is to create the web, the harder it is to maintain it, and the harder to evolve it.

The more code, the more duplication of effort by countless developers the world over to do the same things.

According to studies, the average page weighs in at about a Mibibyte (2^23 bits), with an average of nearly 100 objects (mostly graphics), and the growth continues.

It’s clear that this entire paradigm for creating programs and sites will have to change at some point. We’re still in an era where humans and raw data touch way too much, rather than having managed data objects that humans can handle more effectively.

Take, for example, writing a style sheet. Oops, you made a typographical error. Your page doesn’t work right, but is that because of a failure of understanding, a bug in the browser, or some unseen error in: your style sheet, your JavaScript, your markup? Maybe it’s a caching problem.

There are some IDE-type editors, that might give you suggestions as you type a selector, but they don’t know exactly what your intention is, so they invariably defer to your mistakes.

A similar problem occurs when you want to recreate one piece of a page in another project. You are digging out the markup, the JavaScript, and the styles separately. But you have to update them all to fit with your other project, and that requires an omniscience of the namespace and behavior of the other project.

This is ignoring the cargo-cult programming phenomena, which is another by-product of too much code. Too much code in that case means that a novice who might otherwise understand the code will stare at the screen, give up, search for code, copy, paste. It fails, so maybe they paste a bunch of other things. Finally it works, and they move on, leaving a horrible mess just waiting to fail in some new and interesting way.

The question is how to fix it. Syntactic sugar goes a long way. Python tends to be much better than other languages simply because of its focus on readability. But it can still be turned into a garbled mess with enough ignorance and/or effort and/or haste.

So, I say again, the real solution lies in making data into managed objects. Look at the filesystem abstraction. It’s very rare that someone corrupts their filesystem through normal interaction. Open a file. Copy a file. The user isn’t touching the data. They’re touching an interface that touches the data, just like nobody manipulates the voltages running into an arcade game directly. They touch the controls of the game, which handles the electrical signals to the game.

One good example of a tool that works toward this is Inkscape, the vector editor. You can manipulate the SVG (Scalable Vector Graphics) file directly as XML (eXtensible Markup Language), but you can also let a tool like Inkscape manage the data objects for you.

But in the long term we need to be more willing to say that certain behaviors aren’t available from the default interface. To create more lite versions of things that can predominate where the complexity isn’t needed and certainly isn’t adding anything.

My favorite example of that is for online banking. I really do not believe that online banking should happen in a browser or on the web. It makes much more sense to have a dedicated protocol with a dedicated client for that. Something that doesn’t expect to be loading all sorts of complex data in a complex manner.

That isn’t to say a bank shouldn’t have a website. Banks should have websites, but they shouldn’t be the means of account access. They can be used for informational and advertising/brand purposes, sure.