My final conclusion about CSS is - program the damn machine.
What I mean by this is STOP every single type of abstraction/library/programming layer for CSS - nothing gets it right, everything causes a problem.
The ONLY way to deal with CSS is program it directly in the way the docs say, never anything else.
There's nothing wrong with using Bootstrap or whatever, and I definitely use JavaScript to program CSS. What I am saying is - no abstractions - no "better way" - no trying to turn CSS into something it isn't via whatever your new abstraction is that can be added to the N other abstractions that other people have made over the years.
Yes. It’s been twenty years of watching people pick an fussy framework because they don’t want to learn the tool, then struggle to get the results they want because the framework is flawed but they didn’t learn enough to understand how and when to fight it.
And with grid, variables, animation, container queries, modern CSS is amazing. You just need to treat it with a little respect.
CSS suffers from one of its original design tenants in that it's very easy to throw some shit at the wall and kind of get it working without fully understanding it. This is especially true for people who have dabbled in it from time to time in their career when absolutely needed. It's rare to see someone sit down and learn it from first principles. It doesn't take long and knowing the basic theory goes a long ways!
I agree. I taught myself CSS1 by reading the spec (it was limited, small and simple). CSS2 was a lot bigger and way more complex but Eric Meyer's Salmon book helped a lot.
One problem (20yrs ago at least) was that for a long time the specs weren't supported very well by common browsers. So everyone just prodded at hacks using trial and error instead of learning it. That approach never really went away even after support improved.
> CSS suffers from one of its original design tenants in that it's very easy to throw some shit at the wall and kind of get it working without fully understanding it
And dev tools made this feedback loop much faster.
For me nothing beats plain old classes and an external css file. For PWAs I just use lit css within the element, again with classes and plain css. If things cause problems, just figure out why and fix the classes.
I've loved tailwind for the colocation of the component HTML and its corresponding styling (never gave up on traditional CSS though!), but with scoped styles I might start leaning back to traditional CSS.
I also spent years on the same problem. I was creating a programming language for designers, which was supposed to abstract away the complexity of CSS. Long story short, I gave up.
Happy to take questions! I built this because I kept hitting the same wall: CSS state resolution is opaque when states overlap, and extending components means mentally re-deriving the whole selector matrix every time.
Some topics I'm curious what people think about:
- What’s the one thing this doesn’t cover that you’d expect it to?
- Does the syntax feel natural to you, or did you find yourself confused by anything?
- I'm looking for edge cases: what kind of complex selector scenario would trip this compiler up or be impossible to express with this model?
AMA—happy to answer any questions about the tool, the implementation, or the design choices.
This sounds interesting, but I’d need to think about it more so I could picture how things fit together as they get more complex and different styles logically overlap. This looks to head in the utility direction possibly too far for that to work nicely. But it may well work better than I’m initially imagining.
Unfortunately I can’t give it more attention now, because I should have gone to sleep a couple of hours ago…
—⁂—
Another approach entirely is to embrace last-declaration-wins, by :where()ing everything:
I’d be interested to know which approach performs better once you have altogether too many elements and altogether too complex selectors. I suspect the :where() would win, but that the difference would be impossible to detect in any sort of realistic load.
My final conclusion about CSS is - program the damn machine.
What I mean by this is STOP every single type of abstraction/library/programming layer for CSS - nothing gets it right, everything causes a problem.
The ONLY way to deal with CSS is program it directly in the way the docs say, never anything else.
There's nothing wrong with using Bootstrap or whatever, and I definitely use JavaScript to program CSS. What I am saying is - no abstractions - no "better way" - no trying to turn CSS into something it isn't via whatever your new abstraction is that can be added to the N other abstractions that other people have made over the years.
Program the damn machine.
Yes. It’s been twenty years of watching people pick an fussy framework because they don’t want to learn the tool, then struggle to get the results they want because the framework is flawed but they didn’t learn enough to understand how and when to fight it.
And with grid, variables, animation, container queries, modern CSS is amazing. You just need to treat it with a little respect.
Lots of developers feel they need a library to program anything - got forbid that you should program that actual machine.
CSS suffers from one of its original design tenants in that it's very easy to throw some shit at the wall and kind of get it working without fully understanding it. This is especially true for people who have dabbled in it from time to time in their career when absolutely needed. It's rare to see someone sit down and learn it from first principles. It doesn't take long and knowing the basic theory goes a long ways!
I agree. I taught myself CSS1 by reading the spec (it was limited, small and simple). CSS2 was a lot bigger and way more complex but Eric Meyer's Salmon book helped a lot.
One problem (20yrs ago at least) was that for a long time the specs weren't supported very well by common browsers. So everyone just prodded at hacks using trial and error instead of learning it. That approach never really went away even after support improved.
> CSS suffers from one of its original design tenants in that it's very easy to throw some shit at the wall and kind of get it working without fully understanding it
And dev tools made this feedback loop much faster.
For me nothing beats plain old classes and an external css file. For PWAs I just use lit css within the element, again with classes and plain css. If things cause problems, just figure out why and fix the classes.
I've loved tailwind for the colocation of the component HTML and its corresponding styling (never gave up on traditional CSS though!), but with scoped styles I might start leaning back to traditional CSS.
This is exactly how I feel. Learn how to write CSS! Like you would do with any language!
I also spent years on the same problem. I was creating a programming language for designers, which was supposed to abstract away the complexity of CSS. Long story short, I gave up.
I’ve made some gnarly custom forms over the years but never quite run into the problem you’re describing.
These days if starting a greenfield web app, each page has its own style/css sent in the head tag.
Because it’s usually just base layout + page specific styles/overrides then it barely adds any overhead in the scheme of things(couple of extra KB).
Maybe the base layout could be moved into a static file to be cached but whatever, it’s already ridiculously quick to render plain html/css.
Happy to take questions! I built this because I kept hitting the same wall: CSS state resolution is opaque when states overlap, and extending components means mentally re-deriving the whole selector matrix every time.
Some topics I'm curious what people think about:
- What’s the one thing this doesn’t cover that you’d expect it to?
- Does the syntax feel natural to you, or did you find yourself confused by anything?
- I'm looking for edge cases: what kind of complex selector scenario would trip this compiler up or be impossible to express with this model?
AMA—happy to answer any questions about the tool, the implementation, or the design choices.
This sounds interesting, but I’d need to think about it more so I could picture how things fit together as they get more complex and different styles logically overlap. This looks to head in the utility direction possibly too far for that to work nicely. But it may well work better than I’m initially imagining.
Unfortunately I can’t give it more attention now, because I should have gone to sleep a couple of hours ago…
—⁂—
Another approach entirely is to embrace last-declaration-wins, by :where()ing everything:
I’d be interested to know which approach performs better once you have altogether too many elements and altogether too complex selectors. I suspect the :where() would win, but that the difference would be impossible to detect in any sort of realistic load.Personally I just increase the specificity as needed.
.thing
.thing-container .thing
html body .thing-container .thing.thing.thing.thing
Probably because you aren't using Sin