[CSSWG] Minutes Telecon 2024-04-24 [css-grid][masonry][css-color]

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


Alternate masonry path forward
------------------------------

  - jensimmons presented an overview of the proposal for issue #9041
      (Alternate masonry path forward) and an accompanying demo to add
      clarity (demo: https://webkit.org/demos/grid3/photos/ )
  - The Google & Edge implementors were concerned that the current
      proposal would not be implementable because the algorithm would
      cause exponential behavior in some cases and proposed some
      restrictions to prevent it (full details in this comment:
      https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2075210820 )
  - Several folks expressed concern with including this in Grid since,
      though they have similarity, understanding masonry in a grid
      context would limit what masonry could do. On the other hand,
      authors could want to switch between grid and masonry at
      different breakpoints which would argue for keeping them together.
  - Discussion will continue on github to allow folks time to think
      about and discuss the various ideas raised on the call.

CSS Color
---------

  - RESOLVED: `none` is preserved in calculations involving CSS math
              functions (Issue #10211: Clarify that `none` is preserved
              in calculations)
  - RESOLVED: When interpolating between two none-containing values,
              the result is a calc-mix() expression preserving the
              `none` keywords in both values (Issue #10211)

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

Agenda: https://lists.w3.org/Archives/Public/www-style/2024Apr/0006.html

Present:
  Rachel Andrew
  Rossen Atanassov
  Tab Atkins Bittner
  Kevin Babbitt
  David Baron
  Andreu Botella
  Oriol Brufau
  Stephen Chenney
  Emilio Cobos Álvarez
  Yehonatan Daniv
  Elika Etemad
  Robert Flack
  Chris Harrelson
  Daniel Holbert
  Jonathan Kew
  Roman Komarov
  Una Kravets
  David Leininger
  Vladimir Levin
  Chris Lilley
  Alison Maher
  Florian Rivoal
  Jen Simmons
  Miriam Suzanne
  Alan Stearns
  Brandon Stewart
  Bramus Van Damme
  Lea Verou
  Sebastian Zartner

Regrets:
  Eric Meyer

Chair: Rossen

Scribe: fantasai
Scribe's scribe: schenney

Alternate masonry path forward
==============================
  github: https://github.com/w3c/csswg-drafts/issues/9041

  fantasai: Topics: can masonry replace grid, track info, interaction
            of masonry-grid. For authors? For spec?
  <fantasai> ->
https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2071086963
  fantasai: Question? Use case for variable track sizes. It's not
            necessary, all sorts of objections due to complexity. Jen
            Simmons has demos to present and talk through.

  jensimmons: We're hoping to make real progress on this question, it's
              been 4 years since this question first came up
  jensimmons: the demos are online
  <bts> Link to demo: https://webkit.org/demos/grid3/photos/
  jensimmons: Photos demo is a good start. If we show numbers you can
              see multicol layout, where the images go down the first
              column, then second, etc.
  jensimmons: for this content it's ok, other content it's not great;
              but also it doesn't allow loading additional content to
              the bottom
  jensimmons: If you use grid L1, it lines up in both row and column.
              If aspect ratio isn't uniform, doesn't look great
  jensimmons: Masonry gives a chance to lay things out going across the
              top of the columns, and then keep going across filling
              the shortest column
  jensimmons: it builds into grid easily, can specify any set of
              columns you want and then set rows to 'masonry'
  jensimmons: basically turns the rows off
  jensimmons: There are other things you can do with grid, because full
              power of grid-template-columns
  jensimmons: in this demo, first and last cols are fixed sizes, and
              the middle columns 1fr, and number of columns scales with
              width of window
  jensimmons: Next demo, all columns are flexible but we have narrow
              and wide columns
  jensimmons: and always starts and ends with a narrow column
  jensimmons: The basic masonry layout is popular because JS can only
              do so much, but building into CSS can do a lot more
  jensimmons: Spanning in grid allows some interesting possibilities,
              e.g. every 5th item is wider here. Gives more graphic
              design interest.
  jensimmons: In this version made the landscape photos wider
  jensimmons: [shows horizontal masonry demo]
  jensimmons: Mega menus are another use case
  jensimmons: Multicol would go down the columns, but masonry allows to
              lay out the first items across
  jensimmons: Text becomes more interesting also.
  jensimmons: A lot of websites lay out teaser content by fitting the
              content to the regular boxes
  jensimmons: often by trucating it
  jensimmons: keep everything the same aspect ratio, creates a very
              modernist grid
  jensimmons: this is why graphic design can feel boring on the web
  jensimmons: Classic masonry allows more flow of content, but still
              somewhat rigid
  jensimmons: start applying different widths and spans, create very
              interesting layouts
  jensimmons: This last demo is classic masonry, but grid allows some
              extra possibilities
  jensimmons: the header/sidebar can be shifted to the other side using
              explicit placement
  jensimmons: or use subgrid to align metadata across cards
  jensimmons: subgrid is powerful here
  jensimmons: questions?

  <florian> I underestimated this Newspaper demo. There's more to it
            that I thought at first, and I do find it compelling
  <lea> +1 for letting Jen finish. This is important, we can spend 5
        more minutes on it. Also, talking about timeboxing came close
        to taking more time than the actual presentation.

  jensimmons: As I wrote in the article, this is about saying "hey,
              we've got grid -- but what if we let go of the idea that
              it's only modular grids?"
  jensimmons: columnar grids are grid systems, historically in graphic
              design
  jensimmons: this just lets us turn off rows (or turn off columns)
  jensimmons: and contents pack together

  keithamus: Is this display: block grid?
  jensimmons: no inlines, this is just 'display: grid'

  TabAtkins: I posted a long comment to the issue about an hour ago.
             Long because I went into our reasoning, but can read tldr
             and proposal
  TabAtkins: Summary of our position, we the Chrome+Edge engineers find
             the current spec unshippable given the algorithm in it
  <dbaron> https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2075210820
  TabAtkins: it can trigger quadratic or exponential behavior, which
             could brick the page
  TabAtkins: we acknowledge they are edge cases
  TabAtkins: The restrictions we need are not ones that Jen's demos hit
  TabAtkins: We just need to restrict to either a) fixed or flexible
             tracks OR b) intrinsic tracks
  TabAtkins: Every demo presented works in those constraints
  TabAtkins: problem only happens when you can mix intrinsic track with
             other types of track sizing
  TabAtkins: because that's when spanners start to contribute
             differently in different racks
  TabAtkins: On a more conceptual level, we think there's a number of
             friction points where the syntax is suboptimal because
             designed for 2D grid
  TabAtkins: or concepts don't directly translate and need to default
             values instead of rejecting at parse time
  TabAtkins: e.g. auto-fit is treated as auto-fill
  TabAtkins: However, we think there's also significant conceptual
             similarity to grid. It has tracks, lines, etc.
  TabAtkins: so should do as much connection between the two
  TabAtkins: e.g. have subgrid take lines from a parent, assuming we
             have fixed sizing bits
  TabAtkins: Similarly submasonry value, taking lines from parent
  TabAtkins: Everywhere they interact, make it easy to translate
             knowledge. But they're still not the same thing, and
             enough pain points that they should be done in different
             display types
  <dholbert> TabAtkins' github comment with more details:
             https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2075210820

  Lea: These demos are impressive, and this is solving real author pain
       points.
  Lea: I did have some reservations about how this combines with
       multicol from an author point of view, but I think I'm now
       convinced this makes sense as a part of grid.
  Lea: One thing is that the `masonry` keyword seems a little magical.
       How can authors set constraints on the min and max size of these
       generated rows/columns? How does it interact with
       `grid-auto-flow`?
  Lea: e.g. what about 'dense' keyword?

  miriam: Agree quite a bit with Lea. Agree we like this as part of
          grid. Syntax feels right.
  miriam: would like to add a few more constraints
  miriam: get that there's some constraints on implementation
  miriam: Looking at separate masonry proposal, seems like new terms
          for similar things
  miriam: Why do I need to learn new terms for the same thing?
  miriam: I also might want to switch between grid and masonry at
          different break points
  miriam: keeping them together makes it a lot easier to do
  miriam: I like the grid syntax if we can make it work
  <lea> +1 to miriam great point about switching to/from masonry

  fantasai: Response to Lea. I don't understand min/max rows columns.
            Maybe explain later.
  fantasai: Dense, autoflow maybe mergable from ? and ?

  jensimmons: We put this out to designers and developers to see what
              kind of feedback we would get
  jensimmons: Overwhelmingly people want to see this as part of grid.
              It's not 100%, but on issue in CSSWG it's roughly 80/20
              in favor of building into grid.
  jensimmons: Authors prefer making it part of what they're already
              familiar with, already learning, as part of CSS Grid
  <TabAtkins> wrt the author feedback, note that the blog post argued
              exclusively against an overly simplistic model (only
              fixed-size, identical tracks, a la multicol). Every demo
              was showing how we need more than that. As I said, tho,
              every demo is perfectly fine; the actual restrictions we
              need are much more subtle. We can't take support for
              "what the blog post displayed" as arguments for "build it
              into Grid".

  ydaniv: +1 to what miriam said before
  ydaniv: Thinking about interpolation, animating to/from masonry and
          grid
  ydaniv: could be easier inside grid than between display types

  florian: Thanks Jen & team for the demos, and also for presentation.
           I had skimmed the blog but realized more things during
           presentation
  florian: more compelling, and really makes the case for needing these
           capabilities
  florian: With regards to Google proposal posted recently, seems it's
           fuller than what was originally discussed
  florian: I think we need more time on this topic soon, and discuss
           the differences between the two

  rachelandrew: WebKit team presented to developers saying the only way
                is to have grid implementation, and I don't think
                that's the case as Tab outlined
  rachelandrew: but when I first started showing people Flexbox and
                Grid, people would say "it's inconsistent", because it
                was different from block layout
  rachelandrew: at this point we have good understanding of formatting
                contexts
  rachelandrew: My worry as someone who teaches this is, if we put
                masonry in grid we have to say "these properties only
                work in grid that's not masonry" or "these properties
                only work in grid that is masonry"
  rachelandrew: If we build into a separate display type, can still
                have a lot of cool stuff, but not dancing around the
                differences

  dholbert: We have a prototype implementation of masonry in grid
  dholbert: I'm sympathetic to the performance considerations of every
            item in every track
  dholbert: agree with sharing a lot of the same behavior with grid
  dholbert: using a restricted form of track syntax but compatible for
            masonry, that's only possible to do by using a different
            set of property names

  lea: How does masonry work with explicit grid placement?
  fantasai: If you specify specific track, masonry item goes there.
  fantasai: Just like grid etc, move to that position and keep placing.
  florian: Do you ignore a dimension?
  fantasai: Yes.
  <lea> Yup, just tried it in the demo, it seems to work very
        reasonably, nice
  <TabAtkins> + there's a switch in masonry-auto-flow about whether to
              place all the explicit items first (like Grid does) or in
              the normal order.
  <lea> big +1 for integrating masonry-auto-flow with grid-auto-flow if
        this becomes part of grid

  Rossen: Good discussion, let's review comments and come back to it
          later.
  <astearns> let’s keep posting and conversing in the issue - please do
             not wait until we can schedule more call time

CSS Color
=========
  scribe: dholbert

Clarify that `none` is preserved in calculations
------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/10211

  lea: Awhile back we invented 'none' value for color components to
       represent achromatic colors (that don't have a particular hue)
  lea: when converting gray to a polar format, which hue do you use?
       none are relevant
  lea: then we expanded to chroma and saturation for same reason
  lea: Eventually it turns out once it was deployed, very useful in
       many more use cases
  lea: lets you represent colors that are parameterizable, that get
       meaning based on where you use them
  lea: e.g. color with `none`s and lightness, and mix with it to get
       tints
  lea: with relative color syntax becomes even more useful
  lea: When we wrote the spec, what do you output a color that has
       'none'?
  lea: so we decided to make it convert to zero
  lea: When you're converting from one color space to another, e.g. rgb
       to lch
  lea: you don't want to expose color space conversion math
  lea: This conversion to zero is like a last ditch effort. Last thing
       you do if there's nothing else reasonable to do
  lea: The way this was interpreted by impls, you also convert to zero
       when you can't do a computation, e.g. calc(h)
  lea: This is against author intent; h and calc(h) should really be
       the same
  lea: You could imagine having a color in relative color syntax and
       using calc or calc-mix to ?
  lea: All of these would be solved if we resolved that 'none' was
       preserved during calculations. Don't convert `none`s to
       anything, `none`s remain `none`s

  lea: I've written details about how this might work in the issue
  lea: Interpolation operations have the behavior of the current value
       of none, only have this behavior if the other value is not
       "none-containing"
  lea: Of you're interpolating between a value with none to some other
       value, you get the non-none-containing value
  lea: [missed some]
  lea: This reduces magic/discontinuities.
  lea: Also need to sort out how to handle this for a syntax that
       allows 'none', e.g. clamp's 1st or 3rd argument. Is it the
       'none' that means no bound, or 'none' that means the color
       meaning of 'none'?
  lea: We just need to define precedence. I'd argue for using the color
       meaning of 'none', but I don't care too much
  lea: Main thing I care about is that 'none' values are not dropped
  lea: ChrisL suggests that this is just an editorial change, but
       Romain said it's not editorial; hence, running by the group

  ChrisL: I no longer think this is editorial. Main thing is preserving
          author intent. Coercing none to zero is an option of last
          resort if you're literally trying to draw 'none'
  ChrisL: Other cases, hue of 'none', does that mean they really want a
          bright magenta red? No.
  ChrisL: we're seeing people comment on this in implementations,
          people complaining about why-are-they-getting-a-red-
          arbitrarily
  ChrisL: Regardless of the mechanics, the general thing of "we need to
          preserve this value unless we can get rid of it" is the main
          thing. we can talk about ways to achieve it separately if
          needed
  <TabAtkins> +1 to preserving none. I think it's probably fine to
              treat `clamp()`'s none as the color none in RCS.
  <TabAtkins> (Because, as noted, you can always write
              `clamp(-infinity, val, infinity)` instead.)

  Romain: I was wondering if this is implementable. I assume browsers
          have an internal representation of color that's channel
          values, but with this proposal you need to preserve much more
          information about how the color was specified
  Romain: I think this would be very surprising when you move this
          across color spaces. When you write: [...]
  <Romain> calc(none + 0.2)
  Romain: if you write this^ in LCH or oklch, the 0.2 has a different
          scale in both. But if you switch color spaces, it gets
          preserved and not converted, and that can be surprising
  Romain: not an absolute blocker, but does have sharp edges
  lea: RE implementability, browsers have to do this with variable
       references already
  emilio: That's not how variable reference works; they're substituted
          before parsing
  emilio: You don't have a concept of a calc with variable references;
          you have a string with variable references substituted
  lea: My point is that not every component actually resolves. Even in
       rel color syntax, you keep the values of the base color [??]
  <ChrisL> right but you don't have an immediately displayable color
  lea: Let's not conflate preserving none in color space conversions &
       in calculations
  lea: Converting between color spaces is a whole different beast;
       that's one of the reasons resolving to 0 was invented
  lea: don't want to convert none in a way that exposes color space
       conversion math
  <ChrisL> https://drafts.csswg.org/css-color-4/#analogous-components
  lea: The spec also has a part where if you're converting between two
       color spaces, where one component of first color space is
       largely orthogonal to the rest and related to a component in
       color space b, then swap the none out for zero, and then replace
       the none in that component [??]
  lea: let's discuss the color space conversion separately; it's hairy

  emilio: I agree that preserving 'none' in some way makes sense
  emilio: I was going to say something similar to Romain
  emilio: When you mix 'none' in more complex calculations... have you
          given thought to making 'none' more similar to how NaN works?
          as soon as you mix something with 'none', it remains 'none'
          instead of being an expression involving 'None'?
  <ChrisL> We invented none because the spec said NaN and tab told us
           not to :)
  emilio: that would be less complex to implement. Interpolating
          without having to [...] transforms have such a thing, where
          you have to keep them as a mix that isn't simplified
  emilio: that seems like a less confusing model, where doing math with
          'None' gives you 'None'
  ChrisL: That's what the spec used to say; it used NaN explicitly
  ChrisL: Tab suggested we use a special value, which is where None
          came from
  TabAtkins: My argument against NaN was for other reasons, unrelated
             to infectiousness
  <TabAtkins> (We shouldn't use NaN to indicate "no channel value"
              because NaN *also* comes from simple math errors. We
              didn't want "author made a math error" to accidentally
              also trigger "this channel is powerless and should be
              taken from the opposing color". The infectiousness wasn't
              a part of this.)
  Lea: Infectious none is actually worse than converting it to 0. E.g.
       clamp(50, none, 60) is conceptually very different than none,
       you're basically saying "I want the component of the other
       color, but it needs to be within this range. Converting the
       whole component to none in that case could even harm
       accessibility, if the constraint was there to e.g. ensure
       sufficient contrast.
  lea: infections 'none' is worse than converting it to zero
  lea: if you have an expression clamping 'none' to 50 or 60, the
       author wants it to be in this range
  <ChrisL> https://github.com/w3c/csswg-drafts/issues/6107
  lea: if you convert the whole thing to none, then that can harm a11y

  Romain: This is still related to color space conversion because the
          spec says you have to convert to the same color space when
          doing interpolation
  ChrisL: That's correct, because of missing components

  chrishtr: What does calc(none + 20) resolve to?
  lea: That's well-defined in the issue. calc(none+20) -- the none
       would become the value of that component in another color, and
       then you add 20
  lea: get the lightness of the other color, and then subtract 20
       from it
  lea: e.g. if you're trying to interpolate from a certain color to a
       darker version of it, regardless of what color you're starting
       with
  chrishtr: So that means zero is not the right number, in those
            use-cases
  <ChrisL> So setting hue to calc(none+180) gives you the complement of
           the other color, when interpolating for example
  lea: Correct, zero is almost never the right number

  ChrisL: I've got a suggested resolution for what we want to achieve,
          it sounds like we have consensus on that?
  ChrisL: "don't get rid of none and replace it with zero unless you
          absolutely have to, e.g. if you're forced to use it as a used
          value"
  lea: That might be all we need?
  emilio: I agree
  <lea> I wonder if implementations could even internally rewrite to
        RCS, in some ways it's like a late-resolving RCS
  emilio: I sort of want to review the proposed changes with more
          detail; the details of how you do that might be a bit tricky
  lea: Proposed: None is preserved in calculations involving css math
       functions
  lea: ...and also when interpolating between values containing 'none'
       and values not-containing-none
  <ChrisL> +1

  RESOLVED: `none` is preserved in calculations involving CSS math
            functions

  <lea> When interpolating between two none-containing values, the
        result is a calc-mix() expression preserving the `none` values
        in both values
  PROPOSED: ^
  <ChrisL> +1
  <lea> PROPOSED: When interpolating between two none-containing
        values, the result is a calc-mix() expression preserving the
        `none` keywords in both values
  dholbert: Do we need to cover interpolating between none/not-none?
  lea: That's already defined

  flackr: I see in the issue description that there's also a proposal
          that 'none' resolves to the other component, if the other
          component is not none-containing
  lea: That's already how none works / what none does
  Romain: That's not true; it's not a placeholder for the other
          channel. It makes a channel missing
  Romain: it's not like the nesting selector where it's a placeholder
          for the parent
  Romain: This would be a new mechanic. I'm fine with it being a new
          mechanic, but we should call it that
  ChrisL: That's already in the spec?
  Romain: That's related to color components
  flackr: I'd like to know what's used in the other end of the
          interpolation. Pulling the color from the other end isn't
          what authors would expect
  <TabAtkins> That is actually intended behavior, yes
  flackr: If you're pulling from 2 color values and a none in the
          middle, pulling from two color values at the ends isn't what
          authors would expect
  lea: That's an orthogonal issue and what happens today
  Rossen: Objections?

  RESOLVED: When interpolating between two none-containing values, the
            result is a calc-mix() expression preserving the `none`
            keywords in both values

Received on Thursday, 25 April 2024 23:47:17 UTC