-
Notifications
You must be signed in to change notification settings - Fork 386
Description
I was exploring the possibility of leveraging CSS's state machine and element selection to drive most logic, leaving only the bare necessities to scripts.
Each of these is individually useful, but of course I have a greater vision as well.
Edit: correct a term, add a couple more helpers
Shadow tree scoping
Custom properties, and all inheritable properties for that matter, penetrate through inner shadow trees. A rule modifier like @local key: value;
would be immensely useful for setting inherited properties that you don't want to leak into child shadow trees.
This @local
rule on inheritable properties would cause the property to be unset upon descending into a shadow tree (other than either the direct element it's on or that direct element's shadow root).
Component attribute references
There's already attr(name)
to select the DOM element's attributes, and custom properties can be read via var(--name)
. However, there's still a hole: there's no way to get attributes from the shadow root's host. You can forward these by doing --param-foo: attr(foo)
on the custom element itself, but this will find its way into child shadow trees as well, and that could easily become a recipe for bugs.
So, instead, it'd be nice to have a host-attr(name)
to select attributes from the shadow DOM's host node. Doubly nice would be if that could work anywhere a var(--foo)
can - this is safe to do since that can't impact the immediate element it's defined in. In fact, it could even safely work in container queries for this exact reason.
Object custom property values
var(...)
is a powerful concept. However, it could be made even more powerful by allowing it to hold and process objects.
The syntax allows custom properties to hold blocks, sequences, among many other things, so there's room for it. This opens the door to stuff like get(key/n key/n ..., var(--foo))
, where key
reads the value of a block key and n
gets the nth item in a (delimited) sequence.
And down that vein, simple coercion operators would be useful, even independent of that.
string(v, uppercase/lowercase/titlecase?)
: convert whateverv
is to a string, optionally apply a Unicode case mappingnumber(unit, v)
: convert whateverv
is to a numberident(v)
: convert string sequencev
into an identifier, invalid if it isn't a valid identifierreplace(v, pattern, replacement)
: replace pattern in stringv
with string replacement (works like in JS)
Template part value
This is where things really get interesting, where CSS starts to control the expression of the template.
Maybe something like @template { ... }
inside a rule, where each name is a top-level template property name, and each value is the value substituted for that expression. Like, for a hypothetical template.update({foo: "one", bar: "two"})
, it might look like @template { foo: "one"; bar: "two"; }
in CSS.
One of the goals here is to allow graceful fallback through key repetition.
Box tree presence observation
Something like elem.onboxtreeadd
and elem.onboxtreeremove
with a way to observe that state could easily replace the usual "on node added" and "on node removed" most frameworks have.
For performance reasons, this can't bubble. It'd be fired on every node in the tree anyways, so bubbling is just plainly useless. However, for similar reasons, the same event object should be dispatched across the whole tree.
This would also need deferred to the next tick after animation frame callbacks run for performance reasons as well.
This could also be augmented in CSS with a state-reset: none | on-box-tree-remove
property that does all this passively. Scripts could check this via getComputedStyle(elem).stateReset
to know in onboxtreeremove
whether they need to reset or not. And the event could be augmented with a .stateReset
property as well.
Declarative document title manipulation
A document-title
CSS property to set the title when an element is visible (last setter wins) would be really helpful in cutting out certain JS.
When combined with the string
function, I could make it all declarative.
I deliberately don't include anything else here. dir
makes more sense as an HTML attribute for one.