HNHacker News
TopNewBestAskShowJobs

tenphi

37 karma · joined June 26, 2020

Frontend Developer & Principal UX/UI Engineer at Cube Dev. Building AI-ready, scalable design systems and UI components. Creator of Tasty and Glaze. Based in Amsterdam.
submissionscomments
tenphi··on I spent years trying to make CSS states predictable
You are right. I doubt it can cause any issue by itself, but with complex states it might end up being `.class:where(.root .class:is([state1], [state2])`. Still, it should be fast enough. Anyway, I prefer a fully deterministic approach that eliminates any potential issue. `revert-layer` is just `revert` for layers. It's not a lack of value.

Tasty doesn't fight cascase; it fights ambiguity in source order and specificity. Cascade might still be useful for many things.

tenphi··on I spent years trying to make CSS states predictable
I was, but now it's written in the code.
tenphi··on I spent years trying to make CSS states predictable
For example, I want to set (override the inherited one) a custom property by default, but not when some condition is met. Yes, it might be solved with `inherit`, but in other cases `initial` should be used. I prefer not to define anything unless necessary, so the default (from the cascade) can still be used.

You are probably right about `:where`, but using it with complex selectors might noticeably affect the performance, as it does with `:has`. Didn't run any test for `:where` specifically, though. Also, we apply lots of styles to the same elements, most of which are overridden.

Another issue is using a different set of longhand/shorthand properties for different states that won't be correctly overridden in this approach.

So it might work pretty well in most of the cases, especially simple ones. But it's definitely not better than mutually exclusive selectors.

tenphi··on I spent years trying to make CSS states predictable
Actually, most importantly, AI can read and edit styles. CSS is hard enough on its own; adding overrides makes it so complex that it becomes unmanageable at scale.
tenphi··on I spent years trying to make CSS states predictable
Exactly. And we won't find out if we don't try. Also, specifically, this approach is more JSON-based (compared to other CSS-in-JS). So you can easily put styles into a separate file if you want, JS or JSON. But I prefer defining styled components in a separate file, as `styled-components` recommends.
tenphi··on I spent years trying to make CSS states predictable
It took me years to picture "how things fit together as they get more complex and different styles logically overlap". I hope we didn't lose you :)

Considering the `:where` approach, I would say it might work most of the time, but it doesn't cover cases where you don't need to set a value, or when your condition requires a more complex selector (e.g., a parent/root context). It was very important for me to support all cases, so I don't feel limited by the tool.

tenphi··on I spent years trying to make CSS states predictable
If you lack a solid component system, you likely do not require complex tools to manage CSS.
tenphi··on I spent years trying to make CSS states predictable
Great, if it suits your needs. In a big enterprise product, it would be a waste to have so many CSS that are not actually used. Also, maintaining this seems like a nightmare to me.
tenphi··on I spent years trying to make CSS states predictable
Because usually each style requires its own set of states, and raw strings are hard to type (in Typescript). But there are even more reasons.

`styled-components` is just an advanced CSS injector. We used it as an injector in the early version of Tasty.

tenphi··on I spent years trying to make CSS states predictable
Sorry to hear it. I didn't. And now our designers can tweak the code directly to adjust component styling. They can finally read and edit styles.
tenphi··on I spent years trying to make CSS states predictable
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.