[CSSWG] Minutes Cupertino F2F 2023-07-19 Part III: CSS Nesting [css-nesting]

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


CSS Nesting
-----------

  - The latest test case on #2881 (Concern about combinatorial
      explosion) showed breakage with too many nested style rules
      which the group agreed that it should be fixed.
  - It's unclear what (author-understandable) limits would be
      appropriate to avoid such out-of-memory/perf problems.
  - RESOLVED: Limits on nesting is ua-defined (Issue #2881: Concern
              about combinatorial explosion)

  - Several people expressed concerns/dislike with the way interleaved
      rules do not follow source order in the cascade, but get pulled
      up. However, there was not a clearly workable counter-proposal.
      The issue will remain open while folks draft up an alternative
      behavior. (issue #8738: Figure out whether we're fine
      with "shifting up" bare declarations after nested rules)

===== FULL MEETING MINUTES ======

Agenda: https://github.com/w3c/csswg-drafts/projects/38

Scribe: bramus

CSS Nesting
===========

Concern about combinatorial explosion
-------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/2881

  TabAtkins: Depending on your implementation strategy for nesting and
             possibly all times, there can be an issue with deeply
             nested style rules
  TabAtkins: particularly if you have selector lists
  TabAtkins: oriol posted an example at the end
  TabAtkins: Crashed webkit and makes style resolution take 10s on
             blink
  <astearns> https://yarusome.github.io/box-shadow-proposal/
  <astearns> https://github.com/w3c/csswg-drafts/issues/2881#issuecomment-1642450622
             for the latest test
  TabAtkins: We previously talked about a possible limit
  TabAtkins: In practice 3 is a reasonable limit. People don't go much
             further than that
  TabAtkins: sass did a survey on it too
  TabAtkins: we should spec some reasonable minimum to require and to
             let browsers have an implementation defined nesting depth
  TabAtkins: webkit has a limit of 128, but as you can see you can
             trigger problems much earlier
  TabAtkins: suggestions to support at least 10 limits, to err on the
             safe side of what people use
  TabAtkins: max can be higher than that
  <emilio> Firefox takes 3.6s on my machine on the test-case fwiw ;)

  matthieudubet: Issue is not surely with depths but length of selector
  matthieudubet: depth limit is easier to explain
  matthieudubet: Real issue here is the lengths of the context selector
  matthieudubet: If we put limit, we can put limit on the ??? context
                 selector
  matthieudubet: not depth per se
  matthieudubet: Suggesting to put limit of length on selector list
                 and length of context selector
  TabAtkins: And I think limit would not be a particular complex
             selector, but in product of nested selector lists
  TabAtkins: example with 256 * 256
  TabAktins: product of lengths of selector lists seems fine
  TabAktins: whichever seems more reasonable to impls
  TabAktins: we can express a limit that is higher than we expect
             to see

  matthieudubet: Should we define how we would fail?
  matthieudubet: support until some depth?
  TabAtkins: Sometimes we do and sometimes not
  TabAtkins: in this case might make sense to ignore rules that were
             nested too deeply
  fantasai: If we do a limit on depth, we might all want to have the
            same limit across vendors
  fantasai: we need to have a min depth that is sufficient for authors
  <fantasai> Losing a few rules that are just past the limit in some
             browsers but not others would be a problem that could
             really break things
  <fantasai> So we should have interop on nesting depth support if
             it's not something so far beyond what authors would use
             that no one will run into it

  plinss: +1 on limit consistency
  plinss: Concerned about when authors hit it: are they gonna know?
  plinss: Also concerned about performance impact when we have a
          reasonable limit. Limit can be ??? than we have right now
  plinss: Other issue - don't want to derail - but might make
          explosion problem worse so will keep for later
  Rossen: Please introduce
  plinss: When the parent rule has commas with multiple lists, the
          nested rule is prewrapped in :is() and that breaks the
          cascade
  astearns: There is an issue for that
  emilio: I don't understand
  <bkardell> thought :matches?
  TabAtkins: :is() doesn't reflect specificity
  plinss: I expect two rules that are nested cascade with different
          specificity level, with :is() you don't have that
  plinss: explosion is worse than we think it is, if we fix that
  <fremy> I don't have that expectation, personally

  emilio: I'm ok with a limit
  emilio: I don't think a max should be specced
  Rossen: That is what Tab suggested
  Rossen: We did something similar for units way back
  TabAtkins: But Elika was saying we should spec a max
  fantasai: If the limit is something low, then it is reasonable
            authors will hit that.
  fantasai: some browsers might then drop rules
  Rossen: No, this is about a lower limit
  fantasai: If the upper limit is far enough – e.g. 100 – only some
            test cases or auto-generated stuff might hit it,
            then it's ok to not be interoperable
  fantasai: This proposal is that min is 10, but that would mean max
            should also be 10
  fantasai: Min should therefore be far enough to not cause interop
            problem
  emilio: We don't have limit of length of selectors.
  emilio: It all depends on what you are nesting
  emilio: Single selectors nesting is probably fine
  emilio: If you nest lists of 100 selectors each, that might blow up
          soon

  fremy: Nesting limit does not seem the right metric
  fremy: Correct midway is to see how much selectors you end up with
  fremy: e.g. you can have up to 256 if it is expanded
  fremy: Better to limit total num of selectors
  TabAtkins: Won't work
  TabAtkins: At least in blink, if you take oriol's example and wrap
             it in :is(), you still have a problem
  TabAtkins: It is combinatorial in some more ephemeral notion of
             complexity that I do not want to define
  fremy: That is different
  fremy: if you put in :is() you only have complexity in running the
         code, not storing it
  TabAtkins: Blinks performance is the same for with as without
  TabAtkins: reason we have 10s recompute here is based on something
             more intrinsic about complexity of the selector, not the
             length of the list
  TabAtkins: a expanded selector here is still 125.
  TabAtkins: Complexity here is not something we can easily define in
             terms of any selector metric

  matthieudubet: If you count list inside of parent list, the time is
                 linear to.
  matthieudubet: (missed)
  matthieudubet: limit I am suggesting should be related to length
  TabAtkins: webkit will delay for longer than 10s right now. chrome
             and firefox have similar timings
  TabAtkins: but also def of 'what things to expand' is already a
             number of things: :is(), :where(), :nth-child() with 'of'
  matthieudubet: Yes, it is more complex that depth

  matthieudubet: depth limit of 10 might not be enough
  TabAtkins: 10 is more then enough for virtually all cases (based on
             sass survey)
  TabAtkins: somebody might go over, but in people tend to stick below
             that
  <bkardell> that doesn't really jive with what I have seen, can we
             confirm it? How?
  ntim: I can see limit of 10 being too low, e.g. in build systems
  myles: What are the current limits?
  TabAtkins: None, there is no spec limit.
  florian: In implementations, they run out of memory or crash
  emilio: Yeah
  nsull: can we get data from sass (or some other party) about the
         number of nesting authors do?
  <bkardell> +1
  miriam: sass does not track that
  miriam: people nested really deep at the start, but best practice
          now is 3 but people don't always follow that
  <bkardell> surely we can grep github for scss stuff
  miriam: web archive might have data on that
  nsull: Interesting. What is average selector length?
  <bkardell> ah yeah, good call...
  Rossen: If we don't have the data, we should explore that offline

  myles: Seems like the limits are purely mechanical
  myles: Why is this different than things like total number of nodes
         or nested iframes?
  TabAtkins: There is a reason why you would want to limit here
  TabAtkins: If quantity is roughly linear with amount of stuff in the
             page it might be ok
  TabAtkins: but if its exponential we are concerned about it
  TabAtkins: We have a limit in variables for example
  TabAtkins: to prevent doubling in 30 stages before going OOM
  TabAtkins: this falls in similar case. You don't want people to be
             able to crash a page by writing a crazy selector
  myles: I understand this is easier here, than a bunch of nested
         iframes
  myles: reason other limits are not standard is because people will
         not hit them
  myles: Are you, Tab, saying that reason that limit is needed here
         because we expect people to make real pages and hit it?
  TabAtkins: Potentially. 3rd party CSS could DOS your page, which is
             not ideal
  <nicole> myles said there are limits on DOM size or number of nested
           iframes that aren't standardized because they are high
           enough authors don't hit them

  bkardell: 3rd party thing is a little bit tricky
  bkardell: because 3rd party stuff could ruin the whole internet
  <TabAtkins> I don't mean "a professional company giving 3rd party
              style", I mean "user-controlled"
  bkardell: I have not seen a ton of sass, but can say that in the
            stuff I have seen like 4-6 depths is what was there
  bkardell: am happy to help look up the actual numbers
  TabAtkins: We do want to have a min limit so that users have an
             expectation of what is usable.
  TabAtkins: in case of browser limits get cut low
  TabAtkins: We rarely put a max limit
  TabAtkins: but proposed resolution is to add a min limit
  TabAtkins: It seems like a moderately excessive depth to support
  TabAtkins: authors might run into a cutoff after that, and UAs
             should make sure pages remain responsive in that case

  Rossen: We seem to be circling back
  florian: For max limit, they can then choose some metric they want,
           not necessarily depth
  florian: Are browsers likely to create a limit that authors might
           hit? If not, setting a minimum around 10 isn't going to
           constrain anyone
  florian: We can also say a limit is implementation defined
  TabAtkins: Analogous situation is size of grids, where we knew that
             relatively large grids were larger than the limit we had
  TabAtkins: I am fine with saying it is implementation defined
  <astearns> implementation-defined and wait for bugs to come in?
  TabAtkins: Authors must in that case not do stupid stuff
  TabAtkins: so I am happy with close no change
  TabAtkins: Currently there is nothing in the spec about it

  fremy: Quick idea: in the example you can get to 7mo selectors. Can
         we compute the length of the selectors like string length and
         compute product of that and cut off at a limit?
  fremy: To prevent exponential scenarios
  TabAtkins: I don't want to get into that complexity bag, and let
             implementations figure it out
  fremy: I am proposing to use the actual string length of a selector
  fremy: without considering how complex it is
  fremy: e.g. 1000 chars
  TabAtkins: Problem case here can be constructed in a few 100 chars

  plinss: If we allow implementers to choose a limit, then we must set
          a minimum and have some advice to authors about that
  plinss: to prevent interop issues

  TabAtkins: 2 proposals:
  TabAtkins: - close no change
  TabAtkins: - or a depth specified min
  myles: and a third to pick 10?
  TabAtkins: that is option 2
  Rossen: we seem to come back to option 2
  <SebastianZ> I'd vote for option 2.

  fremy: Based on Tab's remarks option 2 makes no sense? with just
         adding :is() you can get the same complexity in a normal
         selector, so why limit depth in nesting?
  Rossen: That is separate issue, no?
  fremy: It is not
  astearns: But maybe we should
  TabAtkins: It is not just :is(), :is(), :nth-child(), :where()
  florian: Given that this is a case, should we do nothing nowhere?
  fremy: That is my point. I'd rather go with option 1 than 2, as you
         can do it somewhere else
  <fremy> +1 on Rossen proposal to add a recommendation for nesting
          depth
  Rossen: (goes over options again) but happy to go with 1
  plinss: I don't see point in author guidance about exceeding a max,
          when there is no min in spec
  <TabAtkins> Interestingly, if you take Oriol's example, wrap each
              selector in an :is(), then collapse away the nesting to
              make it a single selector with the same behavior, we get
              substantially faster performance in chrome
  <TabAtkins> (~0.8s on my laptop, vs 13s for the nested version)

  Rossen: (missed)
  Rossen: I appreciate the pushback, but don't see how any author
          guidance for that logic could turn into formal vendor reqs
  plinss: If we don't have min and give author guidance, that number
          is fiction
  <fantasai> +1 plinss
  Rossen: Perhaps for some browser on some platform
  plinss: Then spec it as min
  TabAtkins: Even if we consider that even a small depth might trigger
             same problem. Not certain if that is case or not. There
             might not be any reasonable metric to use, but reasonable
             author behavior with some guideline will keep people in
             bright space of good perf.
  TabAtkins: Trying to lay down a strict limit might not give us the
             guarantee of good perf
  TabAtkins: so “you should think about >” might be a good thing
  <fremy> @ TabAtkins, if the :is() is faster, then your original
          intuition about the slow down root cause might not be
          correct, so the issue might not be related to the number of
          selectors
  <fremy> @ TabAtkins, I guess maybe we should investigate a bit more
  <TabAtkins> right, I'm wondering if it's just something about the
              length of the nesting entirely

  SebastianZ: I think a min limit would be good, but
  SebastianZ: it is not limited to nesting but also selector
              complexity so maybe selector spec should also mention
              that?
  TabAtkins: Yeah
  SebastianZ: If we can come up with a metric, it should be in the
              selector spec

  emilio: Since this is related
  emilio: Same case in variable, and vendors have different limits
  emilio: string based, token based, …
  emilio: It don't think limit is easy to define
  emilio: perf is based on impl details
  emilio: complexity depends on whether elements match too
  emilio: I would want to leave this undefined until we have decent
          understanding of these performance characteristics
  <plinss> +1 emilio
  Rossen: By undefined you mean explicitly undefined?
  emilio: Yes
  <nicole> +1 emilio
  florian: I agree, but also give authors some guidance as well, but
           not in terms of max levels, since that's the wrong metric.
           Rather: "be mindful of combinatorial explosions. For
           instance {this example} crashes browsers. Don't do this
  <fremy> +1

  matthieudubet: As Tab said, it does not depend on depth but length
                 of selector which is easy to define
  matthieudubet: that are the limits we are hitting. not depth, length
                 of selector
  TabAtkins: A quick test case shows it is not the case
  TabAtkins: e.g. 25 :is() is slow
  matthieudubet: I agree it might be too complex to put into a spec

  nsull: Agree with emilio and myles
  nsull: We don't know how devs will use this
  nsull: Making up guidance now seems too premature
  nsull: so I support option 1, and see what actually breaks now
  nsull: and we might revisit guidance later
  myles: I was not stating, but asking for clarification

  <TabAtkins> Also I misremembered, Variables does *not* impose an
              explicit limit, it just calls this out as an impl issue.

  Rossen: Seems like there is enough support for option 1 to keep it
          explicitly undefined
  Rossen: It is important that impls not crash though
  Rossen: Can we resolve?
  plinss: Small objection, as option 1 was 'close no change' and wait
          for data
  TabAtkins: I am fine with 'close no change' without prejudice
  TabAtkins: until we hit a problem in the future

  ntim: We need to figure out how nesting is used in the wild
  Rossen: So are you signing up?
  ntim: No
  TabAtkins: Bug trackers will find the data, and then we can file a
             new issue based on that
  <florian> +1
  TabAtkins: Until we have practical proof, we don't need to hold this
             open
  iank: We had a limit for grid tracks, and we received a bunch of
        bugs for it. so people file them
  ntim: To prevent interop issues, we need the data
  TabAtkins: And the bug reports will surface that

  <bkardell> Can I ask for one clarification? Is option #1 also put no
             author guidance/information about preventing problems
             into the spec?
  <bkardell> Rossen: ^ can we clarify that?
  <TabAtkins> this issue has no bearing on author guidance in the spec
  <TabAtkins> I'll put some in.

  Rossen: Let's close here
  Rossen: Do we want to resolve on 1: explicitly define that the limit
          is (pause) undefined
  <bkardell> if tab will put some explanation in, I can +1 on option 1
  <TabAtkins> I'll put in some guidance similar to this
              https://drafts.csswg.org/css-variables/#long-variables
  Rossen: Objections?
  plinss: No
  Rossen: Explicitly undefined as in “no limit”
  plinss: We will have answer when research is done
  Rossen: Objections?
  florian: Saying explicitly that there is no limit, you require ???
  TabAtkins: No, not 'no limit' but undefined
  TabAtkins proposed resolution: nesting limit is UA defined
  <TabAtkins> proposed resolution: limits on nesting is ua-defined

  RESOLVED: limits on nesting is ua-defined

Is it OK for nesting to reorder declarations?
---------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/8738

  emilio: Right now in nesting, when you have mixed declarations and
          nested rules, the current behavior of nesting (and sass?) is
          to pull all the declarations up which may feel a bit weird
          if you don't know this happens
  emilio: the source order changes
  emilio: don't know where we ended up in this discussion
  emilio: but I think it is unfortunate
  emilio: if people are fine with no change, so am I
  Rossen: Tab’s last comments were suggesting that
  TabAtkins: Yes

  Rossen: Remarks?
  fremy: Thank you emilio for filing.
  fremy: Would love if we could fix this but understand that
         implementations are shipped

  fantasai: I think this is very confusing. On the plus side it is not
            common authors will do this, where they have the same
            specificity as the ??? and they are modifying the same
            property. So authors will not commonly run into this
  fantasai: However, when they do, the fact that it applies out of order
            is very confusing
  fantasai: We don't have to have this problem
  fantasai: In terms of options, we can say that when you are
            interleaving, you have to make additional ampersand rules
            to have them maintain their position
  fantasai: Seems straightforward but are concerned that we should fix
            the cascade because it is confusing

  TabAtkins: Main argument for no change is that this behavior is the
             same as what preprocessors do since they supported it
  TabAtkins: It has not been a problem for any of them as far as we
             can tell
  TabAtkins: for sass we have a maintainer confirming that
  TabAtkins: so we don't need to worry about it I think
  TabAtkins: It is not an issue in practice, so we should not come up
             with complicated solution
  TabAtkins: MQs and non-style rules have a different behavior when
             nested than style rules are
  TabAtkins: style rules put all their props in the style as if it
             were up front
  TabAtkins: and MQs in similar put all their ?? in nested style rules
  TabAtkins: We could run into the issue that knowing when nesting has
             begun depends on non; it is not intuitive what to define
             well when we have started nested
  TabAtkins: A rule that is unknown or mis-typed can change that
             interpretation
  TabAtkins: in an unpredictable way
  TabAtkins: to keep consistent behavior lets avoid that problem
             entirely, and data from preprocessors has shown it is not
             a problem

  fremy: The last argument seems valid
  fremy: The examples emilio gave is not about nesting selectors but
         nesting an at-media rule, which I can do
  fremy: I feel example is convincing enough
  fremy: is implementation of sass/less supporting this use case?
  fremy: If they don't, then we are making things quite ???
  TabAtkins: Yes, I believe they do
  TabAtkins: throw it into a sass playground and it will output the
             equivalent compiled code with media shifted out
  TabAtkins: the two decls will be combined together
  fremy: In this case I don't feel strongly enough that we should

  emilio: So fixing interleaved decls inside a grouping rule by
          wrapping in &-rule is easy
  emilio: fixing style rules by adding nested style rules is not too
          hard but … I guess we could fix it
  emilio: Don't feel too strongly either way
  <TabAtkins> yup, today emilio's examples compiles to "the div with
              both properties, followed by the @media holding a div
              holding the conditional props"
  Rossen: so then the proposed resolution is to close no change

  fremy: Did anybody look into Lea Verou’s comment?
  Rossen: We did

  jensimmons: We do not like the proposed resolution. It does not make
              sense for authors right now. They expect for the later
              styles to apply
  jensimmons: I agree that a non-complicated thing is a goal, but
              should not be what we have now
  jensimmons: sass is a guiding principle, but we should follow how
              CSS has always worked: source order
  <ntim> +1
  jensimmons: ntim has a proposal
  <miriam> Here's the example in a Sass playground, for reference
           (sorry it's a long url):
           https://sass-lang.com/playground/#MTFkaXYlMjAlN0IlMEElMjAlMjBjb2xvciUzQSUyMGdyZWVuJTNCJTBBJTIwJTIwJTQwbWVkaWElMjAod2lkdGglMjAlM0UlMjAwKSUyMCU3QiUwQSUyMCUyMCUyMCUyMGNvbG9yJTNBJTIwcmVkJTNCJTBBJTIwJTIwJTIwJTIwYmFja2dyb3VuZCUzQSUyMHJlZCUzQiUwQSUyMCUyMCU3RCUwQSUyMCUyMGJhY2tncm91bmQlM0ElMjBncmVlbiUzQiUwQSU3RA==
  ntim: emilio wrote it in the issue : wrapping in &
  astearns: Just for my clarification: that solution will allow later
            rule to override the earlier ones?
  [multiple]: Yes

  plinss: I presume for wrapping ??? in another declaration block it
          becomes another rule in the OM?
  TabAtkins: Yes
  plinss: Is the & still required these days?
  TabAtkins: Yes, you need a selector
  TabAtkins: In terms of raw css syntax parsing, omitting the selector
             will give you a rule with empty prelude and that will
             fail to parse as valid style rule
  TabAtkins: Further issue as explained in thread. anything we do that
             distinguished behavior on before/after nested rule means
             we have to define the switch for 'we are past a nested
             rule'
  TabAtkins: Can't be ??? to cause the syntax trigger

  TabAtkins: We don't need that concept if we don't do this
  TabAtkins: It will potentially change the cascade
  emilio: Why would you have problem to just use valid nested rule as
          trigger?
  TabAtkins: Because a new rule that does not exist in older browser
             that understands nesting will throw away that new rule
             and conclude that nesting hasn't started yet
  emilio: And the declarations will ?? and that seems fine

  TabAtkins: And the OM changes
  emilio: ????
  emilio: Like the OM changes, but it also changes when you introduce
          new rules.
  emilio: you end up with different length list
  fantasai: If we have style rule with interleaved rules and
            declarations. Lets say 3 decls at top, at-rule, and 2 decl
            at bottom
  fantasai: old browser will have 5 decls appear in .style of that
            stylerule
  fantasai: if we wrap it in an :is() rule then in a new browser you
            would get first 3 decls in .style. then at-media in
            .cssRules followed by - followed in it - a new style rule
            with last 2 decls
  TabAtkins: Not, but that is closely related.
  <TabAtkins> specifically, `::before { & {color: red;}}` does *not*
              apply red to ::before in today's spec
  <TabAtkins> and causing implicit wrapping would trigger that problem
              as well

scribe: dbaron

  oriol: About wrapping decls in an &: with two elements, the & can't
         represent 2 elements. If you have a declaration, garbage, and
         a declaration -- if later a new feature parses the garbage as
         a nested rule, then the following declaration would be
         grabbed and not work.
  oriol: While I agree the current behavior is not great, and would be
         a good argument for choosing option 4, I'm leaning more
         towards what tab is saying -- keeping current behavior
  TabAtkins: I forgot about that -- I agree that kills it harder. You
             can't nest if your parent rule has pseudo-elements.
             That's the behavior of :is(). If you tried to do this and
             parent selector applied styles to pseudo-elements, the
             implicit wrapping would just drop these declarations on
             the floor. That's broken at a fundamental model level
             right now.
  plinss: That goes away if we get rid of the :is() behavior, right?
  TabAtkins: Yes
  TabAtkins: My proposed resolution is still to close with no change;
             I think current spec is right.
  TabAtkins: but we should see if objection from Apple is still
             standing

  ntim: I wonder if we can translate to a ? rule without using &, just
        using the selector text.
  <ntim> div { color: green; } @media (width > 0) { div { color: red;
         background: red; } } div { background: green }
  TabAtkins: No, because that's a relative selector
  TabAtkins: Those nested rules are "div div"; it's still relative to
             the parent rule
  hober: Siblings, not nested
  myles: There's 3 sibling rules in that example
  TabAtkins: That would mean treating nesting as a preprocessor
             directive that rewrites into a different rule structure
  TabAtkins: We haven't been pursuing that approach since very early
             on in nesting. I'd like to reject trying to rewrite style
             things. That makes many things more complicated, like for
             how @media nesting works in rules. But the more we
             diverge the OM and the model underneath from the syntax
             authors write, the worse it is.

  fantasai: I think I'm not comfortable resolving on no change -- it
            doesn't sound like we have consensus -- but we don't have
            a clear counter proposal worked out. I think TabAtkins
            brought up many useful concerns with emilio's path. We
            should take some time outside the meeting to review
            minutes and try to think through the possibilities. Might
            be down to these 2, but maybe something else. And see if
            we can address relevant concerns, or at least have a better
            understanding of what they are
  <jensimmons> +1 to what Elika just said
  TabAtkins: If you think it's valuable to more exploration, you're
             welcome to. I don't think it's going to work, but you're
             welcome to.
  fantasai: Sounds like there's an action item for people with
            concerns about current proposal to come up with a counter
            proposal.
  Rossen: No rule that we can't reopen issues.
  fantasai: I object to resolving when this many people don't like the
            direction.
  TabAtkins: As long as it's not a drastic change (like turning it
             into a rewriting rule), unlikely there will be compat
             concerns if it changes relatively soon, given that this
             is a rare code pattern. But not indefinitely, and
             limitations on how far that reaches.
  Rossen: So let's move on to the next issue. And once Apple or anyone
          else has a better proposal, bring it back.
  <astearns> fwiw I have already seen authoring advice against mixing
             rules and declarations this way, so if people follow that
             advice it lessens the compat concerns

Received on Sunday, 10 September 2023 15:23:28 UTC