CSS counter-reset doesn't reset the counter correctly
Categories
(Core :: Layout: Generated Content, Lists, and Counters, defect)
Tracking
()
People
(Reporter: ocavue, Assigned: emilio)
Details
Attachments
(6 files)
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Steps to reproduce:
Open https://codesandbox.io/s/firefox-counter-css-bug-mpt3fh or download the index.html file in this bug report. This webpage render a custom list item counter using counter-reset
and counter-increment
. The custom counter is between [
and ]
.
Actual results:
The result in Firefox is
[1] 1. A1
[1] 1. B1
[2] 2. B2
[3] 3. B3
[4] 4. B4
[5] 2. A2
[6] 3. A3
Notice that the counters before A2
and A3
are incorrect.
Expected results:
The result in Chrome and Safari is as following:
[1] 1. A1
[1] 1. B1
[2] 2. B2
[3] 3. B3
[4] 4. B4
[2] 2. A2
[3] 3. A3
![]() |
||
Updated•1 year ago
|
Assignee | ||
Comment 1•1 year ago
|
||
This is a bug in Chrome and Safari. We still have the old behavior behind the layout.css.counter-ancestor-scope.enabled=false
pref, but the spec says to do what we do, see https://drafts.csswg.org/css-lists/#creating-counters, bug 1548753, https://wpt.fyi/results/css/css-lists, etc.
(In reply to Emilio Cobos Álvarez (:emilio) from comment #1)
This is a bug in Chrome and Safari. We still have the old behavior behind the
layout.css.counter-ancestor-scope.enabled=false
pref, but the spec says to do what we do, see https://drafts.csswg.org/css-lists/#creating-counters, bug 1548753, https://wpt.fyi/results/css/css-lists, etc.
If I add another A0
list item right above A1
, I get the same behavior from Firefox, Safari and Chrome, show as below:
[1] 1. A0
[2] 2. A1
[1] 1. B1
[2] 2. B2
[3] 3. B3
[4] 4. B4
[3] 3. A2
[4] 4. A3
You can also see the screenshot between these two results here: https://github-production-user-asset-6210df.s3.amazonaws.com/24715727/251175475-12abe1b2-c845-44be-9fa0-4cbba0a55a52.png
Are both these two results are expected? I feel that there is a conflict in the behavior of the two.
Assignee | ||
Comment 3•1 year ago
|
||
In the first one there's A1
s scope, which is the ancestor scope, while in the second one there's no ancestor scope because A1
matches li + li { counter-reset: none }
. So behavior changes, but only because your CSS specifies it.
If you want to match <ol>
s behavior but with a custom counter, the way to go about it is described in https://drafts.csswg.org/css-lists/#ua-stylesheet. So, something like:
li { counter-increment: my-list-counter; }
ol { counter-reset: list-item my-list-counter; }
That works, with valid markup, in all browsers. With invalid markup it only matches the HTML behavior on Firefox, that's the bug linked above.
Thank you for your explanation! I kindly have another question, and I would greatly appreciate your assistance in providing an suggestion. In fact I don't have two levels of DOM structure (i.e. `li` and `ol`), I only have one level of `div` elements. Here is code ```HTML
Thank you for your explanation! I kindly have another question, and I would greatly appreciate your assistance in providing an suggestion. In fact I don't have two levels of DOM structure (i.e. `li` and `ol`), I only have one level of `div` elements. Here is code
Thank you for your explanation! I have another question and would appreciate your suggestion. I have a single level of `div` elements instead of two levels of DOM structure (`li` and `ol`), so I cannot use the custom counter from https://drafts.csswg.org/css-lists/#ua-stylesheet. Is there anyway to achieve the same behavior as `<ol>` in this HTML structure? ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div.list-item { counter-set: my-list-counter; counter-reset: my-list-counter; counter-increment: my-list-counter; position: relative; margin-left: 100px; } div.list-item+div.list-item { counter-reset: none; counter-set: none } div.list-item:before { position: absolute; content: '[' counter(my-list-counter, decimal) ']'; color: red; left: -40px } </style> </head> <body> <div class="list-item"> <p>A1</p> <div class="list-item"> <p>B1</p> </div> <div class="list-item"> <p>B2</p> </div> <div class="list-item"> <p>B3</p> </div> <div class="list-item"> <p>B4</p> </div> </div> <div class="list-item"> <p>A2</p> </div> <div class="list-item"> <p>A3</p> </div> </body> </html> ```
Thank you for your explanation!
I have another inquiry, and I would be most grateful for your valuable suggestion.
We have a single level of div
elements instead of two levels of DOM structure (li
and ol
), so I cannot use the custom counter from https://drafts.csswg.org/css-lists/#ua-stylesheet directly. Is there anyway to achieve the same behavior as <ol>
in this HTML structure?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div.list-item {
counter-set: my-list-counter;
counter-reset: my-list-counter;
counter-increment: my-list-counter;
position: relative;
margin-left: 100px;
}
div.list-item+div.list-item {
counter-reset: none;
counter-set: none
}
div.list-item:before {
position: absolute;
content: '[' counter(my-list-counter, decimal) ']';
color: red;
left: -40px
}
</style>
</head>
<body>
<div class="list-item">
<p>A1</p>
<div class="list-item">
<p>B1</p>
</div>
<div class="list-item">
<p>B2</p>
</div>
<div class="list-item">
<p>B3</p>
</div>
<div class="list-item">
<p>B4</p>
</div>
</div>
<div class="list-item">
<p>A2</p>
</div>
<div class="list-item">
<p>A3</p>
</div>
</body>
</html>
(Ah, it seems that I somehow submit the same comment for four times! It's my first time to use bugzilla and I'm not sure what went wrong. I couldn't find a button to delete my duplicate comment. I'm sorry for this)
Assignee | ||
Comment 9•1 year ago
|
||
So, I thought I had come up with a clever way of doing it with even less CSS. Just:
div.list-item {
contain: style;
counter-increment: my-list-counter;
position: relative;
margin-left: 100px;
}
div.list-item::before {
position: absolute;
content: '[' counter(my-list-counter, decimal) ']';
color: red;
left: -40px
}
But that doesn't work in Chrome / Safari :'(
I believe Firefox is right tho, as per https://drafts.csswg.org/css-contain-2/#property-scoped-to-a-sub-tree:
except the scoping element itself is counted as "outside" the tree
Chrome and Safari fail to do this afaict...
Assignee | ||
Comment 10•1 year ago
|
||
Assignee | ||
Comment 11•1 year ago
|
||
Firefox's rendering is correct, if I'm not holding this wrong, as per:
https://drafts.csswg.org/css-contain-2/#containment-style:
The counter-increment and counter-set properties must be scoped to the element’s sub-tree and create a new counter.
https://drafts.csswg.org/css-contain-2/#property-scoped-to-a-sub-tree:
the scoping element itself is counted as "outside" the tree, like the rest of the document, and the effects of the property on that element are unaffected by scoping.
I believe Chrome and Safari fail to implement that last bit.
Updated•1 year ago
|
Reporter | ||
Comment 12•1 year ago
|
||
Thank you very such! Your code works like a charm! I didn't know I can use contain: style
here.
I guess I could use @supports (-moz-appearance: none)
to apply different rules to Firefox and other browsers as a workaround for now.
Assignee | ||
Comment 13•1 year ago
|
||
Well, Firefox is doing the right thing, so ideally you avoid hacking for Firefox and add the special-case for Chrome/WebKit instead. But... :)
Reporter | ||
Comment 14•1 year ago
|
||
😄 I will use @supports not (-moz-appearance: none)
to add special-case for non-Firefix browsers.
Comment 15•1 year ago
|
||
A patch has been attached on this bug, which was already closed. Filing a separate bug will ensure better tracking. If this was not by mistake and further action is needed, please alert the appropriate party. (Or: if the patch doesn't change behavior -- e.g. landing a test case, or fixing a typo -- then feel free to disregard this message)
Updated•1 year ago
|
Assignee | ||
Comment 16•1 year ago
|
||
The patch is just a test for an issue that was here (https://bugs.chromium.org/p/chromium/issues/detail?id=1462328). So seems appropriate to use this bug to land it? I'm happy to file a different one too I guess, it's just that it didn't seem worth it...
Comment 17•11 months ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #16)
The patch is just a test for an issue that was here (https://bugs.chromium.org/p/chromium/issues/detail?id=1462328). So seems appropriate to use this bug to land it?
Yup, this is fine, per the parenthetical at the end comment 15. ("e.g. landing a test case")
Comment 18•11 months ago
|
||
Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/f9c12557d7a4 Add a WPT for the counter scoping issue mentioned in comment 9. r=dholbert
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/41162 for changes under testing/web-platform/tests
Comment 20•11 months ago
|
||
bugherder |
Upstream PR merged by moz-wptsync-bot
Comment 22•11 months ago
|
||
bugherder |
Description
•