Bug 224538 - [css-grid] last-baseline shouldn't affect baseline alignment
Summary: [css-grid] last-baseline shouldn't affect baseline alignment
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-04-14 03:47 PDT by zsun
Modified: 2021-04-21 06:34 PDT (History)
11 users (show)

See Also:


Attachments
Patch (7.98 KB, patch)
2021-04-14 11:55 PDT, zsun
no flags Details | Formatted Diff | Diff
Patch (5.99 KB, patch)
2021-04-16 02:57 PDT, zsun
no flags Details | Formatted Diff | Diff
Patch (7.14 KB, patch)
2021-04-19 01:49 PDT, zsun
no flags Details | Formatted Diff | Diff
Patch (9.27 KB, patch)
2021-04-20 05:18 PDT, zsun
no flags Details | Formatted Diff | Diff
Patch (8.57 KB, patch)
2021-04-21 03:36 PDT, zsun
no flags Details | Formatted Diff | Diff
Patch (8.61 KB, patch)
2021-04-21 04:22 PDT, zsun
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description zsun 2021-04-14 03:47:03 PDT
Spec link:
https://github.com/w3c/csswg-drafts/issues/5293

A couple of subtests have failed in css/css-grid/alignment/grid-baseline-004.html after an update from 
https://github.com/web-platform-tests/wpt/commit/e3698c7bb3c309df69134e9bc0a375f00535e226
Comment 1 zsun 2021-04-14 11:55:05 PDT
Created attachment 426028 [details]
Patch
Comment 2 Javier Fernandez 2021-04-16 00:52:32 PDT
Comment on attachment 426028 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426028&action=review

> Source/WebCore/rendering/RenderGrid.cpp:1246
> +    return isBaselinePosition(align) && align != ItemPosition::LastBaseline && !hasAutoMargins;

I don't think this is correct. The purpose of this function was to determine whether a grid item has or not a value for the CSS Box Alignment properties that may imply it participates in baseline alignment (this would depend on other factors too). Hence, last-baseline is a valid value for this purpose.

If I've understood the CSS WG resolution, what we want is to prevent last-baseline to affect how we compute the grid container's baseline, which the algorithm described in the spec states that we should consider grid items participating in baseline alignment "along the first row". That indeed implies excluding items with last-baseline value, but only for this specific purpose. 

I'd rather add the logic to exclude the last-baseline value as part of the algorithm implemented in  RenderGrid::firstLineBaseline.
Comment 3 zsun 2021-04-16 02:57:52 PDT
Created attachment 426201 [details]
Patch
Comment 4 zsun 2021-04-16 02:58:23 PDT
(In reply to Javier Fernandez from comment #2)
> Comment on attachment 426028 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=426028&action=review
> 
> > Source/WebCore/rendering/RenderGrid.cpp:1246
> > +    return isBaselinePosition(align) && align != ItemPosition::LastBaseline && !hasAutoMargins;
> 
> I don't think this is correct. The purpose of this function was to determine
> whether a grid item has or not a value for the CSS Box Alignment properties
> that may imply it participates in baseline alignment (this would depend on
> other factors too). Hence, last-baseline is a valid value for this purpose.
> 
> If I've understood the CSS WG resolution, what we want is to prevent
> last-baseline to affect how we compute the grid container's baseline, which
> the algorithm described in the spec states that we should consider grid
> items participating in baseline alignment "along the first row". That indeed
> implies excluding items with last-baseline value, but only for this specific
> purpose. 
> 
> I'd rather add the logic to exclude the last-baseline value as part of the
> algorithm implemented in  RenderGrid::firstLineBaseline.

Code updated. Thank you!
Comment 5 Darin Adler 2021-04-17 20:59:15 PDT
Comment on attachment 426201 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426201&action=review

> Source/WebCore/rendering/RenderGrid.cpp:1272
> +            if (isBaselineAlignmentForChild(*child) && !(alignSelfForChild(*child).position() == ItemPosition::LastBaseline || justifySelfForChild(*child).position() == ItemPosition::LastBaseline)) {

Is this the most elegant way to write it? I have trouble understanding the code. Also, consider the Demorgan’s Law equivalent:

    if (isBaselineAlignmentForChild(*child) && alignSelfForChild(*child).position() != ItemPosition::LastBaseline && justifySelfForChild(*child).position() != ItemPosition::LastBaseline) {

Maybe another named helper function like isBaselineAlignmentForChild could make the code more readable, although I don’t know what I’d name it.
Comment 6 zsun 2021-04-19 01:49:49 PDT
Created attachment 426399 [details]
Patch
Comment 7 Javier Fernandez 2021-04-19 10:41:40 PDT
Comment on attachment 426399 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426399&action=review

> Source/WebCore/rendering/RenderGrid.cpp:1277
> +            if (isBaselineAlignmentForChild(*child) && !iSelfAlignmentForChildAtLastBaseline(*child)) {

If you let me suggest something, I'd rather create a new function in GridBaselineAlignment.h for checking only first-line baseline (although such keyword doesn't exist formally in the spec). Then, we can pass that function as an argument for RenderGrid::isBaselineAlignmentForChild (perhaps use a template here ?). Something like this:

static inline bool isFirstBaselinePosition(ItemPosition position) { return position == ItemPosition::Baseline; }

template <typename F>
bool RenderGrid::isBaselineAlignmentForChild(const RenderBox& child, F isBaseline) const;

template <typename F>
bool RenderGrid::isBaselineAlignmentForChild(const RenderBox& child, GridAxis baselineAxis, F isBaseline) const;

Then, we can make the non-template versions of these 2 methods so that they use the "isBaselinePosition" function we already have. This way we don't need to apply any change on the many callers of isBaselineAlignmentForChild. 

For the case we are changing the behavior in this patch, we would use the new isFirstBaseline call we are defining now.
Comment 8 zsun 2021-04-20 05:18:33 PDT
Created attachment 426539 [details]
Patch
Comment 9 Javier Fernandez 2021-04-20 14:05:15 PDT
Comment on attachment 426539 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426539&action=review

> Source/WebCore/rendering/RenderGrid.cpp:1236
> +bool RenderGrid::isBaselineAlignmentForChild(const RenderBox& child, F isBaseline) const

As we discussed privately, perhaps this approach is not the ideal one. We can achieve the same using an enumeration instead of the function argument, so that we can figure whether first baseline, last baseline or both are valid values. 
We can define the new argument to default to "both", which is the common case and it'd avoid to change any of the other callers. What do you think ?
Comment 10 zsun 2021-04-21 03:36:44 PDT
Created attachment 426665 [details]
Patch
Comment 11 Radar WebKit Bug Importer 2021-04-21 03:47:14 PDT
<rdar://problem/76948720>
Comment 12 Javier Fernandez 2021-04-21 04:19:52 PDT
Comment on attachment 426665 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426665&action=review

r=me

> Source/WebCore/rendering/RenderGrid.cpp:1246
> +    bool isBaseline = allowed == FirstLine? isFirstBaselinePosition(align) : isBaselinePosition(align);

nit: there must be a space between FirstLine and the "?" symbol.
Comment 13 zsun 2021-04-21 04:22:01 PDT
Created attachment 426670 [details]
Patch
Comment 14 EWS 2021-04-21 06:34:20 PDT
Committed r276356 (236834@main): <https://commits.webkit.org/236834@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 426670 [details].