Zumi's Scratchpad

Just let me have custom CSS, dammit...

updated on

Alright. So let's say you're a contemporary web dev using the build tools that you've either learned at a bootcamp or what your employer requires. You're building or adding to a website and you have all the articles, tutorials, StackOverflow and documentation to help you get through these trying times. You stumble upon a thing which you wish was made easier, and then you find technology that does:

Oh man. I need to finish this component fast. The whole thing must be done by Friday. I don't feel like dealing with CSS, it sucks.

So far I have a navbar and a few buttons in it. ...No, I won't use .nav and .nav .button, I'm told that's confusing and bad and slow and specificity is BAD.

Maybe I'll try BEM: .nav__button. ...Hey, I have another navbar here. Hmm, what should I name it? .list-nav__button? Seems too unwieldy. There must be a way for me not to do this manually.

Besides, I don't want to have to open two files just to get at the styles of a single component. I'm also told that loading a gajillion CSS files for each component is a big no-no as well. What to do, what to do...

*clickity clackity*

CSS Modules? ...what's that?

...uh-huh, so... I would write my CSS inside the component, and style names are dynamically generated based on its component? Damn, that's handy. Here's my primary navbar:

../_components/MainNavBar/MainNavBar.js:

import style from "./style.css";
MainNavBar.outerHTML = `
    <div class="${style}">
        <h2 class="${style.title}">Menu</h3>
        <a class="${style.button}">Home</a>
        <a class="${style.button}">About</a>
        <a class="${style.button}">Projects</a>
    </div>
`;

And my secondary:

../_components/LinkNavBar/LinkNavBar.js:

import style from "./style.css";

LinkNavBar.outerHTML = `
    <div class="${style}">
        <h3 class="${style.title}">Links</h3>
        <a class="${style.button}">foo</a>
        <a class="${style.button}">bar</a>
        <a class="${style.button}">baz</a>
    </div>
`;

And if I render it...

<div class="MainNavBar___1lPv5">
    <h2 class="MainNavBar__title___vlA4-z}">Menu</h3>
    <a class="MainNavBar__button___a4afAx}">Home</a>
    <a class="MainNavBar__button___a4afAx}">About</a>
    <a class="MainNavBar__button___a4afAx}">Projects</a>
</div>
<div class="LinkNavBar___aL-gvF">
    <h2 class="LinkNavBar__title___p-5Av}">Menu</h3>
    <a class="LinkNavBar__button___lMvE6}">Home</a>
    <a class="LinkNavBar__button___lMvE6}">About</a>
    <a class="LinkNavBar__button___lMvE6}">Projects</a>
</div>

Damn. Looks like... it just works! This is a godsend. Now I don't have to worry anymore about pesky globals and inane context switching. Not to mention, I don't have to keep track of names in the CSS. AND I get to have shared styles WITHOUT the pains of multiple selectors and cascading?? Ballinnnnnn'!

...Huh? What do you mean the class names are increasing the required bandwidth?

Hmm, I think minifying them would help it. One sec...

<div class="1l">
    <h2 class="vl">Menu</h3>
    <a class="a4">Home</a>
    <a class="a4">About</a>
    <a class="a4">Projects</a>
</div>
<div class="aL">
    <h2 class="p-">Menu</h3>
    <a class="lM">Home</a>
    <a class="lM">About</a>
    <a class="lM">Projects</a>
</div>

There, I think that should do it. Time to move on to the next component!

So that's roughly the compromises or design decisions web devs would take to produce... well, the horror that we see in our inspectors and view-source tabs. It's almost like an attempt at making the web un-open or something, that code should be utterly terrifying to the newcomer who will see literal garbled text and probably dissuade them from trying to learn the ropes (it's probably not a bug).

But if I am a theme developer or a user looking for custom themes for a site, this design is actively against my interests. It makes it harder to be able to theme my favorite websites. Maybe I want to have more contrast, maybe the site is missing a dark mode that I want or need, maybe I wanna put sprinkles all over it. And that is given through theme extensions like Stylus.

Using CSS Modules especially discourages any sort of personalization even in the private setting. Because you never know when these class names are regenerated. Theme developers often can't do what was wanted (say, "can you make Twitter look like this mockup I found cool?"), precisely because of these decisions that developers say "make their life easier".

The user would still be lucky if the developers didn't employ minification, thus exposing the clear class names - like Discord (markup-eYLPri, messageContent-2t3eCI). With class names like that, theme devs can at least use tricks like [class^='markup'].

Not so with Twitter (css-901oao, r-poiln3, css-1dbjc4n) or Medium (ip, b, ch, it). Sometimes these unthemeable hellscapes do offer limited personalization features (even if you have to sign up or pay them), although again, that might not be enough. There is very little chance of a working custom theme for that kind of website or app, and good fuckin' luck trying to.

And it's just another symptom of the fairly sophisticated build tools for building websites and apps, taken in the wrong direction. If I am a web developer, it prioritizes my convenience... which is good, but I don't want to be doing it at the expense of user choice.

In `${new Date().getFullYear()}`, we aren't just building web pages with Notepad like savages, no, we use meticulously-crafted build systems. We have the technology, and with that comes more modern ways of thinking. Like, say, componentizing. Endless dependency chains. Long deployment times.

The three core web languages: HTML, CSS, JS - they are designed this way for a reason. But because JavaScript has been the main focus of development, thus "dogma" and "good practices" in which the other two are designed with in mind are decried as antique, pointless conservatism, and promptly thrown out the window since they are subservient to the omnipotent JavaScript. HTML and CSS have become mere means to an end. Pesky markup...

And the above serves as yet another example of how the future sucks.

Addendum

Whilst websites and the JavaScript-focused infrastructure are opaque and make it look like it's wisdom from above, GNOME devs make it very apparent that user theming is something to fear as an app developer.

I hear them. My XP icon theme, against all sane judgement, decides to symlink the Firefox icon to the Internet Explorer icon. Meanwhile, a few themes don't work right in some places, either making it really ugly or otherwise unreadable and I have to resort to hacks to make it look pleasant again. I do see their argument.

But arguments against theming for some people, in practice, often turn into deprecation of custom theming altogether. If this is aimed at distributions breaking your perfect vision of an app, or the themes not cooperating well with your app leading to confused lemmings on your bug tracker, it still is very well limiting. Limiting, in an environment where everyone wants control. The distros, the users, the developers. Remind yourself of Freedom 0. Frankly, everyone at the GNOME Foundation should, but it's probably not that they'd want to anyway. Adwaita, the only one.

When they designed GTK 3, theming is only meant for app developers. Not users. The fact that full themes exist for GTK 3 is a force of nature. Because they change the specs every so often (because it's for the devs, duh), I ended up staying with GTK 2 apps for a long time, until relatively recently, when the 3 API was provably stable. Playing around with .gtkrc-2.0 was fun, what with all the different theme engines... (pixmap was my favorite, of course) Officially, GTK 3 theming is simply "Fine. Dark theme. That's it."

Anti-user practices. You know the saying "Never attribute to malice what can be explained with incompetence"? For web devs it's the latter. GNOME devs actively profess the former.