Re: [csswg-drafts] [css-content] target-counter(): Need to have number format details in source markup is a problem (#1107)

Just found this one. This is a genuinely good idea. My only criticism is I don't think you sold it as well as you could have!

To paraphrase: the problem is that the counter _value_ and _formatted value_ are not linked. This isn't so much of a problem for regular counters, but it becomes a larger problem for `target-counter`, because every time you refer to a counter in another element, you also have to refer to its style. A subsequent change to the style then has to be made it in multiple locations.

```html
<style>
a.appendix::before{
    content: "Appendix " target-counter(attr(href uri), appendix, decimal);
}
section.appendix {
    counter-increment: appendix;
}
section.appendix h1::before {
    content: counter(appendix, upper-alpha) ": ";
}
</style>
<p>
See <a class="appendix" href="#changelog"></a>
</p>
<section id="changelog" class="appendix">
 <h1>Change log</h1>
</section>
```

> See Appendix 1
> 
> ### A: Change log
> 

Whoops! I forget that I'd changed appendices to be numbered with upper-alpha. In a heavily cross-referenced document this sort of thing could easily be missed, as you have to include the style of the named counter _every single time_.

The more you think about this, the less it seems it a good idea.

@drmacro raised the original issue on `page` counters, but it will apply to _any_ `target-counter`. I suspect the only reason this hasn't come up before is that this function isn't yet supported in _any_ browser.


I think there is a very simple, completely backwards compatible solution.

### Proposal: counter-format property

| Key | Value |
| ------------- | ------------- |
| Name: | counter-format |
| Value | [ \<counter-name\> \<counter-style\> ]+ \| auto |
| Inheritable | no (see notes) |

Currently, if the format of a `counter` or `target-counter` is unspecified it defaults to "decimal". Change this to default to the value as specified in a new `counter-format` property, and have that default to "decimal". This approach should be completely backwards compatible, and while the syntax would benefit from "additive CSS (https://github.com/w3c/csswg-drafts/issues/1594)", it's consistent with `counter-increment`, `counter-reset` and `counter-set`.

Here's the above example, fixed:

```html
<style>
a.appendix::before{
    content: "Appendix " target-counter(attr(href uri), appendix);
}
section.appendix {
    counter-increment: appendix;
    counter-format: appendix upper-alpha;
}
section.appendix h1::before {
    content: counter(appendix) ": ";
}
</style>
<p>
See <a class="appendix" href="#changelog"></a>
</p>
<section id="changelog" class="appendix">
 <h1>Change log</h1>
</section>
```
> See Appendix A
> 
> ### A: Change log
> 

This is conceptually very similar to `list-style-type`, which is an inheritable property. But I think `counter-format` needs to be associated with the counter itself - i.e. it needs to be "inherited" via the counter scoping rules defined in https://drafts.csswg.org/css-lists-3/#creating-counters. 

The reason for this is the use case raised by @drmacro - page counters.

```html
<style>
@page frontmatter {
    counter-format: page lower-roman;
    @top {
        content: counter(page);
    }
}
a::after {
    content: "(page " target-counter(attr(href uri), "page") ")";
}
</style>
<section style="page: frontmatter">
 <section id="prefix">...</section>
</section>
<section style="page:normal">
   ...
   See the <a href="#prefix">prefix</a>
</section>
```
> See the prefix (page xviii)

The "page" counter is reset in :root and incremented in the @page rule (see https://drafts.csswg.org/css-page-3/#page-based-counters and my notes at https://github.com/w3c/csswg-drafts/issues/3520), so regular CSS inheritance wouldn't work in this case. 

In short, for implementers this change means associating a default format with a scoped counter, as well as a value. Specifying `counter-format` doesn't create a new scope, but it sets the format on the counter in the current scope; setting the default format in exactly the same way that `counter-set` sets the value.

-- 
GitHub Notification of comment by faceless2
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/1107#issuecomment-568170310 using your GitHub account

Received on Saturday, 21 December 2019 10:28:36 UTC