[css-lists] Implement presentational hint for the `counter-reset` [chromium/src : main]

0 views
Skip to first unread message

Minseong Kim (Gerrit)

unread,
Jan 9, 2026, 7:15:02 AM (3 days ago) Jan 9
to AyeAye, Rune Lillesveen, Daniil Sakhapov, Chromium LUCI CQ, Menard, Alexis, chromium...@chromium.org, blink-rev...@chromium.org, blink-re...@chromium.org, apavlo...@chromium.org, blink-re...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
Attention needed from Daniil Sakhapov and Rune Lillesveen

Minseong Kim added 5 comments

Patchset-level comments
File-level comment, Patchset 20 (Latest):
Minseong Kim . resolved

Thanks for the reviews. Would you review again, please?

File third_party/blink/renderer/core/dom/element.cc
Line 5439, Patchset 18: if (RuntimeEnabledFeatures::CSSCounterResetReversedEnabled() &&
Rune Lillesveen . resolved

So, IIUC, we cannot represent this modification as presentation style because it's combined with declarations from author style in a way that is not expressible using current CSS primitives?

It looks like the counter-reset part could be represented as presentation style?

Or actually, looking at the code below, it does indeed like this could be purely presentation style. What does the spec say?

Rune Lillesveen

In fact, it's specified as presentation style here:

https://html.spec.whatwg.org/multipage/rendering.html#the-css-user-agent-style-sheet-and-presentational-hints

Rune Lillesveen

HTML element specific presentation styles are implemented in overrides of CollectStyleForPresentationAttribute()

Minseong Kim

Ah, yes, that's the correct way! Thank you so much for the information. Done.

Line 5466, Patchset 18: builder.AccessCounterDirectives().insert(list_item_identifier,
new_directives);
Daniil Sakhapov . unresolved

btw, I don't think we should override "list-item" counter directive, if the element has one defined from style?
let's add a test for it, which has some non-default "list-item" counter sets and reversed on <ol>?

Minseong Kim

This didn't override the "list-item" counter because this logic was guarded by `if (!directives.IsReset())`.


> let's add a test for it, which has some non-default "list-item" counter sets and reversed on <ol>?


Can I ask `third_party/blink/web_tests/external/wpt/css/css-lists/li-value-reversed-025.html` is right one?

File third_party/blink/renderer/core/html/html_olist_element.cc
Line 92, Patchset 18: kSubtreeStyleChange,
Rune Lillesveen . resolved

kSubtreeStyleChange can be super-expensive. Why do we need to recalc all descendants?

Minseong Kim

Removed. `SetNeedsStyleRecalc` is not need after moving the logic into `CollectStyleForPresentationAttribute`.

Line 101, Patchset 18: if (reversed == IsReversed()) {
Minseong Kim . resolved

Hmm, I need to check if changing the reversed attribute value from true to false and changing to true immediately causes any issues.

Minseong Kim

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Daniil Sakhapov
  • Rune Lillesveen
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic2dc0661b9c57dfbd021c0f52b6e7ec0a2070c9d
Gerrit-Change-Number: 7233512
Gerrit-PatchSet: 20
Gerrit-Owner: Minseong Kim <jja0...@gmail.com>
Gerrit-Reviewer: Daniil Sakhapov <sakh...@chromium.org>
Gerrit-Reviewer: Minseong Kim <jja0...@gmail.com>
Gerrit-Reviewer: Rune Lillesveen <fut...@chromium.org>
Gerrit-CC: Menard, Alexis <alexis...@intel.com>
Gerrit-Attention: Daniil Sakhapov <sakh...@chromium.org>
Gerrit-Attention: Rune Lillesveen <fut...@chromium.org>
Gerrit-Comment-Date: Fri, 09 Jan 2026 12:14:54 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Daniil Sakhapov <sakh...@chromium.org>
Comment-In-Reply-To: Rune Lillesveen <fut...@chromium.org>
Comment-In-Reply-To: Minseong Kim <jja0...@gmail.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Minseong Kim (Gerrit)

unread,
Jan 9, 2026, 10:46:30 PM (3 days ago) Jan 9
to AyeAye, Rune Lillesveen, Daniil Sakhapov, Chromium LUCI CQ, Menard, Alexis, chromium...@chromium.org, blink-rev...@chromium.org, blink-re...@chromium.org, apavlo...@chromium.org, blink-re...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
Attention needed from Daniil Sakhapov, Minseong Kim and Rune Lillesveen

Message from Minseong Kim

Set Ready For Review

Open in Gerrit

Related details

Attention is currently required from:
  • Daniil Sakhapov
  • Minseong Kim
  • Rune Lillesveen
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic2dc0661b9c57dfbd021c0f52b6e7ec0a2070c9d
Gerrit-Change-Number: 7233512
Gerrit-PatchSet: 21
Gerrit-Owner: Minseong Kim <jja0...@gmail.com>
Gerrit-Reviewer: Daniil Sakhapov <sakh...@chromium.org>
Gerrit-Reviewer: Minseong Kim <jja0...@gmail.com>
Gerrit-Reviewer: Rune Lillesveen <fut...@chromium.org>
Gerrit-CC: Menard, Alexis <alexis...@intel.com>
Gerrit-Attention: Daniil Sakhapov <sakh...@chromium.org>
Gerrit-Attention: Rune Lillesveen <fut...@chromium.org>
Gerrit-Attention: Minseong Kim <jja0...@gmail.com>
Gerrit-Comment-Date: Sat, 10 Jan 2026 03:46:21 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Daniil Sakhapov (Gerrit)

unread,
8:42 AM (10 hours ago) 8:42 AM
to Minseong Kim, AyeAye, Rune Lillesveen, Chromium LUCI CQ, Menard, Alexis, chromium...@chromium.org, blink-rev...@chromium.org, blink-re...@chromium.org, apavlo...@chromium.org, blink-re...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
Attention needed from Minseong Kim and Rune Lillesveen

Daniil Sakhapov added 3 comments

File third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
Line 362, Patchset 21 (Latest): int64_t counter_value = counter_data_value->ComputeNumber(state.CssToLengthConversionData());
Daniil Sakhapov . unresolved

ComputeInteger maybe?

File third_party/blink/renderer/core/html/html_olist_element.cc
Line 81, Patchset 21 (Latest): // This logic depends on both attributes. To avoid duplicate processing,
// if both are present, skip when processing the 'reversed' attribute.
if (name == html_names::kReversedAttr && has_explicit_start_) {
return;
}
Daniil Sakhapov . unresolved

what if you already have an explicit start attribute, but then with JS you set reversed = true, then due to this `if` it would early return, and 'start' is cached, so we don't see a change?
maybe just remove it at let the latest pass override to produce the final correct value?

File third_party/blink/web_tests/fast/lists/ol-reversed-dynamic.html
Line 22, Patchset 21 (Latest): list3.setAttribute("reversed", "");
Daniil Sakhapov . unresolved

why this? maybe it's due to the early return problem I've mentioned above?

Open in Gerrit

Related details

Attention is currently required from:
  • Minseong Kim
  • Rune Lillesveen
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ic2dc0661b9c57dfbd021c0f52b6e7ec0a2070c9d
Gerrit-Change-Number: 7233512
Gerrit-PatchSet: 21
Gerrit-Owner: Minseong Kim <jja0...@gmail.com>
Gerrit-Reviewer: Daniil Sakhapov <sakh...@chromium.org>
Gerrit-Reviewer: Minseong Kim <jja0...@gmail.com>
Gerrit-Reviewer: Rune Lillesveen <fut...@chromium.org>
Gerrit-CC: Menard, Alexis <alexis...@intel.com>
Gerrit-Attention: Rune Lillesveen <fut...@chromium.org>
Gerrit-Attention: Minseong Kim <jja0...@gmail.com>
Gerrit-Comment-Date: Mon, 12 Jan 2026 13:42:30 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Daniil Sakhapov (Gerrit)

unread,
8:43 AM (10 hours ago) 8:43 AM
to Minseong Kim, AyeAye, Rune Lillesveen, Chromium LUCI CQ, Menard, Alexis, chromium...@chromium.org, blink-rev...@chromium.org, blink-re...@chromium.org, apavlo...@chromium.org, blink-re...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org
Attention needed from Minseong Kim and Rune Lillesveen

Daniil Sakhapov added 2 comments

File third_party/blink/renderer/core/dom/element.cc
Line 5466, Patchset 18: builder.AccessCounterDirectives().insert(list_item_identifier,
new_directives);
Daniil Sakhapov . resolved

btw, I don't think we should override "list-item" counter directive, if the element has one defined from style?
let's add a test for it, which has some non-default "list-item" counter sets and reversed on <ol>?

Minseong Kim

This didn't override the "list-item" counter because this logic was guarded by `if (!directives.IsReset())`.


> let's add a test for it, which has some non-default "list-item" counter sets and reversed on <ol>?


Can I ask `third_party/blink/web_tests/external/wpt/css/css-lists/li-value-reversed-025.html` is right one?

Daniil Sakhapov

I see now, thanks, looks good!

File third_party/blink/renderer/core/html/html_olist_element.h
Line 52, Patchset 17: bool IsReversed() const {
if (RuntimeEnabledFeatures::CSSCounterResetReversedEnabled()) {
return ListItemCounterDirectives().IsResetReversed();
}
return is_reversed_;
}
Daniil Sakhapov . unresolved

Just a side note - I was a bit worried about this, since - https://developer.mozilla.org/en-US/docs/Web/API/HTMLOListElement/reversed says `It reflects the reversed attribute of the <ol> element.`

But in IDL (https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_olist_element.idl;l=25;drc=939a03bab4837456f0924dbc2502f6f557dc0801) we have - `[CEReactions, Reflect] attribute boolean reversed;`, which probably generates something like `bool HTMLOListElement::reversed() { return hasAttribute("reversed"); }`.
Meaning that we don't use IsReversed() to interact with JS `revesed` prop, so it should be fine.

But it raises another question. This IsReversed() function now requires style to be clean, right? Could you, please, double check that it doesn't conflict with the call sites that use it?

Maybe we need to think through some test that changes attribute from JS and checks result before the style is triggered? (or maybe it's not even possible)

@fut...@chromium.org, could you check my thoughts, please?

Daniil Sakhapov

I gave it more thought though and found that it is a more complex indeed.

Check HTMLOListElement::ParseAttribute, when we change `reversed`, we end up immediatly calling InvalidateItemValues().

THat sounds dangerous? Or it will just mark list items as layout and paint dirty, but then RecalcOwnStyle changes will override those changes anyway, so that the final update is still correct?

Rune, could you check the logic, please?

Minseong Kim

Yes, `IsReversed()` requires the style to be clean. I have checked the call sites: `CountersAttachmentContext::MaybeCreateListItemCounter`, `ListItemOrdinal::IsInReversedOrderedList` and `ListItemOrdinal::CalcValue` are invoked during the Layout phase.

On the other hand, `HTMLOListElement::ParseAttribute` is triggered during the DOM/Attribute Parsing phase. However, it only calls `InvalidateItemValues()` to mark the ordinals as dirty. It does not perform any immediate calculations that require clean style. So, there should be no conflict.. right?

Daniil Sakhapov

sounds good, I'll just let Rune have a second look

Gerrit-Comment-Date: Mon, 12 Jan 2026 13:43:42 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Daniil Sakhapov <sakh...@chromium.org>
Comment-In-Reply-To: Minseong Kim <jja0...@gmail.com>
satisfied_requirement
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages