Every year I make an end of year project where I try some new technology. This year I made my project with Svelte. It's a list of the best albums, films, series etc. according to me.
I followed the link to the css framework you used/developed, Ygdir, and I am not sure I understand it. Is the website a work in progress? Feel like it needs to explain with more details and examples what you mean by "convention-first". I agree what you said about utility first css but I'm not sure what makes Ygdir better
This is something very new (a few weeks) and still a work in progress, it's nowhere near complete. It's going to be a “way of doing things” instead of a full-on framework, but at the same time, we could use more examples on how to exactly do what it prescribes. A tutorial, a sample project following the conventions etc.
It will be interesting to read the comments on this early version but it's not really “released” yet.
Wolfr_- Just read over ygdir and wondering: We've had such phenomenal success with https://styled-system.com/ across our team that I'm wondering if your adversity to utility-first CSS might be due to misuse in some way? Utility first is largely to build primitive abstractions that expose narrow constrains for developers building UI. It's the opposite of complexity due to the fact that it reduces options. _But_ if the utils are incorrectly spread all across your codebase and not constrained to primitives then indeed it could be a mess.
I'm not Wolfr_, and I haven't used that React-based library you link, but I have seen tailwindcss.com -- which, as far as I've heard, is one of the flagship "utility-first" CSS libraries -- used in medium-to-large scale projects.
The problems I've seen with Tailwind in these projects are:
- Elements end up with messy, non-semantic class name strings like "m-4 mt-0 p-3 rounded bg-blue". This makes it much harder for non-technical teams to use out-of-the-box SaaS solutions for things like interaction tracking and A/B testing. (These apps often use element class names under the hood, so if you use Tailwind and change a CTA from rounded to very-rounded, the marketing guy will discover two weeks later that all his click-through metrics are wrong.)
- References to the utility classes wind up scattered in thousands of unrelated places in the codebase, making refactoring and changes to the CSS impossible. Like, if you ever wanted to remove the p-3 class (or change how much padding it represented), it would be almost impossible: you'd have to individually find and test/change all 9000 use sites, a task which is made even more difficult when developers write things like class={`p-${first ? 4 : 3}`}. At least one website I know is stuck on Tailwind 0.x pretty much indefinitely for this reason.
- Whenever you add a new color or padding amount or anything, you pay the full cost of generating all the variations (p-7, pt-7, bigscreen:pt-7, etc) up front in a CSS file that needs to be loaded before anything on the page can be rendered. (Sure, Tailwind might not generate 50K of variants when you add a padding value out-of-the-box, but once you've set those options it's impossible to un-set them because of the above point.)
This eventually leads to a codebase where no one wants to add, remove, or change CSS classes for fear of breaking something unrelated or destroying performance. In other words, it makes your CSS impossible to maintain.
> - Elements end up with messy, non-semantic class name strings like "m-4 mt-0 p-3 rounded bg-blue". This makes it much harder for non-technical teams to use out-of-the-box SaaS solutions for things like interaction tracking and A/B testing. (These apps often use element class names under the hood, so if you use Tailwind and change a CTA from rounded to very-rounded, the marketing guy will discover two weeks later that all his click-through metrics are wrong.)
IMO the problem here is tools trying to use CSS for something it’s not designed for. They advertise themselves as not requiring technical knowledge to use, but they’re selling a lie. Unless the marketing guy understands the structure of the site and the CSS there’s no way for him to be sure he’s tracking the thing he thinks he’s tracking - unless you’re instrumenting the CSS to help him out, and are committed to not doing anything that would break one of his selectors (or change its meaning, or reuse it for something else - and are you sure you know all the selectors he’s using, and that the automatic selectors the tool is creating are actually doing what he intends?).
Data attributes are probably the solution here, then CSS can be reserved for its intended use: controlling styles. But then the tooling needs a way to target those attributes automatically, otherwise you’ve “broken” the “no technical knowledge required” sell of the software they already licensed (without asking you for input...)
Pretty much this, utility-first leads to unmaintainable codebases, I try to explain why I want to change this with a combination of conventions on this page: https://ygdir.dev/rationale
I prefer non-semantic class names (“messy” is up for debate). I find it much easier to reason about the markup when I can see exactly how each element is styled right there _with_ the element. Not only does semantic naming add a layer of indirection, I have have never found it to be as “clean” as you are insinuating. I can’t count the number of times I’ve found myself having to invent names for elements, containers, etc. just so I can apply a style when it would have been much easier to just “style=whatever”. All the naming conventions in the world don’t solve this: is it list-item__header or list__item-header? Who cares?
I don’t find your arguments about maintenance very compelling either. If you want an element with “p-3” to have more padding, just... change it to “p-4”. That’s the whole point! You don’t have to wrangle with the _semantics_ of the element. You style it exactly as you want. It’s akin to using the `style` attribute but terser. The only vector of change for the definition of a class name becomes the CSS spec itself. “p-3” === “padding: 3px” and cant _ever_ mean anything else (or it would have a different name).
I see your point about SaaS tools, but why can’t you just add a class name for that purpose alone? Seems simple enough to me.
I’ve tried just about everything when it comes to organizing CSS/styles and I have come to the conclusion that semantic naming is more trouble than its worth.
Thank you for explaining. I think the difference between tailwind and styled-system is that the CSS-in-JS approach (while still being able to write normal CSS via styled-components) eliminates most of these issues up front in favor of a component-based approach that contains said complexity very efficiently.
One request: I read your gaming section eagerly and all the games you mentioned look super cool, but would you mind adding some links / details about each of them? I’m still not sure exactly which racing sim you’re talking about and the other screen shots look super cool but I had to google each game to figure out what the deal was. Not a huge deal but a small suggestion.