- From: Dael Jackson <daelcss@gmail.com>
- Date: Thu, 25 Apr 2024 19:46:44 -0400
- To: www-style@w3.org
========================================= 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