[csswg-drafts] [css-grid][css-align] How items with synthesized baseline affect the size of intrinsic tracks

mrego has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-grid][css-align] How items with synthesized baseline affect the size of intrinsic tracks ==

Let's try to explain an issue we're hitting while trying to implement baseline alignment on CSS Grid Layout.

The example is a bit complex, so let's go step by step:
```html
<div style="display: grid; width: 200px; height: 200px;
            grid: auto 50px / 100px 100px; border: solid thick;
            align-items: baseline;">
  <div style="font: 25px/1 Monospace; background: magenta;">
    First<br>item
  </div>
  <div style="writing-mode: vertical-lr;
              font: 25px/1 Ahem; background: cyan;">
    XX X X X X X
  </div>
  <div style="grid-column: span 2; align-self: stretch;
              background: rgba(255, 255, 0, 0.5);">
  </div>
</div>
```

Columns have a fixed size, so we don't need to care about them.

Regarding rows, on the first run of the grid track sizing algorithm, to calculate the size of the first row it checks the heights of the items inside:
* 1st item (magenta) has a 50px height.
* 2nd item (cyan) is vertical, so its height has a range between 50px (the min-content size) and 300px (the max-content size).

As the 2nd row has 50px and the grid container has a fixed height of 200px, the 1st row ends up being 150px tall.

![Status of the grid after the first pass](https://cloud.githubusercontent.com/assets/11602/25994215/56ef8340-370d-11e7-94e2-3e6d87497a00.png)

Until here everything seems pretty clear. Let's move to the funny part.

Now we calculate the baselines to apply the alignment to the items in the first row.
* 1st item (magenta) baseline is 25px (height of the first line).
* 2nd item (cyan) as is vertical we use the [synthesized baseline](https://drafts.csswg.org/css-align/#synthesize-baselines), so the bottom of the element 150px.

We take the biggest one 150px baseline and calculate the baseline offsets:
* 1st item (magenta) 150px - 25px = 125px. We add [a kind of 125px margin](https://drafts.csswg.org/css-align/#baseline-self-alignment) to the item.
* 2nd item (cyan) 150px - 150px = 0px. No changes here.

![Status of the grid when we apply baseline alignment](https://cloud.githubusercontent.com/assets/11602/25994223/61544320-370d-11e7-9b56-4105952e8cd9.png)

Here the [min-content contribution of the first item has changed](https://drafts.csswg.org/css-grid/#algo-overview), before it was 50px, and now it's 175px = 125px (the baseline offset) + 50px (its height). So we've to do a new run of the algorithm.

In this second run to compute the size of the first row we do:
* 1st item (magenta) has a 175px "height" now (it's not really its height but its min-content contribution due to the baseline alignment).
* 2nd item (cyan) has a range between 50px and 300px.

The first row has to be now 175px height, the 2nd row is fixed so it has 50px height and it overflows the container (not a big deal as that's what happens in similar cases without baseline alignment).

Problem comes now, what should we do at this point?

### Option 1)

Following the approach above, we'd recompute the baselines offests:
* 1st item (magenta) the baseline is 150px = 125px (from the previous run) + 25x (height of the first line).
* 2nd item (cyan) this item has now a height of 175px, so 175px.

The biggest baseline is 175px so we calculate the offsets again:
* 1st item (magenta) 175px - 150px = 25px. We move the item down 25px more.
* 2nd item (cyan) 175px - 175px = 0px. We don't do any change.

Then we'd stop, as the algorithm just ask to repeat it only once.
The result would be:
* 1st row: 175px.
* 2nd row: 50px, overflowing the grid container.
* 1st item (magenta): 50px height (with a 150px baseline offset), overflowing the 2nd row.
* 2nd item (cyan): 175px height, no oveflow.

![Status of the grid following option 1](https://cloud.githubusercontent.com/assets/11602/25994178/29ebc5e8-370d-11e7-80c4-08a2d24f665f.png)

### Option 2)

We avoid to recompute the baselines and reuse the biggest one from the previous run, which was 150px.

Then we calculate the new offsets:
* 1st item (magenta) 150px - 150px (current "height") = 0px. We don't move it further.
* 2nd item (cyan) 150px - 175px (current height) = -25px. We move it up 25px.

Again, this is the 2nd run so we stop at this point.
The result would be:
* 1st row: 175px.
* 2nd row: 50px (overflowing the grid container).
* 1st item (magenta): 50px height (with a 125px baseline offset), not overflowing the 2nd row.
* 2nd item (cyan): 175px height (with a -25px baseline offset), overflowing the 1st row on the top and not reaching the bottom of the row.

![Status of the grid following option 2](https://cloud.githubusercontent.com/assets/11602/25994478/43991f12-370e-11e7-89e2-c5cc06a8a36e.png)

### Option 3)

As a last resort we could think on a different approach that would be to ignore the items with synthesized baseline. So in this case both items will be on the top of the first row and have a height of 50px and 150px (so the row would be 150px). But probably we don't want this.

What do you think?


Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/1365 using your GitHub account

Received on Friday, 12 May 2017 11:37:48 UTC