[CSSWG] Minutes Telecon 2025-05-07 [css-color-hdr][css-highlight-api][css-animations][css-masking][css-borders]

=========================================
  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 Color HDR
-------------

  - RESOLVED: Use "constrained" for the middle value (Issue #11698: New
              values for dynamic-range-limit property)

CSS Highlight API
-----------------

  - RESOLVED: Accept the proposal in the issue (Issue #12031: Should
              highlightsFromPoint also return ranges under the hit
              point?)

CSS Animations
--------------

  - The possible models to address issue #12119 (How should
      AnimationTrigger work?) were reviewed and folks were asked to add
      their thoughts to the github.

CSS Masking
-----------

  - RESOLVED: Specify that 'opacity' has no effect on hit-testing
              (Issue #11339: Impact of masks on hit-testing needs to be
              specified)
  - RESOLVED: Specify that 'mask' has no effect on hit-testing (Issue
              #11339)
  - RESOLVED: Define some way for clip-path to derive a path from an
              image, similar to shape-outside. Details TBD (Issue
              #11339)

CSS Borders
-----------

  - There wasn't consensus on if the proposal to address issue #3720
      (Add a 'hairline' border-width value) should be a new unit or a
      new keyword.

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

Agenda: https://lists.w3.org/Archives/Public/www-style/2025May/0001.html

Present:
  Rossen Atanassov
  Tab Atkins-Bittner
  David Awogbemila
  Kevin Babbitt
  Keith Cirkel
  Daniel Clark
  Emilio Cobos Álvarez
  Stephen Chenney
  Yehonatan Daniv
  Elika Etemad
  Robert Flack
  Simon Fraser
  Chris Harrelson
  Daniel Holbert
  Jonathan Kew
  Roman Komarov
  Chris Lilley
  Alison Maher
  Eric Meyer
  Noam Rosenthal
  Jen Simmons
  Alan Stearns
  Miriam Suzanne
  Josh Tumath
  Munira Tursunova
  Sam Weinig

Regrets:
  David Baron
  Oriol Brufau
  Bramus Van Damme
  Lea Verou

Scribe: TabAtkins
Scribe's scribes: dandclark & fantasai

CSS Color HDR
=============

New values for dynamic-range-limit property
-------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/11698

  ChrisL: We haven't agreed on the intermediate values for
          dynamic-range.
  ChrisL: agreed on "standard" and "no-limit"
  ChrisL: Proposal is "constrained", several people suggested and it
          seems to already be adopted by some community members
  ChrisL: so suggest we just take it
  jensimmons: It makes sense, constrained-high was designed to work
              with "high" when "high" meant HDR, but that's no-limit now
  Rossen: So proposal is to go with "constrained". any other comments,
          objections?

  RESOLVED: Use "constrained" for the middle value

CSS Highlight API
=================

Should highlightsFromPoint also return ranges under the hit point?
------------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/12031

  fernando: This is about the return value of highlightsFromPoint
  fernando: Original proposal for for highlights that are hit under a
            certain point
  fernando: After some examples, might be useful to return the *ranges*
            hit for every highlight that is hit, too
  fernando: So proposing to return, rather than a sequence of
            highlights, a sequence of highlighthitresults that are the
            highlight and the range
  fernando: This is useful for spell checkers, custom find in page, etc
            where you need to know what word you're interacting with
  fernando: so I'd like to hear your thoughts

  emilio: Seems fine overall
  emilio: Is the idea that... presumably we're not synthesizing ranges,
          we return the actual Range objects right? Just filtering down
          the ranges that the highlight currently has?
  fernando: Yes, correct
  emilio: Okay, I think we had similar discussions (unsure if this api
          or another one), the concern was that it wasn't clear exactly
          what ranges to return
  emilio: but as long as we're just filtering the existing ranges from
          the highlight, that's fine
  emilio: One concern is you can't early-out as soon as you hit a
          highlight, you do need to iterate over the ranges
  emilio: might be a little annoying to have to do that work if the
          user doesn't need it
  emilio: but if you're clicking on one misspelled word, having to walk
          all the ranges associated with that highlight in author-land
          seems bad
  emilio: So I think it's probably fine, just a bit unfortunate you'll
          still have to pay for it if all you need is the highlight
          itself
  emilio: but the common case is not hitting them anyway

  schenney: I think the issue you're remembering is related to the
            pseudo-classes on pseudo-elements, if you hovered a [missed
            due to overtalk]
  emilio: That's right
  schenney: If you set a highlight with a particular name, with
            multiple sub ranges, and you click on any one range you'll
            get all the ranges for that highlight? or just the ones
            under the hit point
  fernando: The latter, only the ranges that were hit
  fernando: you can already retrieve all the associated ranges just
            from the highlight directly
  schenney: Okay, I think that addresses the concern I raised on the
            intent. I'm happy, then

  fantasai: Two questions
  fantasai: For emilio's question, would it make sense to have two
            different apis? One that returns the highlight and one that
            filters the ranges?
  fantasai: if there's use-cases for just getting the highlight, the
            extra compute doesn't have to be done
  fantasai: Second, seems like we're envisioning some sophisticated
            interfaces being built. Is there a plan for how this would
            work for keyboard users?
  fernando: For first, currently there's no extra compute, we already
            have to go through the ranges to hit-test anyway
  fernando: but maybe there's another impl that can be done where it's
            an extra cost
  fernando: for second, could you repeat?
  fantasai: [repeats the question]
  fernando: The API takes two coords, x y, that can be done with
            keyboard if you get the caret position
  fantasai: That sounds a lot more complicated. Do we think authors
            will actually do that?
  fernando: Hm, that could be something to think about. But I think
            this is similar to elementsFromPoint... was this a concern
            there as well?
  fernando: Would be interested to know how that api deals with it, it
            seems like the same idea
  fantasai: So I suggest the spec should include a practical example
            with this API that shows off keyboard usage
  fantasai: If that ends up being unreasonably complicated, we should
            solve that somehow
  fantasai: whether that's altering this api or adding a new one
  <fantasai> But in any case the spec should show off best practices
  emilio: I think the keyboard interface is a lot simpler, you don't
          need to compute the caret position. The selection api has
          ranges
  emilio: At least the range api does have an isPointInRange or
          something
  emilio: so it's actually easier to implement for keyboard users, they
          just iterate over the highlights, then the ranges, and see if
          the caret point is in there
  emilio: also I don't think AbstractRange has that API, only the live
          ranges. I think we should fix that.
  fantasai: So yeah, I think the spec should just have an example of
            how to do this properly, so people know how to do it

  dandclark: I think we should also take a look at what devs are
             doing now
  dandclark: We're just taking this ability into the engine. Should
             look and see if that's already keyboard accessible.
  dandclark: Think the other point from fantasai about two APIs -
             wasn't sure if we were talking about extra work from
             author or engine. Either case, I think it makes more sense
             to be just one API.
  dandclark: From engine side we're doing the work anyway, from dev
             side if they're getting it all together anyway they can
             just ignore one
  schenney: On the a11y issues, I think it's a broader issue. No way to
            know in the a11y data if a word or string is highlighted, I
            think
  schenney: I'll look into that and raise an issue if that is a problem
  dandclark: Exposing a11y of highlights is something we looked at.
             Different platforms have different ways of exposing it,
             but OSes do have ways to expose grammar/spelling/emphasis
  dandclark: Details escape me, they're different between platforms,
             but we do expose things to a degree.

  TabAtkins: Emphasizing that this is identical to elementsFromPoint.
             Should ensure it's solvable, add example, but that
             shouldn't be a blocker
  TabAtkins: it's doing the same things this other thing is already
             doing, and that thing is good on its own merits

  emilio: One clarification on perf argument
  emilio: I agree it's probably not worth two APIs, the common case
          needs the hit range anyway
  emilio: My point is just that right now you could stop once you hit
          *one* range that works, you don't have to iterate all the rest
  emilio: but I think in the common case you'll do it anyway, so no
          need for a separate api
  <emilio> https://github.com/whatwg/dom/issues/591
  emilio: for keyboards, I just linked to a DOM issue moving a lot of
          stuff from Range to AbstractRange. should move a lot of the
          test stuff

  flackr: Dunno if I mentioned it in this group, but I said it in the
          intent thread. I think we need to think about a more generic
          hit-testing api that combines the various things
  flackr: I think highlightFromPoint, you only get a highlight if the
          element with the highlight would have been hit
  flackr: but elementsFromPoint gives you the list in order
  flackr: Could be useful to have elements and highlights together, in
          order. Maybe with options to let you test for
          pointer-events:none, etc
  flackr: so this doesn't need to block this work, but we should pursue
          a more general hit-test API so we can deal with interleaved
          things
  <TabAtkins> +1
  Rossen: So it sounds like we're agreeing with the proposal
  Rossen: There's good feedback I'm hoping editors will take back to
          the spec, for added clarity if nothing else
  Rossen: how it's different from rangesFromPoint(), how it addresses
          keyboard a11y, etc
  Rossen: but that said, any objections to the proposal as outlined?

  RESOLVED: Accept the proposal in the issue

Should highlightsFromPoint also return ranges under the hit point?
------------------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/12031

  fantasai: flackr brought up that elementsFromPoint returns a list.
            Does this return a list of highlights...? wait nevermind, I
            misread the issue
  emilio: Rob's point is just that you don't interleave the highlights
          and elements. It's also a little naive, doesn't check
          pointer-events, etc.
  flackr: and I think it stops as the first opaque elements
  emilio: Does it?
  flackr: Would be weird for it to not, don't want to hit a highlight
          that's obscured by another element
  emilio: I think as specified it'll return the highlight
  Rossen: Can we take this back to the issue?
  emilio: Yes

CSS Animations
==============

How should AnimationTrigger work?
---------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/12119

  DavidA: We have this concept of animation triggers, which is a way to
          declaratively tie *when* to play/pause to a timeline, same as
          scroll-driven animations
  DavidA: end goal is to support scroll-triggered animations
  DavidA: Two approaches we can do this. different implications for the
          existing concepts
  DavidA: One approach is thinking about animation triggers as an
          internal animation mechanism
  DavidA: The other is triggers as an external thing.
  DavidA: Difference between models is their relationship between
          triggers and play/pause/etc
  DavidA: For internal, we think of play as arming the trigger, so
          responsibility is the trigger itself. Calling play() just
          gets the trigger ready, and then when the trigger is
          satisfied it actually plays
  DavidA: The external way, the trigger is what invokes play()
  DavidA: We're not looking for a resolution today, just feedback on
          which way, if any, the WG would lean towards
  DavidA: I think that'll inform how a lot of other issues I've filed
          will resolve
  DavidA: I can talk about details

  fantasai: I think it would be confusing if play() didn't make the
            animation play. I think the second animation makes more
            sense
  fantasai: Could imagine an animation easily that the author wants to
            trigger on a scroll position, but also have an explicit
            trigger from the user. Those should interact in a
            reasonable way
  DavidA: That would still be accommodated in the internal model
  DavidA: What play() does, if the trigger isn't armed, play() arms the
          trigger. If it's armed and tripped, play() starts the
          animation.
  TabAtkins: I don't think that's right, if you have a trigger set up
             and you're not at the position, but want to have a button
             to trigger the animation, that won't trigger it in this
             case

  ydaniv: On my last issue comment, I tried to enumerate the things I
          think we already agree on in the behavior. We should solve
          the behavior first, what we expect
  ydaniv: like what fantasai asked about
  ydaniv: and once we agree on the behavior, can decide what the model
          should be
  ydaniv: So I enumerated stuff I think we agree on, and rob has a
          comment on a lot of stuff about how it works with existing
          animation features, which I also think we have agreement on
  <flackr> (comment)
https://github.com/w3c/csswg-drafts/issues/12119#issuecomment-2842322212

  ydaniv: A couple of issues I think are still open are, what happens
          with multiple calls to play() with an already activated
          trigger?
  ydaniv: and what happens if a user calls reverse()?
  DavidA: On the first, repeated calls to play(), I think that's what I
          just talked about - I think the expectation is it would play
          again if you call it repeatedly
  DavidA: For reverse(), I think the expectation is also that it would
          play, it's like play() it just auto-reverses it
  flackr: Another important aspect to consider is, if you cancel an
          animation, it won't have an effect until you play() again. If
          you construct an animation but don't play() it it won't have
          an effect
  flackr: So does assigning a trigger to it make it start having an
          effect? particularly in the "before" phase?
  flackr: That seems surprising. Seems like you need some way to "arm"
          the trigger that's not just implicit
  flackr: Also from element.animate() it implicitly calls play, we
          wouldn't expect it to start playing
  flackr: Note I'm not looking to address these issues right now
  fantasai: I'd have to read the whole thing to have a good sense, but
            I feel like the trigger should be another actor - the user
            (via JS) and the trigger, they're both acting on the
            animation and can each make it play or pause or whatever
  fantasai: I think those calls interleave in that way, like there's
            two users that each have access to the play/pause buttons
  <TabAtkins> (modulo some questions about the animation being "active"
              for before effect, etc, I also agree with fantasai
              initially)
  <ydaniv> I had the same model in mind as fantasai
  <flackr> ydaniv, fantasai that model naively would mean that the
           animation isn't in getAnimations, and isn't in the before
           phase until triggered

  Rossen: So, what resolution are you looking for?
  DavidA: None right now, looking for feedback on what model to go with
  DavidA: [summarizes the models again]
  DavidA: Would probably be useful to know that, in the second model
          (trigger calls play()), to Rob's point, we'll need some
          explicit apis to say when to enable and disable the trigger
  DavidA: so if people still want to think about it, that's fine,
          otherwise we can resolve one way or another
  <TabAtkins> (I think continuing on the issue and treating this as
              just raising awareness is just fine.)
  fantasai: Adding extra apis to enable/disable the trigger makes sense
            to me
  Rossen: All right, let's come back with a model with those extra APIs
  <ydaniv> flackr I agree that we should tweak the naive model further

CSS Masking
===========

Impact of masks on hit-testing needs to be specified
----------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/11339

  ChrisL: We have an extra issue that says we don't specify hit-testing
          anywhere. Been open since 2018
  ChrisL: This is one example, there are other things that are
          unspecified. Might affect whether we want to sprinkle details
          around or collect them into one spec
  smfr: Hit testing is undefined, with masks there's different
        behavior. Webkit follows the current spec and ignores the mask,
        chrome respects the mask
  smfr: so it's a compat issue in what can actually be clicked
  smfr: hit testing is undefined in general. What do we do?

  TabAtkins: Me and Chris Harrelson chatted about this earlier today,
             and we want to get this spec written this year
  TabAtkins: So already on my plan to do this year
  TabAtkins: don't have an opinion on solving this issue for masks now
             or put details later into other spec
  TabAtkins: but I would like to write up the spec later this year to
             close the 2018 issue
  TabAtkins: No comments on this specific issue
  Rossen: That would be amazing to have
  emilio: +1
  emilio: Yeah huge +1 to having the spec
  emilio: For this issue, is there a good use-case... what would
          authors expect?
  emilio: could see both.
  emilio: Might want mask decorative, others where you want it honored
  emilio: Since there's disagreement I assume we can change, just need
          to figure out what the most useful behavior is
  <noamr> +1

  ChrisL: Coming back to SVG, where this came from, we distinguish
          between "clip" (inside vs outside, a binary) and "mask" (a
          gradient from fully opaque to transparent). people ask about
          0/transparent
  ChrisL: I think we should definitely define it, and it shouldn't be
          like a 50% mask value or something
  <lea> what if we have reasonable defaults and a way to override them?
        (e.g. `hit-testing-area` or something, TBB)
  noamr: I'm not aware of the history, but I'd say it needs to be
         derived from opacity - whatever we decide for opacity we
         should use here
  noamr: opacity doesn't affect hit-testing, that's a feature more than
         a bug
  noamr: So opacity:0 elements are still hit-tested
  noamr: To me mask is more like opacity than a clip-path
  noamr: so I think we should be consistent

  kizu: This might be covered by the future spec, but both for this and
        cases like border-radius, would be nice to have a property
        controlling the hit test
  kizu: sometimes want different behaviors
  kizu: Years ago when browsers changed the hit-test for border-radius,
        I was annoyed I couldn't achieve the old behavior without
        adding a wrapper.
  ChrisL: I agree this should be consistent with opacity. we're
          entirely silent on the opacity issue fwiw
  ChrisL: At minimum, should we put something into opacity saying "this
          doesn't affect hit testing"?
  ChrisL: seems there's consensus on that between browsers.
  ChrisL: There's a WPT proposed by ladybird because this is untested
  TabAtkins: Agree, now that I remember
  TabAtkins: binary vs gradient issue
  TabAtkins: agree we should have mask by default work same as opacity,
             i.e. no effect on hit testing
  TabAtkins: Need more exploration of tools; being able to derive a
             clip-path from a mask would be useful
  TabAtkins: but that would be a clip-path feature
  TabAtkins: put some individual details into properties like opacity /
             mask is a good idea

  fantasai: I think the hit testing spec should provide a framework for
            defining how it works fundamentally/generally, but specific
            properties should define how they work. that's what we do
            for border-radius and clip-path currently. having it all
            centralized makes it more likely we'll forget stuff.
  fantasai: can have examples, but not having the centralized list of
            exhaustive effects.
  fantasai: So it seems there's a proposal to define opacity as not
            affecting hit-testing, a proposal to define mask as not
            defining hit-testing, and a proposal to derive clip-path
            from a mask
  fantasai: Maybe we want to take those as resolutions?
  Rossen: Okay, propose that opacity doesn't affect hit-testing. Any
          objections to that?

  RESOLVED: Specify that 'opacity' has no effect on hit-testing.

  Rossen: Next, propose that 'mask' has no effect on hit-testing
  smfr: This would require behavior changes from chrome and firefox

  RESOLVED: Specify that 'mask' has no effect on hit-testing

  Rossen: Finally, propose to define a way to derive a clip-path from
          mask
  smfr: Noting that shape-outside also has a way to derive a path from
        an image, we should be consistent
  <emeyer> +1 to smfr’s point about being consistent with shape-outside
  <ydaniv> +1
  smfr: shape-outside defaults to using the opacity of the image. if we
        have knobs for that, they should work in both places
  <ChrisL> Agree that both mask opacity and mask luminance should be
           options
  <fantasai> See
https://www.w3.org/TR/css-shapes-1/#shape-image-threshold-property
  <fantasai> and https://www.w3.org/TR/css-shapes-1/#shape-outside-property
  <emeyer> +1 to ChrisL
  TabAtkins: Shapes spec uses alpha channel, defines threshold
  TabAtkins: We can figure out how to make them consistent
  Rossen: So figure out some way to define a clip path from an image,
          similar to shape outside. details TBD
  <noamr> btw `view-transitions` spec *does* define hit-testing

  RESOLVED: Define some way for clip-path to derive a path from an
            image, similar to shape-outside. Details TBD.

CSS Borders
===========

Add a 'hairline' border-width value
-----------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/3720

  TabAtkins: Discussed border-rounding behavior, where borders with
             nonzero width but less than a pixel will round to
             something visible
  TabAtkins: lot of discussion
  TabAtkins: Conversation seemed to lean towards exposing a 'hairline'
             keyword for a few properties
  TabAtkins: and maybe a rounding function that rounds like borders do,
             always away from zero
  TabAtkins: Since then, Oriol suggested 'hairline' as a unit
  TabAtkins: maps to a number of device pixels
  TabAtkins: can be used as a length unit anywhere lengths are allowed
  TabAtkins: Avoids need for new rounding function
  TabAtkins: Also useful if you want another box to match the width of
             a box with hairline border
  TabAtkins: could specify calc(100px + 2hairline)
  TabAtkins: smfr concerned that larger multiples wouldn't be reasonable
  TabAtkins: but use cases for small multiples
  TabAtkins: so I suggest resolving on this approach
  TabAtkins: A new unit that is 1px or less, but at least one device
             pixel

  emilio: One question, should we make it a keyword rather than a unit?
  emilio: A unit that's such a mouthful feels weird
  TabAtkins: A keyword either is not usable in calc, or is one of the
             calc keywords, unless we do something to make it usable
             both ways
  smfr: I wouldn't object to the unit, think it's a bit weird though
  TabAtkins: Exactly what we do today with border widths less than a
             pixel. We still have some definition of what it means
             internally
  fantasai: I think making this a unit feels wrong, if you want the
            boxes to match you should use box-sizing
  <jfkthame> fantasai++
  fantasai: people might start using the unit to reference device
            pixels in a way that's more fragile than we want
  flackr: If an author wants something thicker than a hairline...?
  TabAtkins: max(1hairline, .3px)
  fantasai: I think having a rounding function makes more sense
  <emilio> fwiw, I think implementing it as a keyword seems trivial-ish
           as well (so that it works in calc() and other <length>s too)
  TabAtkins: Well this clearly wasn't doable in five minutes
  <emeyer> I have concerns about device fingerprinting with a unit that
           yields a number of device pixels.
  <TabAtkins> emeyer, device pixel ratio is already exposed in numerous
              other ways

Received on Wednesday, 7 May 2025 23:42:54 UTC