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

[css-values] Proposal: descendant-count() function #11069

Open
kizu opened this issue Oct 22, 2024 · 3 comments
Open

[css-values] Proposal: descendant-count() function #11069

kizu opened this issue Oct 22, 2024 · 3 comments

Comments

@kizu
Copy link
Member

kizu commented Oct 22, 2024

This is a more powerful/versatile version of my previous children-count() proposal (#11068).

The Proposal

Unlike children-count(), this one counts all descendant elements.

If we were to approximate it with JS, it could be something like el.querySelectorAll('*').length.

I imagine this function being the most useful with the optional selector (so the #9572 must be resolved first), as it allows narrowing down what exactly we want to count.

Example usage:

An accumulated padding based on the count of nested lists:

.table-of-contents {
	padding-inline-start: calc(
		1ch
		*
		descendant-count(ul:first-of-type)
	)
}

Other use cases

  • Same as children-count(), but when there are extra wrappers between the element on which we need to get the value, and the items: it could happen easily with display: contents or subgrids.
  • A way to check if we have some content in a way similar to :has(), but where we get the count of elements as the result.

Why not just descendant-count()?

Can we have just it, and skip the children-count() I think that we need both:

  • Most use cases could just use children-count(), while descendant-count() could be used for more complicated use cases.
  • descendant-count() is harder to spell compared to children-count()
  • children-count() will be likely more performant (fewer DOM changes will cause a recalc), so it will be better than descentant-count(> *), and an alternative of having > * as the default value for the descentant-count() would not be too logical.
  • children-count() sounds like a much easier thing to implement. While I would prefer both to be implemented alongside sibling-index() and sibling-count(), if the complexity of descendant-count() will be problematic, I don't want it to be a roadblock.

Could this be a selector instead?

I think we need both, as in one case we conditionally apply some styles, and in another we use the count itself for some purpose. I will try to fill a separate proposal for such a selector in the future.

@kizu kizu changed the title [css-values] Proposal: descendant-count() function [css-values] Proposal: descendant-count() function Oct 22, 2024
@nt1m
Copy link
Member

nt1m commented Oct 22, 2024

How does this work with shadow DOM / slotted content?

@kizu
Copy link
Member Author

kizu commented Oct 23, 2024

How does this work with shadow DOM / slotted content?

That's a good question, but, I guess, this is probably something to discuss in #9572, as I can see it as a more general issue? It would need to work consistently with it, but I can see how this can be a complex issue, as I don't think we handled selectors inside values before, so it is tricky to define how they should work across boundaries.

Like, my first intuition is to make it work the same other selectors work: if it is defined in the light DOM, then it should only select light DOM stuff, and vice versa. But that means that the selector itself will need to somehow be coupled with its origin, as the value itself could be inherited across the boundaries.

(I'll copy a part of this comment to 9572)

@tabatkins
Copy link
Member

I don't see how your example uses this feature. If you're trying to accumulate a padding value as you nest, and you want to do it in one shot rather than actually accumulating, you need to count the ancestors that are uls, not how many descendants that are. As written, the top-level toc would have a huge padding, and then each nested toc section would have a gradually smaller padding.

I'd want to see some more realistic examples of using this before we considered it; it would definitely be more expensive than sibling-count() (which is already relatively expensive).

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

No branches or pull requests

4 participants