Rego’s Everyday Life

A blog about my work at Igalia.

Grid Layout Summertime

Summer season is over and despite of some nice holidays to rest, the Igalia team kept doing progress on the CSS Grid Layout implementation in Chromium/Blink and Safari/WebKit as part of our ongoing collaboration with Bloomberg.

By the end of September the spec has transitioned to Candidate Recommendation (CR), Rachel Andrew wrote a blog post explaining what does it mean. However in the previous months there were a few changes here and there that require the implementations to get updated.

If you remember my presentation on the last BlinkOn we were reviewing the status of the implementation. By that time there were a bunch things marked as WIP or TODO, but now most of them have been already implemented as I’ll explain in this post.

Auto repeat #

My mate Sergio Villar already explained this feature thoroughly in a blog post so I won’t repeat it.

The new thing is that auto-fit keyword implementation has already landed, so you can use it too. auto-fit allows you to collapse the tracks that doesn’t contain any item.

So now you can do something like this:

<div style="display: grid; width: 700px;
grid-template-columns: repeat(auto-fit, 150px); grid-template-rows: 100px;
"
>

<div style="grid-column: 1 / span 2;">grid-column: 1 / span 2</div>
<div style="grid-column: 4;">grid-column: 4</div>
</div>
auto-fit example `auto-fit` example

In the example, there’s room for 4 columns of 150px however as the third column doesn’t have any item, so it’s collapsed to 0px, and you end up like having only 3 columns on your grid container. If you were using auto-fill keyword, the 3rd column won’t be collapsed and it will remain empty.

Multiple tracks #

One of the changes on the spec was adding the possibility to specify more than one track in some of the properties: grid-auto-columns & grid-auto-rows and repeat() notation.

So for example you can now pass a track list to the grid-auto-columns property like:

<div style="display: grid;
grid-auto-columns: 200px 50px; grid-template-rows: 100px;
"
>

<div style="grid-row: 1;">A</div>
<div style="grid-row: 1;">B</div>
<div style="grid-row: 1;">C</div>
<div style="grid-row: 1;">D</div>
</div>
Multiple tracks on grid-auto-columns example Multiple tracks on `grid-auto-columns` example

As you see the first and third columns will have a 200px width, and the second and fourth ones will have a 50px width.

On top of that, you can also use a track list on the repeat() notation:

<div style="display: grid;
grid-template-columns: repeat(3, 200px 50px); grid-template-rows: 100px;
"
>

<div style="grid-row: 1;">A</div>
<div style="grid-row: 1;">B</div>
<div style="grid-row: 1;">C</div>
<div style="grid-row: 1;">D</div>
<div style="grid-row: 1;">E</div>
<div style="grid-row: 1;">F</div>
</div>
Multiple tracks on repeat() notation example Multiple tracks on `repeat()` notation example

This seems a small change, and it was not very hard to implement. However, this combined with the auto repeat feature required a few more changes than expected to make everything work properly.

fit-content() cap #

fit-content keyword has been updated and now you can pass an argument to it that is used as a maximum size. As an argument for the fit-content() function you can specify either a length or a percentage (that will be resolved like for percentage tracks).

So in Grid Layout now you can use fit-content(argument) and the track size will be clamped at the argument:

<div style="display: inline-grid;
grid-template-columns: repeat(2, fit-content(200px)); grid-template-rows: 100px;
"
>

<div>an item</div>
<div>a very long grid item</div>
</div>
fit-content() function example `fit-content()` function example

As you can see the first column uses fit-content so its size is adapted to the item inside. However the second column would need more than 200px in order that the whole item fits, so its size is clamped to 200px.

Percentage support for grid gutters #

Grid gutters have been added a while ago into the different implementations, but we were lacking support for percentage gaps.

We’ve been updating the implementation so now you can use percentages too (again they’re resolved like percentage tracks):

<div style="display: grid; width: 400px;
grid-column-gap: 10%;
grid-auto-columns: 1fr; grid-auto-rows: 100px;
"
>

<div style="grid-row: 1;">A</div>
<div style="grid-row: 1;">B</div>
<div style="grid-row: 1;">C</div>
<div style="grid-row: 1;">D</div>
</div>
Percentage gaps example Percentage gaps example

The 10% column gap is resolved against the width of the grid container to 40px. Then the 1fr tracks take the available space, which in this case means 70px for each column.

The percentage support for grid gaps is marked as at-risk in the spec, however it has been already implemented in Gecko and Blink, so probably it won’t be removed from this level.

New syntax for grid shorthand #

The grid shorthand syntax has been modified so now you can specify in just one property, the explicit grid in one axis and the implicit grid and the auto-placement algorithm mode in the other one.

For example, if you want a grid that has 2 columns of a given size and the rows will be created on demand, you could use the following syntax:

<div style="display: grid;
grid: auto-flow 100px / 200px 100px;
"
>

<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
<div>E</div>
</div>
grid shorthand example `grid` shorthand example

Orthogonal flows #

Orthogonal flows refers to situations when the writing mode of the grid container uses a different direction than some of its items. For example, if you have a horizontal grid container and some vertical items inside it.

This has been a long task but right now you can use orthogonal flows on grid layout already. The basic support has been implemented including alignment of orthogonal items.

So now you can use vertical items inside a horizontal grid layout:

<div style="display: inline-grid;">
<div style="grid-row: 1;">Test</div>
<div style="grid-row: 1; writing-mode: vertical-lr;">Chrome</div>
<div style="grid-row: 1; writing-mode: vertical-lr;">Firefox</div>
<div style="grid-row: 1; writing-mode: vertical-lr;">Safari</div>
<div>test-1.html</div><div></div><div></div><div></div>
<div>test-2.html</div><div></div><div></div><div></div>
</div>
Orthogonal flows example Orthogonal flows example

New normal value for alignment properties #

This is a pretty complex issue from the specs and implementations point of view (as you can see in the epic review for this patch), but probably not very important for the end users because the default behavior on Grid Layout won’t be altered. Now there’s a new value normal for the alignment properties: justify-content, align-content, justify-items, align-items, justify-self and align-self.

The interesting thing regarding this new normal value is that it behaves differently depending on the layout model. In general, the behavior in the Grid Layout case is the same than when you use the stretch keyword.

Conclusion #

This is just a high level overview of the main things that happened during the summer on the Blink and WebKit implementations leaded by Igalia. Of course, I’m missing some much more stuff like lots of bug fixes and even performance optimizations (e.g. nested grids are now 350% faster than before).

Maybe for some of you some of these changes are really great, maybe for other they’re not very relevant. Anyway the good news are that things keep moving forward, and the implementations are getting closer and closer to the specification. This means that we’re on the right path to have CSS Grid Layout enabled on most of the main browsers soon.

Igalia logo Bloomberg logo
Igalia and Bloomberg working together to build a better web

Last, but not least, as usual we’d like to thank our friends at Bloomberg for all their amazing support which allows us to keep pushing Grid Layout.

Translations #