NEW 232421
min() function sometimes returns larger of two values instead of smaller, depending on the units used
https://bugs.webkit.org/show_bug.cgi?id=232421
Summary min() function sometimes returns larger of two values instead of smaller, dep...
Brandon McConnell
Reported 2021-10-27 21:58:22 PDT
Created attachment 442673 [details] Screenshot of overflow issue caused when Safari miscalculates the min() function Working with a CSS Grid, the contents of the grid overflow from the parent, but it's not due to the typical grid overflow issue where setting each child's min-width/width/width properties forces the correct sizing. Instead, the issue actually appears to be with the computation of the `min()` function and the conversion of different units, namely % and vw. From my cross-browser testing, it appears this issue only affects Safari/WebKit. To reproduce the issue, follow these steps: 1. Visit https://www.petsupermarket.com/holiday-shop-toys-treats-gifts 2. Using the inspector, find the element matching selector `section#shop-holiday-by-pet` 3. Attached to that element, you'll find the styles `width: 100vw; max-width: 100%;`. That is a partial and temporary fix I added which appears to get Safari to render 90%+ correctly in most cases, with minimal overflow, though other browsers still have no overflow. That section, in particular, is supposed to extend past the viewport edge with and allow the end-user to scroll left and right in that section similar to how they would when interacting with a feature such as Instagram stories or Twitter Spaces/Fleets(legacy), but in this case, the element actual blows of the full document's width, causing the page to overflow and other elements to extend past the viewport edge as well. 4. Resize viewport width to a mobile size, (e.g. 400px). 5. Observe the minimal overflow. 6. Replace `width: 100vw; max-width: 100%;` for the desired style `width: min(100%, 100vw);`. 7. Observe how switching the style actually causes the section to grow in width, though using the `min()` function should always return the lowest value from a set of values, wherein this case, it actually returns the larger of the two, thereby growing the area.
Attachments
Screenshot of overflow issue caused when Safari miscalculates the min() function (53.27 KB, image/png)
2021-10-27 21:58 PDT, Brandon McConnell
no flags
Oriol Brufau
Comment 1 2021-11-01 12:03:47 PDT
There is probably a bug indeed, but more complex that min() returning the maximum by mistake. Note that `width: min(100%, 100vw);` and `width: 100vw; max-width: 100%;` are not completely equivalent. During intrinsic sizing, if the percentages are cyclic then the former should be treated as `width: auto`, and the latter as `width: 100vw; max-width: none`. https://www.w3.org/TR/css-sizing/#cyclic-percentage-contribution
Brandon McConnell
Comment 2 2021-11-01 13:31:22 PDT
Yes, I understand that `min()` takes the lowest value from a set of values, regardless of order. However, in this example, the `min()` function does in fact take the larger of the two values instead of the smaller. Manually evaluating `width: 100%` vs. `width: 100vw`, it can be observed that `width: 100vw` is the smaller of the two on mobile, yet when switching from `width: 100vw` to `width: min(100%, 100vw);`, the overall width of the element expands to the computed/intrinsic width of `100%` rather than the smaller width of `100vw`.
Brandon McConnell
Comment 3 2021-11-01 13:31:46 PDT
Yes, I understand that `min()` takes the lowest value from a set of values, regardless of order. However, in this example, the `min()` function does in fact take the larger of the two values instead of the smaller. Manually evaluating `width: 100%` vs. `width: 100vw`, it can be observed that `width: 100vw` is the smaller of the two on mobile, yet when switching from `width: 100vw` to `width: min(100%, 100vw);`, the overall width of the element expands to the computed/intrinsic width of `100%` rather than the smaller width of `100vw`.
Radar WebKit Bug Importer
Comment 4 2021-11-03 21:59:17 PDT
Note You need to log in before you can comment on or make changes to this bug.