[CSSWG] Minutes Telecon 2024-10-23 [css-pseudo][css-cascade][resize-observer]

=========================================
  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 Pseudo
----------

  - RESOLVED: Propagation of text-box-trim from ancestor of multicol
              works the same as propagation from multicol itself (Issue
              #11038: Should the "first formatted line" propagate into
              a different BFC?)

CSS Cascade
-----------

  - Performance was no longer a concern for the proposal in issue
      #10795 (Should the scope proximity calculation be impacted by
      nesting scopes?), however the use cases still weren't clear to
      everyone in the group. Discussion will return to github to
      clarify.
  - RESOLVED: Reject option 1 [Provide a name to the 'un-layered layer'
              so that it can be placed in the layer order like any
              other layer.] (Issue #6323: Allow authors to explicitly
              place unlayered styles in the cascade layer order)

Resize Observer
---------------

  - RESOLVED: ResizeObserver uses the "current" global document (Issue
              #10516: It is unclear which Document object
              https://drafts.csswg.org/resize-observer/#ref-for-resizeobserver
              is talking about)

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

Agenda: https://lists.w3.org/Archives/Public/www-style/2024Oct/0009.html

Present:
  Rachel Andrew
  Tab Atkins-Bittner
  Kevin Babbitt
  David Baron
  Stephen Chenney
  Keith Cirkel
  Emilio Cobos Álvarez
  Yehonatan Daniv
  Stephanie Eckles
  Elika Etemad
  Robert Flack
  Simon Fraser
  Paul Grenier
  Chris Harrelson
  Anders Hartvoll Ruud
  Daniel Holbert
  Jonathan Kew
  Roman Komarov
  Alison Maher
  Romain Menke
  Cassondra Roberts
  Noam Rosenthal
  Alan Stearns
  Miriam Suzanne
  Josh Tumath
  Bramus Van Damme

Regrets:
  Gaurav Singh Faujdar
  Sebastian Zartner

Scribe: TabAtkins

CSS Pseudo
==========

Should the "first formatted line" propagate into a different BFC?
-----------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/11038

  fantasai: Interesting questions here are, what do we think about the
            current dfn and behavior, and what the use-cases are?
  fantasai: for example, if someone sets article::first-line
            { text-transform: uppercase }, what would they expect it to
            apply to
  fantasai: The answer might be different for first-line and
            text-box-trim
  fantasai: I think impl-wise they can do whatever we think makes sense
  fantasai: A bunch of these didn't get propagated in the past because,
            as Oriol points out, tables didn't accept ::first-line/
            letter propagation
  fantasai: and that was extended to Grid and Flex too. But we do
            propagate into other BFCs

  fantasai: So first question we have is, what use-cases do we have for
            propagation, and what dfn would make the most sense for it?
  astearns: Does anyone know if Koji has an opinion, since they brought
            it up?
  fantasai: Don't think Koji has a strong opinion, just wants it
            defined clearly
  fantasai: We can defer if people have a good reason, I just don't
            want to pick an arbitrary reason

  dbaron: In some cases propagating is more difficult, so it would be
          good to have some justification in terms of use-cases before
          we decide to do it
  dbaron: but don't remember what the UA divergence is
  fantasai: Some propagation into BFCs and multicol, but nobody into
            other formatting contexts
  fantasai: Current spec requires BFC and multicol

  astearns: We could add more rigor to that dfn saying we require it
            for BFC and multicol, and shouldn't propagate anywhere else?
  astearns: I see the argument that if it doesn't make sense for
            tables, it probably doesn't for flex/grid either
  <TabAtkins> Agreed wrt tables and flex/grid
  fantasai: I believe the spec in Pseudo 4 is clear, I'll double check
  <fantasai> https://drafts.csswg.org/css-pseudo-4/#first-text-line
  <emilio> I have a slight preference to not propagate to other BFCs
           either fwiw
  fantasai: Yeah, specifies only block containers and multicol
  astearns: So should we leave it at that and close no change? or do
            you want to go back to the issue to search for use-cases
            that would justify amending the spec?
  fantasai: Trimming currently requires first formatted line; trimming
            in the first line of a multicol and not subsequent is maybe
            a little weird
  fantasai: It's currently a little unclear for multicol because we
            resolved it should apply to all columns if you set trim on
            the multicol itself
  fantasai: and propagation also considers what happens if you set on
            an ancestor
  fantasai: but that currently only affects the first line in the
            multicol
  fantasai: So I guess we could leave ::first-line/letter, and consider
            the text-box-trim propagation wrt multicol

  emilio: iirc, Gecko didn't propagate across BFCs
  emilio: other browsers don't inherit quite right when they propagate,
          which is weird.
  emilio: Think there's just impl bugs across the board
  emilio: I have a slight preference for not propagating, because it
          seems harder to get wrong
  <TabAtkins> Note we now have ::column pseudo for some special cases,
              if that might be helpful

  dbaron: I think some of the complexity I was referring to was
          specifically first-line/letter, which are really complicated
  dbaron: If there are text-box-trim cases that'll be solved from it
          propagating more, maybe we can just fix that rather than
          change all three
  astearns: Yes, don't see a real need to keep them consistent
  fantasai: Yeah, was just a spec editing convenience
  fantasai: So my suggestion is to make no change to ::first-line/
            letter (though we could come back if we needed to). For
            text-box-trim, because it propagates to columns of a
            multicol, if set on an ancestor it should similarly
            propagate when it hits the multicol
  astearns: Makes sense to me
  astearns: Is there any different handling we should do for flex/grid?
  fantasai: Currently we don't trim them. Might be simplest, we don't
            actually know if the flex/grid will coincide with the top
            of the container
  fantasai: due to alignment/etc
  fantasai: It's pretty understandable to authors, I think, that it
            doesn't propagate into flex/grid/tables
  fantasai: The difference between a BFC root and a normal BFC is a
            little subtle, and can be triggered by accident
  fantasai: so I think it makes sense for the behavior to be more
            transparent there
  astearns: Ok so let's take a resolution on just multicol+text-box-trim

  PROPOSED: propagation of text-box-trim from ancestor of multicol
            works the same as propagation from multicol itself
  <florian> +1
  astearns: objections?

  RESOLVED: Propagation of text-box-trim from ancestor of multicol
            works the same as propagation from multicol itself

CSS Cascade
===========

Should the scope proximity calculation be impacted by nesting scopes?
---------------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/10795

  miriam: Scopes add "proximity" to the cascade, which is the number of
          elements between the element and the scope root. Closer
          proximity wins when there's a specificity tie
  miriam: The only use-cases we've seen rely on just that final step
  miriam: Rather, author's interest seems to be mostly in just that
          final step, nested scopes seem difficult to track impl wise
          and Anders suggests it's a perf issue too
  miriam: matthieud was suggesting we could maybe have *some* way to
          tracking nested scopes
  miriam: A proposal is a number that is the proximity distance, and
          number of scopes as a tiebreaker
  miriam: I'd be happy with either leaving as is, or just going with
          scope count

  andruud: The original proposal in the issue was a dynamic cascade
           criteria for proximity; I was really worried about the perf
  andruud: It wasn't as bad as I thought. Was still some perf
           regression though.
  andruud: So I still think that *if* we make a change, we should go
           with the alternate proposal (just the count of scopes)
  andruud: Simpler for impl, and I think simpler for authors to
           understand

  fantasai: I looked at the proposal; I had a question.
  fantasai: How sure are we that want to index only on the last scope
            proximity
  fantasai: Would it make sense to consider which of the scopes is the
            "highest ranking"?
  fantasai: I could imagine, depending on your stylesheet structure,
            one or the other would be more important
  miriam: Would the importance be marked in some way?
  fantasai: I dunno, could be an interesting question
  fantasai: For the proximity distance, considering the strongest
            rather than last could make sense here
  <romain> having a scope-end makes it more important, in a way
  <romain> having both a scope-start and scope-end vs. only having a
           scope-start
  andruud: We're talking about nested scopes here. So isn't the
           innermost scope always closer to the subject than the outer
           scopes?
  miriam: Yes.
  miriam: The only way you'd change that is if you were measuring the
          distance between the scopes, but I don't know that that's
          useful
  matthieud: That's the same as counting from the subjects, yeah

  andruud: The cascade is already really complex altogether, so I'd
           like to keep it as simple as possible
  <bramus> +1
  miriam: I tend to agree
  <TabAtkins> +1, as simple as possible (but no simpler)
  miriam: Definitely use-cases for measuring to nearest scope. Maybe
          some cases for measuring to nested scopes, but not really
          common, and not sure where it's where proximity is most useful
  emilio: Was gonna bring same point as fantasai
  emilio: Accounting only for proximity of the closest feels a little
          weird
  emilio: leans me towards preferring no change if this isn't super
          useful
  emilio: You can get this sort of tied behavior by using nested
          selector
  emilio: using the & can pull in the specificity of the scope root
  <noamr> +1 to not adding implicit cascade rules on top of the
          existing ones
  fantasai: The trick would be to come up with realistic examples where
            you're nesting scopes and caring about the proximity of each
  fantasai: The canonical example of proximity is the light/dark
            switch, where you want to style based on which is the
            closest ancestor rather than stylesheet ordering
  fantasai: and if you combine that with other aspects that you might
            want -- let's say you had a "zoom" switch as well
  miriam: Generally in that case they'll be written as separate scopes,
          not nested scopes
  emilio: If you were to nest them, the behavior would be extremely
          confusing
  <TabAtkins> I'm pretty strong on the side of "it would be extremely
              confusing" even if there is a use-case

  matthieud: First question is about usage
  matthieud: Seems we don't have an idea even about the usage of nested
             scope itself
  matthieud: Should we forbid nested scope altogether?
  matthieud: Second, about impl. Anders, not sure if it's very
             different from current impl.
  matthieud: Seems linear to the number of scopes
  matthieud: Haven't done the impl but doesn't seem particularly
             complex. And perf concern seems only to be about nested
             scopes, flat scopes seems fine
  <andruud> No
  emilio: The main problem is that this makes things that the cascade
          depends on dynamically sized, which means you need at least
          an extra pointer somewhere
  emilio: And that's extremely hot code
  emilio: so it's not the perf of looking for the scopes (agreed you
          already need to look through them), it's about storing the
          list of applicable decl blocks
  emilio: If you have those along with cascade order, you have to grow
          them, and it grows unconditionally regardless of whether you
          use it, it causes cache misses, etc
  matthieud: Okay if you always have an integer for scope I see it. Our
             impl always has a pointer
  emilio: Right, for us making it a pointer would be a perf regression
          just going in
  emilio: so if it's mostly a theoretical purity thing we could avoid
          the perf hacks
  andruud: I'll say again that perf *would* be acceptable if you *did*
           want to do it that way. I thought it would be terrible, but
           it's merely uncomfortable. Doable if *needed*, I just don't
           want to.

  miriam: Responding to first part about disallowing nested
  miriam: I don't think so
  miriam: I know the reasons for nesting scopes - to narrow in on a
          selector
  miriam: I haven't seen a use-case where that changes what proximity
          is doing
  miriam: so to me I don't see it as necessary that that effects in
          some strong way
  miriam: And the risk to disallowing entirely is, we'd have to remove
          scoping stylesheets, which we currently have on @import
  <TabAtkins> I think the use-case for nested scopes is clear.
  <TabAtkins> @scope my-component { @scope light {...}}
  fantasai: So the question is what use-cases are there for nesting
            scopes
  fantasai: Would it make sense to have a blog post to collect feedback
            on this to get examples?
  <fantasai> https://github.com/w3c/csswg-drafts/issues/8380#issuecomment-1450475188
  <fantasai> @scope (A) {
  <fantasai> @scope (B) {
  <fantasai> X { color: blue }
  <fantasai> }
  <fantasai> X { color: yellow }
  fantasai: this is the previous issue we had on the topic
  fantasai: I'd expect blue to always win inside the B scope
  TabAtkins: yellow would win if you have A inside B inside A
  <emilio> <A><B><A><X>
  fantasai: So there's definitely some confusing stuff that happens
            when taking the outermost
  fantasai: Dunno if we can resolve the confusion
  <TabAtkins> (I think it getting yellow in this case is probably the
              intended behavior, fwiw.)

  fantasai: What behavior they expect is an interesting thing. Probably
            next step is to have a blog post on the CSSWG blog
  astearns: miriam says we already know why people nest scopes though
  miriam: It would be the similar reason for nesting in general - "I
          want to drill down"
  miriam: Often, I've written a scope, but I only want to apply it in a
          certain place.
  fantasai: I think it's clear that people will use nested scopes. The
            proximity part is the - what would they use the proximity
            for rather than just the limiting part of the scope
  emilio: I can't think of any case where you'd nest a scope, but then
          - that weird situation where you have a lone thing you expect
          to be inside is outside
  emilio: I agree with fantasai that we should reach out about this
  emilio: I don't think there's much @scope in the wild, but we could
          check httparchive
  emilio: so I don't think I could come up with a use-case that would
          intentionally break, feels weird to do

  keithamus: A common thing I see in preprocessors is to drop in an
             @include, which might be a whole block of CSS including
             scoped CSS
  keithamus: I have no concept about what that might change, just
             throwing out an example. Possibly just accidental that it
             happens, but it could be a way for nested scopes to happen
  fantasai: Yeah, that's an interesting question. if you have an outer
            @scope, and you drop rules in, and you expect rules in the
            scope to defeat things with a weaker proximity
  fantasai: First block of @scope is 10 proximity, next is 6. Then
            inside it, we have another rule with an @scope... [missed
            example]
  miriam: Remember that no block has a score, it comes from the dom
  fantasai: I dunno I'm confused
  <noamr> IMO we should leave score around imports to layers rather
          than add all kinds of default behavior around this
  <TabAtkins> Agreed, noamr
  emilio: So it's not true that the inner scope is always the most
          relevant for the comparison

  stepheckles: Just thinking through scenarios where someone would nest
  stepheckles: Imagine they're nesting just because it's now available
  stepheckles: Some authors might miss the part where @scope doesn't
               add specificity
  stepheckles: Adding that detail might be useful when asking for
               details

  astearns: So let's take this back to the issue and bring it back when
            we have more clarity/examples

  miriam: emilio, I didn't catch what you were referring to when you
          were saying inner scope wasn't always most relevant
  emilio: In the A-B-A-X case
  miriam: Right, that's the point I was making, it's not the innermost
          *rule*, it's the nearest scope root
  <TabAtkins> (Yes, that's the proximity we use in the spec)

Resize Observer
===============

It is unclear which Document object
    https://drafts.csswg.org/resize-observer/#ref-for-resizeobserver
    is talking about
--------------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/10516

  emilio: resizeObserver spec doesn't define, when you create an
          observer, what Document you add it to.
  emilio: That can be different if you do something like
          iframe.contentWindow.ResizeObserver
  <chrishtr> +1
  emilio: I think from code comments blink and gecko both use "current"
          global; I think webkit too. We should spec that.

  TabAtkins: Remind me which is "current"?
  emilio: In this case, the iframe
  emilio: The "relevant global" from the ResizeObserver object

  <astearns> https://html.spec.whatwg.org/multipage/webappapis.html#concept-current-everything
  astearns: You linked to "current" in your comment
  astearns: So I assume you mean *that* current, not "relevant" that
            follows it
  emilio: So "relevant" you need an object already. I think it needs to
          be "current", which would be the iframe document in this
          case, even if the script is from the outer page

  smfr: Is this different from IntersectionObserver? Can they be
        specced the same way?
  emilio: They should definitely be consistent, I think IO already uses
          current
  emilio: I'll check
  astearns: We could resolve to spec what current engines do, and make
            it consistent with IO
  emilio: Ah, I have an issue on IO spec, because it depends on what
          you observe, per spec, which isn't great
  emilio: I'll crosslink in the issue
  emilio: but wekbit and gecko do use the same concept
  astearns: And you're sure what the concept is?
  emilio: I'm 90% it's "current"
  emilio: The realm that the function you're calling lives in
  astearns: So we can resolve to define that both RO and IO use
            "current" global document, as long as that reflects reality
  emilio: Sounds good
  <TabAtkins> might not match blink's IO behavior
  chrishtr: I'll follow up with Stephan about IO
  astearns: Objections?

  RESOLVED: ResizeObserver uses the "current" global document

CSS Cascade (con't)
===================

Allow authors to explicitly place unlayered styles in the cascade
    layer order
-----------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/6323

  miriam: Since we introduced layers, we intentionally made them weaker
          than unlayered styles
  miriam: This is useful for importing third-party code, if they use
          layers you should be able to determine if they override you
          or not
  miriam: but authors would like a way to be more explicit, there are
          some cases where it would be helpful to import unlayered and
          override them
  miriam: There are cases where you're getting styles from a third
          party that you can't layer
  miriam: Difficult to solve. Three approaches that have come up in
          various forms
  miriam: If we could at least narrow on the approach we could bikeshed
          the syntax

  miriam: 1) somehow say in your layer ordering, give a special name to
          the unlayered styles and let you put it in yourself
  miriam: Conceptually simplest, but now different stylesheets can
          disagree about position. once you set it once, later things
          can't move it around. so styles can't place themselves in
          relation.
  miriam: think we should take it off the table

  miriam: Other two are variants
  miriam: 2) with each layer, say whether it's above or below the
          unlayered styles
  miriam: Ideally make that clear in the layer name itself
  miriam: maybe a !
  miriam: Downside is now we're tracking two layer lists separately, a
          little complicated mentally
  miriam: maybe also impl complicated, unsure
  <bramus> I like to call these “strong layers”
  miriam: 3) simplification of that, one named layer that's above and
          you can add sublayers to that
  miriam: call it !top or something, you can write `@layer !top
          { @layer my-foo {...}}`
  miriam: that seems in some ways a good balance of the tradeoffs

  emilio: I agree we don't want #1
  <emilio> https://github.com/w3c/csswg-drafts/issues/6466
  emilio: This also interacts with this issue (above)
  emilio: where one potential option was letting unlayered styles
          compete by specificity across scopes
  emilio: I don't think this has been discussed yet, but it's
          similar-ish
  <TabAtkins> (I don't think this touches directly on the slotted
              stuff, even if we end up having to define a similar
              solution)
  bramus: Big +1 on solving this, authors are struggling with it
  bramus: I lean towards option 2, has some identifier added to the
          layer name indicating it's a "strong" layer
  bramus: ! is fine, whatever
  bramus: with the ! you can add a strong layer into a non-strong layer
  <fantasai> +1 to bramus

  astearns: Do we allow ! in layer names right now?
  TabAtkins: No, they're idents

  kizu: Big +1
  kizu: I'm for third option
  kizu: Second can be a bit confusing, because ordering layers is odd
        if you mix layers with ! and without
  kizu: I think just giving each layer a !top layer is simplest to
        implement and understand
  kizu: use-cases for this probably isn't that many, so only having one
        !top per layer is fine imo
  kizu: and each layer has its own separate !top

  TabAtkins: I also now think #3 is best, because ordering problem
             where the "below" styles and the "above" styles are
             tracked in the same layer declaration and multiple
             declarations stack
  TabAtkins: That induces a mis-ordering, where you have regular,
             !strong, regular, !strong -- look like they're in a single
             list but interwoven
  TabAtkins: Having an explicit layer avoids this issue, nothing gets
             reordered in an implicit way

  keithamus: At github we just shipped layers, we ran into this issue
             so big +1
  keithamus: I think option 3 works, option 2 is a little confusing,
             option 1 isn't great

  fantasai: Making sure I understand
  fantasai: Option 2 is the name, depending on ! or not, grows the
            layer order away from the unlayered
  miriam: No they both get strong
  fantasai: Okay so two lists
  fantasai: and #3 is the same but the top list has a name
  <TabAtkins> Note my example: `@layers foo bar !baz qux;`
  fantasai: Ok, in that case I would prefer #2. Prefer that to having a
            magic name.

  bramus: Replying to Tab about mixing layers
  bramus: Could say that when defining, can't intermix
  bramus: so only `@layers foo bar; @layers !baz !qux;`

  miriam: Can we reject option 1 at least?
  astearns: Objections?
  <romain> +1

  RESOLVED: Reject option 1

  <TabAtkins> Note that "just don't allow mixing in the same statement"
              is more complicated than it looks.

Received on Wednesday, 23 October 2024 23:26:16 UTC