Open myfonj opened 4 months ago
I see what you mean here! Nice little microjs file to aid in adopting the --sibling-index
idea 🙂
I could def see this as a classname/attribute and a js import which has a mutation observer too?
I am consciously proposing zero-based indexing here as god intended
lol, I mean, if it's your function then you get to make the choices! lots of good ideas come from building tools that match your preferences.
I mentioned this issue in my latest article, so wanted to link back: https://kizu.dev/tree-counting-and-random/
From all my experiments there, I think it could be feasible to have reusable --sibling-index
and --sibling-count
up to ~100 elements. The --sibling-index
requires only 19 rules to cover 99 elements, but the --sibling-count
will need more if it will be using the ~
method. It is possible to make it more compact with :has()
, but it is also much more performance-intensive — my article initially frozen Safari due to it.
The ~
method, though, seems pretty well optimized in all browsers, and has an excellent browser support. So if you don't need to write it from scratch and if it covers ~100 elements, that would be enough for most cases.
given your work here @kizu was put into a prop pack (minor changes made to generalize it) here in Open Props:
.provide-sibling-indexes {
& > * {
--si2: 0;
--si1: 0;
--sibling-index: calc(10 * var(--si2) + var(--si1));
}
& > *:nth-child(10n+1) { --si1: 1 }
& > *:nth-child(10n+2) { --si1: 2 }
& > *:nth-child(10n+3) { --si1: 3 }
& > *:nth-child(10n+4) { --si1: 4 }
& > *:nth-child(10n+5) { --si1: 5 }
& > *:nth-child(10n+6) { --si1: 6 }
& > *:nth-child(10n+7) { --si1: 7 }
& > *:nth-child(10n+8) { --si1: 8 }
& > *:nth-child(10n+9) { --si1: 9 }
& > *:nth-child(n+10):nth-child(-n+19) { --si2: 1 }
& > *:nth-child(n+20):nth-child(-n+29) { --si2: 2 }
& > *:nth-child(n+30):nth-child(-n+39) { --si2: 3 }
& > *:nth-child(n+40):nth-child(-n+49) { --si2: 4 }
& > *:nth-child(n+50):nth-child(-n+59) { --si2: 5 }
& > *:nth-child(n+60):nth-child(-n+69) { --si2: 6 }
& > *:nth-child(n+70):nth-child(-n+79) { --si2: 7 }
& > *:nth-child(n+80):nth-child(-n+89) { --si2: 8 }
& > *:nth-child(n+90):nth-child(-n+99) { --si2: 9 }
}
which then authors could import like:
@import "open-props/sibling-indexes";
and apply to an element like:
<ul class="provide-sibling-indexes">
<li>…</li>
…
</ul>
then use like:
ul {
li {
transition-delay: calc(var(--sibling-index) * 50ms);
}
}
that the kind of flow you're imagining too?
Yep! I did not generalize because I was already feeling the performance hits, but these were mostly from those selectors with :has()
, in this case it should not matter if my guesses about why there are performance hits are correct.
A bit silly feature idea: introduce optional import(s) (or JS generator in the "bookmarklet" include) emulating upcoming sibling-count() and sibling-index() proposal (by some @argyleink dude) in a brute-force ad-nauseam low-key manner:
--sibling-index
(*), and similarly
--sibling-count
or for super backwards ":has()-less" compatibility (or perhaps better performance(?)) the way Lea showcased in the distant past:
Open question remains what initial threshold to pick (1-99?) and whether pre-generate further chunks (100-999, 1000-9999, ...?) in separate includes.
Most probably ideal alternative to includes in client-side environments with scripting available could be a dynamic JS polyfill with lazy mutation observer spitting out additional chunks into in-page
<style>
when maximum sibling count increases somewhere in the tree..(*: I am consciously proposing zero-based indexing here as god intended, even though I clearly know it has zero-chance to be adopted this way; I just had to try 🙃. For
1
-based property I'd propose--sibling-order
. )