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>
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>
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>
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>
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>
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>
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>
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.
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 #
- Russian (March 17, 2017): Как грид-раскладка (Grid Layout) провела лето