Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sibling-index and sibling-count as custom properties #506

Open
myfonj opened this issue Jul 7, 2024 · 4 comments
Open

Add sibling-index and sibling-count as custom properties #506

myfonj opened this issue Jul 7, 2024 · 4 comments

Comments

@myfonj
Copy link

myfonj commented Jul 7, 2024

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

*:nth-child(1) { --sibling-index: 0; }
*:nth-child(2) { --sibling-index: 1; }
/* ... */
*:nth-child(<N>) { --sibling-index: <N-1>; }

(*), and similarly

--sibling-count

*:has(> *:last-child:nth-child(<N>)) > * { --sibling-count: <N>; }

or for super backwards ":has()-less" compatibility (or perhaps better performance(?)) the way Lea showcased in the distant past:

*:first-child:nth-last-child(<N>),
*:first-child:nth-last-child(<N>) ~ * { --sibling-count: <N>; }

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. )

@argyleink
Copy link
Owner

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.

@kizu
Copy link

kizu commented Oct 23, 2024

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.

@argyleink
Copy link
Owner

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?

@kizu
Copy link

kizu commented Oct 23, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants