[CSSWG] Minutes San Francisco F2F 2016-05-09 Part II: Counters, Values & Units [css-lists] [css-values]

=========================================
  These are the official CSSWG minutes.
  Unless you're correcting the minutes,
 Please respond by starting a new thread
   with an appropriate subject line.
=========================================


Counters
--------

  - RESOLVED: Add new syntax (TBD) to control counter scoping and
              consider reversing too.
  - TabAtkins will write a proposal for this new syntax.

Values & Units
--------------

  - plinss will file an issue with TAG to fix the general pushState/
      url reference problem in the DOM.
  - RESOLVED: Add hidden state to hash-reference-only URLs so that
              they can always resolve locally in presence of
              pushState
  - RESOLVED: Adapt the element() function so that it can be used to
              refer to always-local references

===== FULL MINUTES BELOW ======

Agenda: https://wiki.csswg.org/planning/san-francisco-2016#proposed-agenda-topics

Scribe: Shane

Counters
--------

  <astearns> https://lists.w3.org/Archives/Public/www-style/2016Apr/0364.html
  TabAtkins: Ran into a fun example, author commented on what he
             thought was a mistake in list spec.
  [TabAtkins] draws a diagram
  <fantasai> Tab writes:
  <fantasai> <ol>
  <fantasai>   <li>
  <fantasai>   <li>
  <fantasai> </ol>
  <fantasai> <div>
  <fantasai>   <ol>
  <fantasai>     <li>
  <fantasai>   </ol>
  <fantasai> </div>
  TabAtkins: interesting thing is if you manually set up counters
  TabAtkins: and use the counters() function

  dbaron: You're supposed to counter reset on ol:before, not ol. I
          think that avoids the bug you're about to describe.
  TabAtkins: IT DOES!
  [the crowd goes wild]
  <SimonSapin> dbaron: even if ::before has display: none?
  <SimonSapin> or content:none
  TabAtkins: So we should just adjust the spec to say ol:before
             instead of ol?
  dbaron: Assuming :before exists though.

  TabAtkins: Counter established by counter-reset on the first ol
             counts its siblings until the first one that resets
             but the next ol is a cousin, so it nests instead.
  TabAtkins: Few ways around it. (1) instead counter-reset on first
             li or on :before. Then scope only covers the list.
  TabAtkins: (2) explicitly resetting a counter when it came from
             something that wasn't in the ancestor chain then reset
             instead of nesting.
  Florian: Wouldn't that fail with headings?
  TabAtkins: No?
  dbaron: Yes.

  dbaron: The rule is that a later sibling replaces an earlier
          sibling's counter, but not if it's a descendant of the
          later sibling.
  TabAtkins: If you're using heavy sectioning content then you've
             got nesting and it'd probably break.
  dbaron: With sections you should be fine, as long as sections &
          headings line up.

  dbaron: There was another problem, solution was counter-set
          property.
  dbaron: I don't remember the problem.
  TabAtkins: The value attribute on li. Already in spec.
  dbaron: I was trying to remember if other problem relates to this
          one, it doesn't.

  ekimber: Question: what's the use case for having the counter
           apply to following siblings?
  TabAtkins: Headings. You set up one counter at the top of the
             document and run it right down through the whole thing.
             If you have a flat document structure where headings
             are siblings then you can reset H1 and H2 counters,
             which will operate until next H1, next H2, etc.
  dbaron: You reset your H2 counter *at* your H1.
  ekimber: Given that, response would be "HTML is broken, so what."
  ekimber: So this is user error.
  ekimber: This is an unavoidable consequence of having to support
           this flat list.
  TabAtkins: Not necessarily, only if you want to support *all* of
             what HTML can do.
  TabAtkins: If you have an H1 as a child of body, and a div wrapper
             around the H2 that sets up a subsection.
  TabAtkins: Then that would break with the suggestion I'm making.
  ekimber: Implication seems to be - be consistent, otherwise things
           will mess up.
  Florian: Also the header element, can use for header of page OR
           title with subtitle.
  Florian: Not consistent, so nesting will be varying,

  esprehn: This change would be observable, right?
  esprehn: ol resets the counter. If you put the value attribute on
           an li which lets you explicitly number, then there's a
           reset there too.
  dbaron: That's a set.
  TabAtkins: Something something bug.
  esprehn: Does anyone implement?
  esprehn: We support counter but both value and reset are the same.
           So doing this changes the behavior.
  TabAtkins: But current behavior is very unexpected
  dbaron: <li><li><li value=5> - counter value inside each one,
          without set you'd have 1, 2, 2.5
  TabAtkins: So yeah it'll fix it to 1, 2, 5, which is actually good.

  Florian: Given earlier thing with header, does that rule out
           solution?
  TabAtkins: Makes it less attractive. Another option: add a
             property to counter-reset or another property that
             changes scope
  TabAtkins: to descendants only instead of descendants & siblings.
  TabAtkins: Problem with :before is that it may not get created.
  dbaron: I like the new value or property idea
  plinss: Putting the :before rule with reset property doesn't
          trigger :before?
  TabAtkins: Nope.

  <zcorpan> "This specification does not yet define the CSS-specific
            rules for rendering li elements, because CSS doesn't yet
            provide sufficient hooks for this purpose."
            https://html.spec.whatwg.org/multipage/rendering.html#lists
  zcorpan: Question: is it possible with counter spec to specify how
           <ol> and <li> are supposed to work?
  TabAtkins: You can as long as nesting isn't observable.
  TabAtkins: Except for reverse
  TabAtkins: but if nesting is exposed somehow then the naive
             mapping is wrong and can't be done in CSS.
  zcorpan: I think we should make the counter spec usable by <ol>,
           <li>
  TabAtkins: Yup.
  fantasai: Yup.
  TabAtkins: Shall we go with the idea of a new value or property
             that scopes only to descendants?
  <TabAtkins> ol > :first-child
  <zcorpan> including <ol reversed> (ideally)
  Florian: but we can just ol :first-child { counter-reset: blah }.

  [Tab draws a waaay better diagram]
  <shane> https://usercontent.irccloud-cdn.com/file/HwvTalBE/IMG_20160509_115341.jpg

  Scribe: fantasai

  Florian: So one proposal was use ::before if it exists, or
           :first-child of the list
  Florian: to reset the counter.
  TabAtkins: It works for HTML, but it is weird overall, because you
             have to be concerned with the first child who is being
             set.
  TabAtkins: Setting on the container is much cleaner.
  TabAtkins: So one proposal is to cut counter [...]
  TabAtkins: Better one from dbaron is we have some syntax for
             indicating on counter-reset that counter will only
             scope to its descendants.
  TabAtkins: The counter would then end its scope at the end of the
             </ol>
  Florian: Seems a lot cleaner, but worried it will be very obscure
           and nobody would know about it.
  Florian: Is it better to have a simple system with ::before or a
           complex system with lots of switches?

  Scribe: shane

  TabAtkins: I wouldn't have designed counters this way.

  fantasai: One use case that should work - sometimes you start a
            list, then close and want to continue later.
  <zcorpan> <ol start>
  dauwhe: This is super important for us.
  Florian: Can't just use a class?
  TabAtkins: You need to establish counter in ancestor.
  dbaron: dauwhe, does it sound OK if browsers implement list
          numbering using counters, you could do it by having a div
          higher up that contains all the lists you want to number
          together
  dbaron: explicitly resetting list counter on that div, then
          removing on individual lists. Would this work for you?
  dauwhe: That makes sense to me and I think I can explain it OK to
          people too.

  <TabAtkins> https://drafts.csswg.org/css-flexbox/#main-sizing
  TabAtkins: This is explicitly what we use in the flex algorithm.
  TabAtkins: Multiple OLs crossing sections that number
             subsequently, put a counter on body and use that one
             instead.

  Florian: Either if we have a simple but surprising system, or a
           complex system, people aren't going to understand and
           will need to look at stack overflow.
  TabAtkins: Can put into UA stylesheet and make prominent in spec
  TabAtkins: if you're doing headings, do it like this, etc.
  Florian: Probably cleaner with complex but unsurprising system.
  fantasai: If it's a syntactic switch then it'll be in the spec.
  fantasai: People who are using counters are going to look it up.
            It'll be fairly obvious

  fantasai: so add a keyword to counter-reset?
  TabAtkins: We can't extend counter-reset. It's multi-valued
             without commas between each value.
  TabAtkins: Can't tell whether a keyword is a second counter or not.
  Florian: So multiple counters, might want to scope each one
           differently. So need a list in the parallel property too?
  fantasai: Can have a second property which does the same as
            counter-reset but with the other behavior. OR a property
            that switches the behavior.
  dbaron: Want other options too, in particular reversing.
  TabAtkins: Currently can't be expressed in the counter model.

  RESOLVED: Add new syntax to control counter scoping and consider
            reversing too. (Syntax TBD.)

  <dbaron> (Tab to propose syntax)
  <zcorpan> (This needs to be directly usable by HTML spec's UA
            stylesheet for <ol>, <ol start>, <li value>,
            <ol reversed>...)
  [discussion about resolutions, resolution reversion, and
      contradictions]
  <dbaron> (and counter-resolutions)

Values and Units
----------------

  TabAtkins: Say you have a background image 'url(#svgfrag)'.
  TabAtkins: Clearly points to something local.
  TabAtkins: Once you absolutize the url
  TabAtkins: you notice it points to same doc, go find it,
             everything's cool.
  TabAtkins: But say you do push-state to update the URL, the page
             changes it's URL
  TabAtkins: we don't go an re-absolutize the images
  TabAtkins: (in all browsers, interoperably).
  TabAtkins: So that's an issue. pushState means the reference is no
             longer local.

  <zcorpan> history.pushState()
  <zcorpan> or insert a <base href>
  <SimonSapin> this is an inline stylesheet, right?
  <SimonSapin> <style> not <link>

  dbaron: Why didn't that change when the document's URI changes?
  TabAtkins: Because everyone absolutizes at parse time and nobody
             changes it.
  fantasai: Can't we fix it?
  TabAtkins: No. It's good behavior.
  TabAtkins: If the ref is relative to to the slash path then do
             pushState that just changes local position in doc tree
             would result in local references being probably wrong.
  TabAtkins: If you start out at http://example.com and reference
             foo.svg
  TabAtkins: then pushState to http://example.com/startMyApp/
  TabAtkins: then we're now referencing
             http://example.com/startMyApp/foo.svg, which probably
             doesn't exist.
  TabAtkins: So don't want to update in this case.

  fantasai: This is super messed up. Could have 2 different refs to
            same target that point to different things because of
            statefulness of pushState.
  zcorpan: I think it's too expensive to re-resolve all the urls in
           the universe when a pushState happens.
  plinss: If you pushState to a new URL then you should be able to
          reload from that URL and get back to exactly the same state.
  TabAtkins: In practice doesn't always work, and can use middleware
             to fix the problem anyway.
  plinss: I'm not concerned about case where middleware masks a bug.
  TabAtkins: I don't think it's a bug that you should have to
             rewrite references on pushState.
  plinss: But it is a bug that you can't reload a pushState and get
          back to the same state.
  plinss: I want to see data that we can't fix that bug.
  TabAtkins: Someone should say we *can* do it first.
  TabAtkins: It's an HTML problem.
  plinss: It's a cross-spec problem really.
  zcorpan: From browser vendor's POV the burden of proof is in other
           direction. Won't risk breaking pages without data saying
           it won't break pages.
  plinss: If it was a minor change that's fine. But fundamental
          architectural issue so different stance.
  hober: Would love to see data on compat issue, but given that
         absent data implementors are unlikely to change, who's
         volunteering to collect data?

  TabAtkins: I want to move on to issue. Not absolutizing is bad for
             local references that become remote.
  TabAtkins: So e.g. pushState from http://example.com to
             http://example.com/foo. #svgFrag no longer resolves as
             local because the URLs don't match.
  TabAtkins: My proposal: '#' is a very clear indication that you're
             doing a local reference. So if a url is JUST a hashref
             then we store state that indicates the reference is
             definitely local, and never absolutize.
  TabAtkins: If we can solve the more general problem then we don't
             need to do this.
  plinss: Sounds like a hack on a hack.
  * glazou agrees with plinss
  [A general rehashing occurs. Rehashing. Hah]

  astearns: If there is a compat issue with fixing this the right
            way, isn't this going to trigger that too?
  TabAtkins: No. This definitely always wants to be local.
  Florian: But it's not clear for files because you don't know
           whether they want to be relative or relative relative
  hober: Are you proposing that hidden state be exposed to CSSOM? Or
         via syntax to explicitly opt in? Or via URL object?
  TabAtkins: Currently just if URL string starts with '#'. Can
             detect by asking for computed value because it should
             serialize back to just a '#' instead of abs value for
             round tripping purposes.
  plinss: In general, TAG is facing another issue where we need to
          assign additional information to a URL to make it useful.
          Tim hates this. Fundamentally URLs should be standalone,
          without magic. This is going to <elided> Tim.
  TabAtkins: We could introduce new function that is identical to
             url but only accepts local references
  TabAtkins: but that doesn't fix existing pages
  TabAtkins: or upon parsing this could computed value to local only
             function.
  plinss: Yuck.
  plinss: Shouldn't make an assumption based on presence or absence
          of parts of the url.

  TabAtkins: There's a couple of options; we need to fix it somewhere.
  TabAtkins: (A) get DOM to fix everything
  TabAtkins: (B) hidden state on urls
  TabAtkins: (C) new local-only url function
  fantasai: How is that better than fixing A?
  TabAtkins: Because A will break things
  TabAtkins: e.g. your URL is "foo.svg" and you pushState to
             something with a different URL segment then your page
             will break.
  plinss: But right now it'll break on reload anyway.
  TabAtkins: We should decide on (A) assume DOM will fix everything
             and make no change or (B) make *some* sort of change.
  fantasai: What about (D) try to get (A) to work and in the
            meantime do (B).
  fantasai: I prefer (D)
  astearns: Me too, but I don't know how fixing the actual problem
            is going to happen?

  hober: Comes back to: "who's going to provide the data"? Haven't
         heard any volunteers.
  fantasai: If you do it correctly, relative URLs aren't going to
            change unless you wanted them to change. If you're
            depending on the broken-ness then it's going to change
            and you'll need to fix your URLs.
  plinss: I'll file (A) as an issue with the TAG. It's bigger than
          CSS.

  astearns: Does anyone object to pursuing a temporary solution
            while that happens?
  <fantasai> Proposed resolution: Make local fragment URLs magically
             always relative; file issue against TAG to fix this
             generally.
  Florian: (B) is a temporary solution that silently disappears if
           we fix (A) so it's better than (C)
  fantasai: yeah, agreed.

  plinss: I'd rather have a different function - i.e. (C)
  Florian: Why would you prefer a different function?
  plinss: So you can say what you mean. getElementByID should be a
          new thing, not the existing thing,
  plinss: and the parameter should be an ID, not a URL fragment.
  hober: I think esprehn's saying that functionally, fragment
         references currently are getElementByID.
  esprehn: Right. It's already live in that we can swap out elements
           and the reference updates.
  zcorpan: Special casing URLs with only a fragment already exists.
           Navigating special-cases fragment changes vs. other
           changes.
  Florian: In this case we specialize fragment behavior to do the
           right thing. So fixing behavior in the subcase. i.e. like
           (B).

  dbaron: One of the other cases for having something that isn't url
          function is to be able to move styles that reference an ID
          in a document into an external stylesheet.
  dbaron: We added an element() function as an image value. Is
          basically this.
  TabAtkins: element() might be a reasonable choice then.

  hober: This is a garbage fire. Browsers screwed up AND authors
         screwed up. (B) seems reasonable then but both plinss and
         dbaron have made reasonable arguments for adding (C) *as
         well*.
  ChrisL: SVG has a concept of a URL that's restricted to the local
          document. Originally had idref but the TAG told us to stop.

  TabAtkins: Current proposal: Add hidden state to URL *and* make
             sure element() can be used to just refer to local
             references.
  hober: I'm a little unsure about expanding element() beyond
         existing use as an image source. Probably fine.

  ACTION: Peter Linss to file an issue against the TAG to fix the
          general pushState / url reference problem
  <trackbot> Created ACTION-769

  RESOLVED: Add hidden state to hash-reference-only URLs so that they
            can always resolve locally in presence of pushState
  RESOLVED: Adapt the element() function so that it can be used to
            refer to always-local references

  <br type=lunch>

Received on Tuesday, 24 May 2016 23:36:16 UTC