w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.42k stars 648 forks source link

[cssom] Provide access to counter values #5879

Open taralx opened 3 years ago

taralx commented 3 years ago

Currently there is no access to counter values, even with getComputedStyle. I'm trying to implement a system that allows cross-reference to specific elements in a list, and in order to do that I'm having to count the elements myself. Since the browser has already computed the counter value (and AFAIK counters are not reflow-sensitive, unlike page numbers), it seems like it would be useful to expose them directly.

faceless2 commented 3 years ago

The target-counter() function does exactly this in CSS, not JS. But it's currently not implemented in any browsers. https://www.w3.org/TR/css-gcpm-3/#target-counter

Loirooriol commented 3 years ago

Hacky, suboptimal performance and unreliable for big counter values, but I guess you could create a JS function which does this:

  1. Creates a ::before pseudo-element on the desired element, with content: counter(the-counter, the-style)
  2. Uses a @counter-style to define the-style so that it produces:
    • For n < 0, a string with the character 0 repeated -2*n - 1 times.
    • For n = 0, an empty string
    • For n > 0, a string with the character 0 repeated 2*n times.
  3. Uses a monospaced font to display that, and prevents line breaks, etc.
  4. Retrieves the width of the string in pixels with getComputedStyle, and divides it by the amount of pixels in 1ch. That's the number of characters m.
  5. Maps m to the desired original n: n = m % 2 ? -(m+1)/2 : m/2
  6. Restores the original state

Example based on the above (The formulas are a bit different because it's easier like this) ```html
```

The working range is not great, because of

User agents must support representations at least 60 Unicode codepoints long, but they may choose to instead use the fallback style for representations that would be longer than 60 codepoints.

taralx commented 3 years ago

AFAIK@counter-style is still only implemented in Firefox, but once support is broader that might work.

Loirooriol commented 3 years ago

Chromium has an experimental implementation, you can test it with --enable-blink-features=CSSAtRuleCounterStyle.