The idea is to combine the best bit of global styling (reuse, small payload) and local styling (total isolation, first-class React syntax)
This is combined with the concept of traits: you can think of them as permitted property/value pairs. Instead of every component being able to have every CSS property available to it, you can reduce your permitted set to X font families, Y font-size + line-height pairs, Z foreground/background colour pairs, W padding amounts. This is based off my work using amcss on real projects — traits were the single key feature that kept me using AM.
The one-sentence explanation: A site defines a set of permitted visual features, all components are simply a combination of those features
@define-trait X
establishes X
as a type of trait. These include the above mentioned concepts: typography, colouring, spacing, layout, etc.
Any CSS inside a @define-trait :default
block are shared by all users of that class. If a trait was button
, this would be all the default styling for a button.
Any sub-rule under a trait indicates a trait variant. These get turned into classes, and components mix them in. E.g. the variant vertical
of trait flex
gets turned into the class .t-trait--vertical
.
:local
exports local
to React, which is a set of classnames that include an auto-generated class-name for any one-off CSS if needed, plus any traits it includes. Using that in React is dead simple.
Inside a :local
expression, a &
block will allow arbitrary CSS to be written. That will be extracted into a one-off class.
Using traits inside a :local
block should be the main way you include styles. The syntax is like pure css: trait: variant-a variant-b;
.
My opinion - it seems a little arbitrary to me to define traits as a higher level construct which can only apply to these scoped style selectors. If one wants to come up with a syntax that could possibly be included in CSS, it would be nice to ensure it generalises as fully as possible. Locally scoping CSS seems like a completely different specification and concept, but which is also incredibly important.
For example, one could define traits to apply to arbitrary selectors:
Then the specificity preference can be defined - like having inline styles of the same specificity taking preference over the trait style.
The output of the above would then become:
The above can then be compacted into (so that the previous output is never seen):
I know it removes the simplicity of having the trait entirely represented by a class, but then traits can be used on arbitrary elements and one could imagine them a core part of CSS some day.
Do tell me if I'm making no sense though.
In terms of exploring the scoped CSS ideas, loving where this syntax is going, again would be good to consider from a spec-viability perspective as much as possible, not that it is a must, but that it should at least be a possibility and not an impossibility if we miss something obvious that would be a blocker someday.