[CSSWG] Minutes Telecon 2023-10-18 [css-view-transitions][css-contain][cssom-view][css-cascade][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.

View Transitions

  - RESOLVED: Make the parameter non-nullable, but keep it optional
              (Issue #9460: Making the callback param non-nullable)

CSS Contain

  - RESOLVED: Extend checkVisibility to expose content-visibility: auto
              state (Issue #9474: API to expose skipped content state)


  - RESOLVED: Close no change, reopen if use cases are presented on the
              issue (Issue #9478: What does element.checkVisibility()
              return for display: contents elements?)

Cascade & Nesting

  - RESOLVED: We will address this issue, and fix nesting to allow for
              bare declarations after nested rules without moving them
              above (Issue #8738: Figure out whether we're fine with
              "shifting up" bare declarations after rules)


Agenda: https://lists.w3.org/Archives/Public/www-style/2023Oct/0006.html

  Adam Argyle
  David Baron
  Oriol Brufau
  Emilio Cobos Álvarez
  Yehonatan Daniv
  Elika Etemad
  Paul Grenier
  Chris Harrelson
  Daniel Holbert
  Brad Kemper
  Vladimir Levin
  Chris Lilley
  Tim Nguyen
  Cassondra Roberts
  Noam Rosenthal
  Khushal Sagar
  Jen Simmons
  Miriam Suzanne
  Alan Stearns
  Lea Verou
  Sebastian Zartner

  Tab Atkins
  Jonathan Kew
  Bramus Van Damme

Chair: astearns

Scribe: emilio

View Transitions

Making the callback param non-nullable
  github: https://github.com/w3c/csswg-drafts/issues/9460

  vmpstr: We have a startViewTransition call that takes one param that
          is marked as optional nullable with default of null
  vmpstr: We resolved to extend this to allow a dictionary
  vmpstr: so naively it'd be an optional nullable union
  vmpstr: but that's not possible in WebIDL
  vmpstr: so proposal is making it non-nullable
  vmpstr: This only precludes null of being a valid parameter
  vmpstr: it'd still be optional
  astearns: If we decide on null as a naive way of dealing with the
  astearns: was there a purpose?
  vmpstr: There wasn't, it was just in the editor's draft since the
  <khush> +1

  emilio: So if null is passed we will start throwing?
  vmpstr: That's right
  emilio: Hopefully nobody is doing that, if you're fine with the
          compat risk seems fine
  vmpstr: Usage is low enough
  emilio: Sounds good then
  khush: To add to vmpstr there's no production usecase where you'd do
  khush: because the callback is where you are supposed to mutate the
  vmpstr: To clarify it's still optional, it'd be just explicit null
          that could be problematic

  RESOLVED: Make the parameter non-nullable, but keep it optional

CSS Contain

API to expose skipped content state
  github: https://github.com/w3c/csswg-drafts/issues/9474

  ntim: In Safari we have some reader detection code that does some
        visual analysis and performs layout in different subtrees
  ntim: We want an API to be able to skip hidden content for visual
  ntim: because otherwise it cancels out optimizations
  ntim: Ideally it'd cover content-visibility: auto and hidden

  vmpstr: checkVisibility was close to cover this use case
  vmpstr: it deals with content-visibility: hidden
  vmpstr: I'd suggest extending checkVisibility
  vmpstr: content-visibility: auto content remains accessible to
          find-in-page / tab-navigation / etc so it's not "hidden
  vmpstr: so not sure if it'd be consistent with the model
  ntim: You can kinda query it with the statechange event
  ntim: but it's less convenient and you might miss some events

  emilio: Not opposed
  emilio: and I agree with vmpstr on extending checkVisibility
  emilio: but curious about the use case because it seems reader-mode
          should care about content-visibility: auto
  emilio: to check size you need to layout
  ntim: So we have a check for the element being small and skipping the
  ntim: and the rest of the code doesn't care about layout
  ntim: but actually slows down the website because it lays out the
        skipped subtrees
  ntim: Could be a separate method on checkVisibility even
  emilio: The element could be large, and you need to lay it out
  emilio: kinda silly not to expose this
  emilio: It's a bit weird that with the statechange event being async
          you can observe an element being hidden before the state
          change arrives
  emilio: Might cause some subtle bugs
  emilio: but anyhow it seems fine to expose
  vmpstr: Just to answer emilio, I don't think it's unique to this
  vmpstr: intersectionobserver has the same issue, where you could do
          your own math via gBCR
  vmpstr: I'd like to suggest not reusing checkVisibility for this
  emilio: why?
  vmpstr: To me the problematic word there is visibility
  vmpstr: because if you consider things like a11y it's there
  vmpstr: so claiming it's not visible is not entirely accurate
  vmpstr: visibility is a little overloaded
  emilio: But that's true of all the other things CV checks
  emilio: Things with opacity 0 are still in the visibility tree
  emilio: As long as you opt in for content visibility auto, seems like
          you need to check that anyway
  vmpstr: I guess opacity would be similar to this, yeah, the other's

  astearns: Seems there's consensus on exposing this, but not in
            whether to change checkVisibility or something else
  astearns: Might be worth resolving on that and discussing the other
            thing in the issue
  fantasai: Was going to say the same thing as emilio, checkVisibility
            is already a misnomer and was designed with this extension
            in mind
  ntim: I don't feel strongly either way
  <vmpstr> +1

  RESOLVED: Extend checkVisibility to expose content-visibility: auto


What does element.checkVisibility() return for display: contents
  github: https://github.com/w3c/csswg-drafts/issues/9478

  ntim: Right now checkVisibility will return that display: contents
        elements are not visible because they don't have a box
  ntim: which I find not very intuitive
  ntim: I don't know if that was intentional or not
  ntim: WPTs don't test for this

  emilio: FF also returns this, not sure if it was intentional. I can
          see usecases. The spec is not ambiguous
  ntim: It's weird because display: contents is technically visible
  astearns: It's children are anyways
  vmpstr: I don't think this was intentional
  vmpstr: idea was to catch display: none and so

  ntim: My suggestion would be to check for the element or any flat
        tree ancestor having display: none
  emilio: Seems ok-ish to me, but i also think there are use cases for
          making display:contents or considering it invisible. So maybe
          this should be opt in. I don't know
  ntim: You can see display contents elements
  emilio: You can see their children
  astearns: You don't see the box, it's background, just its children

  noamr: What is the behavior for an element with visibility: hidden
         that has children with visibility: visible? I'd expect this to
         be consistent
  emilio: It's consistent with that
  noamr: This is an invisible element with visible children, so it's
         consistent with that
  <SebastianZ> +1 on Noam's points.

  astearns: I'd suggest taking it back to the issue
  astearns: if there are use cases we can come back to this
  astearns: but I don't see consensus
  vmpstr: Use cases for making it visible?
  ntim: not necessarily, just a bit unintuitive
  ntim: don't care either way
  ntim: I guess for visibility we only check the visibility if
        checkVisibilityCSS option is
  ntim: specified

  astearns: Suggested to close no change and add WPTs
  fantasai: If there are use cases for both behaviors can we make that
  astearns: We didn't hear use cases
  fantasai: So point is to go back to the issue to request use cases?
  astearns: I was suggesting close no change and reopening if use cases
            are presented
  astearns: if you'd like to keep it open fine with that
  ntim: Don't feel strongly, I could see web devs wanting to check if
        contents are visible
  ntim: but if we don't respect that for visibility then...

  RESOLVED: Close no change, reopen if use cases are presented on the

  ntim: Should we add a note to the spec?
  astearns: We should def. have a WPT
  astearns: having it in the draft is an editorial decision
  vmpstr: I can add one

CSS Cascade & Nesting
  scribe: fantasai

Figure out whether we're fine with "shifting up" bare declarations
    after rules
  github: https://github.com/w3c/csswg-drafts/issues/8738

  lea: Right now, if we have bare declarations after a nested rule,
       current behavior is that they're shifted up to be before the
       nested rule
  lea: which means nested rule can override them
  lea: [gives example in the issue]
  lea: This behavior violates source order when specificity is the
       same, and is against author expectations
  lea: WebKit ran a poll showing that
  lea: I ran two polls, here's link to both of them
  <lea> https://github.com/w3c/csswg-drafts/issues/8738#issuecomment-1746990112
  lea: Almost 80% of authors were expecting the different behavior
  lea: and those who didn't seemed to have a broken mental model around
  lea: things like "@supports increases specificity"
  <chris> that seems surprising, it breaks document order. I bet people
          spend time debugging this
  lea: That's quite dangerous, not just that this feature has a weird
       behavior, but it encourages a broken mental model of how CSS
  lea: specificity is already confusing as it is, we don't need to add
       to that

  lea: In terms of changing behavior, not really much reason
  lea: in the thread it's "this is how preprocessors work"
  lea: in the TAG we have a principle against this
  lea: Other option is compatible with existing tools
  lea: we suggest that people go with the usability benefit
  lea: 10 years down the line, how preprocessors of today work will not
  lea: There was also point that maybe slightly easier to implement
       current way
  lea: but doesn't seem that there is serious implementation complexity
       problem with changing to match source order
  lea: Also, jensimmons ran several more polls, which validated the
       same point that authors find the behavior confusing

  jensimmons: I feel pretty strongly that we should change the behavior
              so that it matches what people expect from CSS cascade,
              that later thing overrides earlier thing when specificity
              is tied
  jensimmons: People will not remember what SASS did 20 years from now

  oriol: I agree that we should not prioritize aligning with
         preprocessors, since preprocessors can always change by
         releasing a new version
  oriol: authors can adopt when they want
  oriol: but this wasn't the main reason
  oriol: The question is how do you handle this?
  oriol: One was that we would just ignore declarations after nested
  oriol: but that seems problematic if they add garbage, and could
         cause declarations to stop working, so concerned about
  oriol: Wrapping in & doesn't work with pseudo-elements
  oriol: so I don't think this is straightforward
  oriol: While I agree that this is pretty bad and very confusing, and
         I would have objected to current syntax of nesting if I had
         realized this
  oriol: I think alternatives seem worse
  oriol: I don't see a clear proposal addressing all the concerns
  oriol: I think the current state is the lesser of the evils
  <chris> unclear why current state is "worse"

  astearns: I don't believe we're talking about discarding things after
            nested rules, only talking about how to keep them in and do
            the source order correctly
  astearns: whether wrapping in an & is the way forward, would need to
            work through the issues with pseudos etc.
  astearns: Let's go back to the queue

  emilio: I also brought another concern which may or may not be an
  emilio: this also assumes we go with wrapping-in-&, which seemed like
          most straightforward solution
  emilio: Wrapping stuff in extra rules can have surprising
          consequences perf-wise
  emilio: you triple the amount of selectors that element has to match
  emilio: I agree with Oriol that given the & stuff doesn't work with
          pseudo-elements, we either need to figure out how to fix that
  emilio: but current behavior is better than having some declarations
          work and others not
  emilio: we want to make sure all the declarations work
  emilio: but then the nested at-rule would also not work?
  emilio: so maybe pseudo-elements issue isn't such a great argument,
          since the at-rule inside would also be broken
  astearns: Not sure I follow
  emilio: You have sth::before { declarations; @rule {... };
          more-declarations; }
  emilio: The issue is that more-declarations gets shifted up above
  emilio: but wrapping in & doesn't work, because :is() doesn't work
          with pseudo-elements
  emilio: but actually you have this same problem with the at-rule
  emilio: if you put bare declarations in the @rule, they also get
          magically wrapped in &
  emilio: so maybe wrapping in & isn't so terrible
  emilio: it's weird if ones before work and ones after don't
  emilio: but the @rule declarations would also be broken

  miriam: Not a lot to add, except to say that I agree it's confusing
  miriam: I don't know why SASS did it in the first place
  miriam: Authors develop convention of putting declarations first
  miriam: but that's not great
  miriam: We're going to have similar problems with mix-ins in the
  miriam: be nice to not have a totally different solution

  lea: Are we sure it would be a problem with pseudo-elements?
  lea: there's no reason to use :is() for a single &
  lea: You should just get same selector as parent. If you write
       something where that substitution isn't fine then you have a
  lea: If we don't already do that then we should, even aside from this
  lea: would enable media queries inside pseudo-elements, which seems
       important to allow

  emilio: Using :is() is kinda necessary in the sense that it allows
          you to avoid expansion, which prevents combinatorial explosion
  emilio: but maybe special-casing the single & is OK?
  emilio: but I suggest we first fix this, at least the bare at-rule
          issue and then
  emilio: figure out if we need to do this
  emilio: It is observable due to specificity, right? This would get
          the combined specificity of all the items in the selector list
  emilio: if you have #foo, bar { .. } then things inside at-rule would
          be different specificity
  emilio: it would be weird to diverge
  emilio: it would be weird to make & work differently than in any
          other position
  <lea> what emilio is saying is that .foo, #bar { & { color: green } }
        rn has different specificity than .foo, #bar { color: green }
        because it's rewritten as :is(.foo, #bar) { color: green }
  ntim: :is() will take the highest specificity
  emilio: Which is why it's different. & will get the ID's specificity,
          even though that matches .foo rather than #bar
  emilio: assuming of course only one of the selectors matches

  astearns: One of the arguments against making this change is that
            people use SASS conventions and nobody puts declarations
            after nesting anyway
  astearns: Anecdotally, when I went to search, the 2nd CSS file I
            looked at had bare declarations after nesting rule for SASS
  astearns: probably an accident, but don't think you can say it's not

  fantasai: Couple things emilio brought up and I think are insightful.
            First is that this is a current problem for @media in
  <lea> +1 to fantasai
  fantasai: so we need to make it work with nested at rules
  fantasai: Second is that it's weird that that flattening of
            specificity is very weird and unexpected
  fantasai: So I think we should address both of these issues
  fantasai: but the fact that pseudo-elements are already a concern it
            means we need to address it
  fantasai: but it shouldn't block us from solving the cascade
  fantasai: Proposal is that we agree that we're going to fix this
  fantasai: and try to figure out a right way to fix it
  fantasai: We could just make that & matches pseudos or something
  fantasai: or we could come up with another symbol that matches

  jensimmons: Adding to astearns, idea that people will organize their
              code properly, might have worked out a decade ago when
              sites were new and got overhauled every few years, and
              only a few developers
  jensimmons: but now teams are much more massive, and code lasts much
              longer, 5-10 years
  jensimmons: and people are scared to reorder styles, touching cascade
              could break things on other pages
  jensimmons: They just jam things in, and might not understand that
              they're adding things before or after
  jensimmons: so industry has changed enough that I don't think relying
              on good CSS organization is workable
  emilio: I agree with fantasai that we should bring up those issues
          and find a coherent way of fixing it
  <bradk> +1 to @jensimmons
  <chris> also +1 to @jensimmons this makes css fragile and

  emilio: The most straightforward solution would be to make & expand
          to the selector list when it's alone
  emilio: It would solve all the relevant issues here: would make
          pseudos work, would make @media inside stuff work, and it
          would make declarations wrapped in & work
  emilio: It feels a bit inconsistent, but I think it's the only
          reasonable solution
  lea: Agree with emilio. even if we decide this isn't the best
       solution, can invent a better one
  lea: but saying that & alone should invoke the selector directly is a
       good optimization regardless
  lea: no reason to have :is() there
  lea: Good change, solves a bunch of issues, and gives us time to
       solve the problems down the line
  <argyle> I thought :is() only wrapped & when it was a selector list,
           but that changed somewhere along the line
  <jensimmons> +1
  lea: and means implementations can update, and that avoids web compat
       lockdown of waiting

  astearns: OK. Let's first resolve that we want to fix this issue,
            that we want the cascade to use source order
  astearns: I haven't heard any arguments against this change, just
  <bradk> +1

  RESOLVED: We will address this issue, and fix nesting to allow for
            bare declarations after nested rules without moving them

  astearns: Unclear if there's one or two extra issues, can a volunteer
  fantasai: The two issues are, pseudo-elements aren't handled properly
            by & because it wraps in :is(); and specificity is badly
            handled because & is wrapped in :is()
  lea: Should discuss together as one issue
  astearns: OK, we're out of time

Received on Wednesday, 18 October 2023 22:49:47 UTC