Csswg-drafts: [css-lists] Should option/optgroup be able to set counters?

Created on 4 Jun 2019  Ā·  17Comments  Ā·  Source: w3c/csswg-drafts

Should one be able to use 'counter-increment'/etc on <option>/<optgroup> (and other replaced-element form-control descendants)?

I think a strict reading of the spec says no - since <select> is replaced, its children don't generate CSS boxes, and things that don't generate CSS boxes can't interact with counters.

However, that text was written with display:none in mind, not necessarily replaced element descendants.

Here's an example: https://codepen.io/kizu/pen/PEJgpr. Apparently this works in Firefox, and pre-chromium Edge, but it does not work in WebKit or Chrome.

Closed Accepted by CSSWG Resolution css-lists-3

Most helpful comment

Ugh, tho, http://software.hixie.ch/utilities/js/live-dom-viewer/saved/7022 shows that Chrome does increment counters on option inside of <select multiple>. That's terrible, this is terrible, the web is bad and a mistake.

All 17 comments

Hmm, yeah. I think that should work. So CSS boxes or other representation in a rendering tree that's capable of holding CSS properties???

Small note: it works in Chrome with multiple attribute :) https://codepen.io/kizu/pen/EowqxX

(Also, a link to the chromium issue)

I'm not sure if I want to push this as something that should work everywhere, but there is no other way right now to use the value of selects in any other way in CSS, so…

Other case tests for which that I remember doing and which had differences in various browsers (but I don't think I created issues for this) — counter-increment inside inline SVG. I imagine there could be other _interesting_ cases, including maybe shadow DOM and so on :D

Yeah, svg is also a replaced element, and its descendants don't generate CSS boxes either...

The CSS Working Group just discussed Should option/optgroup be able to set counters?.

The full IRC log of that discussion
<dael> Topic: Should option/optgroup be able to set counters?

<dael> github: https://github.com/w3c/csswg-drafts/issues/4004

<dael> TabAtkins: Technically per CSS they are decendent of replaced so don't generate boxes. if continuing the current resolution that counters work on box tree there's no box to let them set or change counter. Howveer FF and previous Edge allow it. Chromium does not

<rachelandrew> I'll take a better look at issue 3846 and see if I have any thoughts from the authoring pov.

<dael> TabAtkins: There are use cases for this and a chromium issue to fix and allow setting of counters.

<dael> TabAtkins: Chrome devs discussing if they should, bbut no conclusion

<dael> TabAtkins: This may effect related issues like if SVG elements can set counters.

<dael> TabAtkins: We need to figure out exact terminology. fantasai prop is go one level up to also things that are like boxes, but not css boxes for layout terms and allow those to host counters.

<dael> TabAtkins: I'm fine with that. prop is allow optin/optgroup and other things that are like boxes outside the css model to effect counters

<dael> astearns: sgtm

<dael> AmeliaBR: Makes sense. I'd like a more explicit definition to what is and isn't like a box

<dael> TabAtkins: I prefer to define a new term other specs could hook and we define what that is for HTML and SVG. Other mockups could say they are that thing even though they don't generate css boxes

<dael> astearns: Other comments?

<TabAtkins> s/mockups/markup languages/

<dael> smfr: Sounds a little confusing for interactions with display:none. If you have optgroup that contributes to counters and you display:none it does it still contribute?

<dael> TabAtkins: I don't think display:none does anything to optin

<dael> smfr: If you have one of these how do you stop contributing to counters

<dael> TabAtkins: You don't set the counter. the display:none wasn't an intentional choice, it was legacy

<dael> smfr: Sounds like it will complicate code to determine what contributes to counters. May be odd interaction with other properties is what I'm saying

<dael> fantasai: I kinda disagree, I would expect diplay:none to have effect on counters. You're processing css properties and counters is one of them. I don't have strong opinion on this

<dael> TabAtkins: If someone with FF or older Edge can check that link I want to see if display has effect in other

<dael> smfr: [missed]

<futhark> Display:none affected in firefox

<smfr> webkit shows the ā€˜bar’ in the testcase

<futhark> that is, removed from select rendering

<dael> Rossen_: We do not support counters inside of display:none. Only time we did something more interesting is if gCS was called inside and we'd have something to calculate in the sub tree. I think we backed it out because it was fragile

<dael> fantasai: I htink prop is that anything that is a replaced element has nothing to do with counters or we have something represented in render tree and not display:none and they can have counters

<dael> astearns: Either way impl would need to change b/c we're not interop

<dael> TabAtkins: Yeah

<dael> TabAtkins: And we're buckwild with what styles can effect inside a select

<dael> fantasai: If we have an idea we want to do this how aout TabAtkins and I come up with specific wording that deals with the issues brought up here. We can bring it back and htink about how it effects different impl

<dael> astearns: Objections to that path?

<dael> ACTION TabAtkins and fantasai develop spec text for https://github.com/w3c/csswg-drafts/issues/4004

<trackbot> Created ACTION-881 - And fantasai develop spec text for https://github.com/w3c/csswg-drafts/issues/4004 [on Tab Atkins Jr. - due 2019-06-26].

Based on testing with http://software.hixie.ch/utilities/js/live-dom-viewer/saved/7019, it looks like:

  • Chrome & Safari allow counters to increment on SVG internals, but never on select internals.
  • Firefox & old-Edge allow counters to increment on SVG internals, and on displayed option elements, but not on display:none options.

I think my preference right now is to say that SVG boxes can manipulate counters (those exist per spec, I'm pretty sure), but that other replaced-element internals cannot (unless otherwise defined).

Ugh, tho, http://software.hixie.ch/utilities/js/live-dom-viewer/saved/7022 shows that Chrome does increment counters on option inside of <select multiple>. That's terrible, this is terrible, the web is bad and a mistake.

So… I was thinking a little more about @kizu's comment about SVG, and wondered if it was specifically about non-rendered SVG elements that aren't technically display: none. And what about <use> copies of SVG elements?

I made a slight variation: http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=7025

Chrome and Firefox both increment for non-rendered SVG elements, unless they explicitly have display: none. Firefox gets completely lost with the <use> copy (the counter gets reset in the outer scope). Chrome just ignores it (not sure if that's normal for shadow DOM). Old Edge reboots the tab helplessly at this monstrosity of a test; not sure which part is so painful (based on an early version of the test, it had seemed to be incrementing for rendered, non-rendered, and shadow SVG content).

I think a strict reading of the spec says no - since <select> is replaced, [...]

It's wrong to say that <select> is a replaced element, because it's not, it's a widget.
I would assume that <option>/<optgroup> are neither replaced elements, nor widgets, since they are not listed in those sections.

... its children don't generate CSS boxes

I tend to disagree with that. We certainly create boxes for <option>/<optgroup> internally in Gecko, albeit with severely restricted styling, and only for its text children etc. (Those limitations are completely artificial, btw. We could support pretty much all of CSS, and arbitrary child content, if the specs allowed it (in fact we did, but then we had to dumb it down to be compatible with other UAs/specs).)

and on _displayed_ option elements, but not on display:none options.

All UAs suppress incrementing counters on all display: none elements. I don't see why <option>/<optgroup> should be special in this respect.

That's terrible, this is terrible, the web is bad and a mistake.

The web is terrible because the CSSWG put that in the spec :-p.

Seriously though, it's 2019 and I still can't do this:

<select>
  <option><img src="Pineapple.png">Pineapple
  <option><img src="Apple.png">Apple
  <option><img src="Lemon.png">Lemon
</select>

Sigh. Now _that_ is truly terrible, because web authors routinely has to work around that in all sorts of terrible ways. It makes me sad because it would be so trivial to support if the specs just allowed it...

BTW, this works perfectly fine in Gecko (meaning we create a grid container for it and render its child elements as grid items):

<style>
option {
  display:grid;
  grid-template-columns: 100px auto;
}
</style>
<option><x>a</x><x>a</x>

Chrome also creates a box for it, but not a grid container(?), although its devtools still reports that the computed value is grid-template-columns: 100px 1152px; as if it were a grid container. Hmm.
Safari doesn't create a box at all.

@MatsPalmgren Here's the layout tree in Chrome:

LayoutNGBlockFlow {HTML} at (0,0) size 800x600
    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
      LayoutGrid {OPTION} at (0,0) size 784x20.19
        LayoutNGBlockFlow (anonymous) at (2,0) size 100x19.19
          LayoutText {#text} at (0,0) size 15x18
            text run at (0,0) width 15: "aa"

It looks like Chrome ignores any elements inside of the option element. I saw the same behaviour with divs, for example.

What are the counter arguments to letting an option element be styled? It feels like if as @MatsPalmgren suggested, we allow images in them (which at a high level seems desirable), all CSS (and therefore counters) should work.

whatwg/html/issues/3596 seems relevant here.

Thinking about this, having counters on selects with multiple is probably the most ā€œrealā€ use case they could have — to show stuff like ā€œN out of M options selectedā€. Counters on options of regular selects still could have viable use-cases (mostly for similar counting/validation help purposes), but as this is not something that was not available at all browsers, developers didn't research this enough.

Talking about if something like that should be present at all, I would confirm that, ideally, options _should_ generate boxes, and developers should have more control over what should be inside the options and how they should be displayed (also: how the option groups should be displayed and styled, but thats completely another issue). Actually, my experiments came from trying to find a way to at least display some extra images (flags for a country input, to be precise) for a selected value. Allowing images inside options would mean so much, and if select styling would be enhanced, I could live without counters on them (but then, if they would generate boxes, they would need to have counters, so… win/win).

The counter-argument to letting options be styled is the same for all the "interesting" form controls: browsers have (and take advantage of!) significant leeway in displaying the elements. Load up a page with a select on Chrome desktop, Chrome android, and the Android Watch browser, for instance; in all three browsers there's significant variation in how the element and its contents are formatted and displayed. (And similar differences exist between all other browsers.)

We'd ideally like to figure out what to actually do about this, so we can define what properties actually work, but we've never had the time to do any of that & implementor interest to actually pursue any work. :(

OK, so Tab and I are proposing to leave the case of descendants of replaced elements explicitly undefined for now.

The CSS Working Group just discussed Should option/optgroup be able to set counters?, and agreed to the following:

  • RESOLVED: leave undefined for now and add a note explaining why

The full IRC log of that discussion
<dael> Topic: Should option/optgroup be able to set counters?

<dael> github: https://github.com/w3c/csswg-drafts/issues/4004#issuecomment-506906199

<dael> astearns: We left it at fantasai and TabAtkins suggesting we punt on replaced elements for now

<TabAtkins> Yes

<dael> fantasai: Dug into issue a little. Seems like figuring out what's going on for form controls is a mess. To get spec to reflect reality we figured fine for spec to leave it undefined.

<dael> fantasai: Want to check with WG if really want to dig into the issue

<dael> heycam: I think need to do at some point, but okay undefining it for now. At some point need to consider alt presentations of certain elements like select and what it means to allow UAs to have CSS based and nonCSS based preso.

<dael> heycam: Make sure counters and anything else makes sense in presence of presenting these in different ways

<dael> astearns: Given we have 1.5 impl that reset counters and option/optgroup are the most list-like would it make sense to def those and leave reset?

<dael> fantasai: Could. Want to move to a world with more styling rather than less. Makes sense elements with some visual rep can handle counters. No reason they can't manipulate counters. I don't feel strongly this is important to solve right now. Happy to leave undefined and let impl merge toward more things being countable

<dael> AmeliaBR: Specific behavior for option/optgroup the inconsistancies with counters are related to other styling inconsistancies. Getting a proper model for explaining how option/optgroup and selects in general work for display trees wuld be useful. Special rules for counters without whole model might make more complicated

<dael> heycam: Counters are special because can effect thigns without. Sep from general stylability in that way. Seems we could solve counter issue independent in terms of should be obserable outside the select so counters increment

<dael> heycam: Am I right that if counters increment inside you can see it outside?

<dael> fantasai: Yeah

<dael> astearns: IN some browsers it has effect, in others it does not

<dael> heycam: Agree with fantasai might not be super important. Does seem like a discussion we can have about if it's acceptable to make UAs that don't have CSS based and therefore boxes should do something else to inc. counters

<dael> fantasai: I think cases where this shows up is test cases. I can imaging using counters within select box but not ref outside. Given not sure how this impacts impl arch. I'm leaning to undefined and let them converge. I don't think we should spend effort getting impl to align. If there's a use case later we can add it. That's why I advocate leave undefined. What impl doing is prob fine for now

<dael> astearns: What is resolve to undefine at this level and add a note we're doing this b/c no interop and don't have a use case guiding to the right direction

<dael> fantasai: More no use case to spend engineering effort to align. Right direction for authors is honors counters. That's what they would expect and it's reasonable. Don't think it matters in this strange case

<dael> astearns: Just having anote why we're leaving undef.

<dael> fantasai: I can have a note that there's no interop and we don't think it's important to get interop so we're leaving it undefined

<dael> astearns: Any further arguments to not leave undefined

<dael> tantek: Can we live with this being a compat issue where we have to compat with whatever Chrome does?

<dael> astearns: Are you aware of any Gecko bugs currently?

<dael> tantek: I don't. I believe that us leaving undef in the long term means it'll end up being a compat issue with Chrome. If we can live with what Chrome does eventually spec may have to spec.

<dael> AmeliaBR: Given it's lack of feature in dominant browser I don't know if that argument is that strong. I don't think people will rely on counters not working in optiongroups. There might be a zombie CSS issue if it ever works but that's not major web compat arg.

<dael> TabAtkins: Okay

<dael> s/tab/tantek

<dael> astearns: Proposal is leave undefined for now and add a note explaining why

<dael> astearns: Objections?

<dael> RESOLVED: leave undefined for now and add a note explaining why

@fantasai please make sure you have an edit for the note (I was surprised you closed this without that change)

@astearns The note was added in 2988d2b9, forgot to link it to this issue.

Was this page helpful?
0 / 5 - 0 ratings