W3C

Bert Bos | A Walkthrough of CSS Grid

A Walkthrough of CSS Grid

Cascading Style Sheets

Bert Bos (W3C) <bert@‌w3.org>

Presented at:
CWI / W3C Benelux Office
Amsterdam, Netherlands
15 June 2017

Motivating example: GUI

CSS Grid is designed for making GUIs:

Both the overall layout
and individual components.

Easy to change layout,
e.g., for narrow screen
or landscape/portrait.

Main characteristics (1/3)

Row & column sizes can be:

Main characteristics (2/3)

Using numbers is probably easiest when style rules are generated by a program. There is probably already some loop variable that has the right value, so no need to translate that to a name.

Using names is probably easiest when writing style rules by hand. More readable and less chance of mistakes, especially if you change a grid, or add another for different screen dimensions.

Whether to use names for areas or names for lines (or both) is probably just a matter of taste. Named areas lead to shorter and easier to read style rules than named lines, as long as the grid isn't too big and has no, or few, overlapping areas.

Main characteristics (3/3)

An item can be vertically and horizontally aligned within its slot.

Two items in the same area will overlap (see also limitations below), but you can control which is on top with ‘z-index’.

Abbreviated syntax for very large grids
grid: 1fr 1fr 1fr / repeat(18, 1fr)

Some terminology (1/2)

* unless absolutely positioned

Some terminology (2/2)

explicit = template implicit = auto

Accessibility

Grid items can be placed anywhere in the grid.

But navigation is still based on source order, not visual order.

Make sure the source order is logical!

(If needed, you can also transform the DOM first.)

Direction and writing-mode

Grids are oriented depending on 'direction' and 'writing-mode'

(I.e., like tables, but unlike absolute positioning or floats.)

(Floats will soon offer a choice between physical and relative directions.)

→ if you have text in Arabic or Hebrew scripts, you may need to add an explicit DIR=ltr on the grid element (and then reset to DIR=rtl on the grid items), otherwise the whole GUI may end up mirrored.

In some cases, mirroring is in fact the right thing to do. E.g., a grid of photo thumbnails may well start at the top right and fill rows from right to left in an Arabic context and labels may be to the left of checkboxes, But many parts of a GUI do not change place.

Making a grid container

display: grid or display: inline-grid

The Display Module is meant to enhance the 'display' property to allow sepate specification of ‘outside’ and ‘inside’ aspects of boxes. The idea is to say, e.g., that an element can act as a table cell on the outside and as a grid on the inside. But not so many display values can be cleanly split and after many years of trying various models and syntaxes, we're still not sure it's actually useful. Also, because grid is meant for GUIs and requires a specific document structure on its inside already, it is probably not a big deal to say that, to put a grid inside a table cell, you'll have to make a tree that has actual table cell element around the grid….)

Grid items

Aligning grid items

By default, grid items fill their area (‘stretch’).

For 'baseline', see further down.

You can also set alignment on all items together with ‘justify-items’/‘align-items’ on the grid container.

'normal' and 'stretch' are the same, except on replaced elements. 'Auto' is usually the same as 'normal', unless the grid container has a 'justify-items' property other than 'auto' or 'normal'.

The size of grid items

The order of automatic placement

The order property applies to grid items
unless they have an explicit position ('grid-area').

When unplaced items are assigned to empty slots,
items with lowest order are placed first.

Z-index of grid items

Z-index applies to grid items

By default, if items overlap, the document order determines the z-order: later items on top.

Defining the explicit grid (1/3)

grid-template-rows, grid-template-columns, grid-template-areas or use the shorthand grid

A grid with 3 rows and 2 columns:
grid: 10px auto 1fr / auto 3em

Ditto, but with limits on the first column:
grid: 10px auto 1fr / minmax(2em,15em) 3em

A grid with 18 columns, the first 17 of equal width:
grid: 10px auto 1fr / repeat(17, 1fr) 5em

Defining the explicit grid (2/3)

A grid with 6 named areas, 3 empty areas and all sizes 'auto'
(An area name consisting only of dots indicates an unused area)

grid: "a1      a2   a2    a3"
      "left    left right right"
      "my-slot ...  ...   ..." 

Ditto with explicit sizes:

grid: "a1      a2    a2    a3"     10px
      "left    left  right right"  auto
      "my-slot ...   ...   ..."    1fr
      / 1fr    1fr   1fr   1fr

Defining the explicit grid (3/3)

Defining how the grid grows (1/4)

The grid grows automatically if

The final grid, including these additional grid cells is called the implicit grid

Defining how the grid grows (2/4)

The 'grid' shorthand allows to specify either

If you need a combination, you'll need to use the longhand properties.

Defining how the grid grows (3/4)

Example: example
grid: auto-flow auto 1em / repeat(10, 5em)

Above is equivalent to:

grid-template-columns: repeat(10, 5em);
grid-auto-rows: auto 1em;
grid-auto-flow: row  /* default */

Defining how the grid grows (4/4)

Example:example
grid: 50px auto auto / auto-flow 6em 4em

Above is equivalent to:

grid-template-rows: 50px auto auto;
grid-auto-columns: 6em 4em;
grid-auto-flow: column

Dense filling

By default, grid items are placed in order: each grid item without an explicit placement is either placed to the right of or below its immediate predecessor (whether automatically placed or not).

If you set replace auto-flow by auto-flow dense, the UA will put grid items without an explicit placement in the earliest possible free area that fits. I.e., such items may end up before a preceding sibling.

E.g., if there is a free slot of size 1x1 and one of 2x1, and two auto-placed items, one of 2x1 and one of 1x1, the first goes into the larger free slot and the second into the smaller.

Placing grid items (1/2)

Into a named area:
grid-area: a2

Into a single cell:
grid-area: 2 / 3 /* 2nd row 3rd column */

Into a span of cells:
grid-area: 2 / 3 / 4 / 7
or:
grid-area: 2 / 3 / span 2 / span 4

Placing grid items (2/2)

Assume
grid: [a-line] 10px [mid] 1fr [b-line] / [lft] auto [rgt]

Now a-line=1, mid=2, b-line=3, lft=1, rgt=2, thus
grid-area: mid / lft / b-line / rgt
puts the item in the 2nd row.

Ambiguous names of areas and lines

An area and a line may have the same name
and multiple lines may have the same name. E.g.:

grid: "      w       x       y       z"      1fr
      "      v       v       v       v"      1fr
      / [v] 1fr [v] 1fr [v] 1fr [v] 1fr [v];

has an area ‘v’ and 5 vertical lines called ‘v’. example

Names are first searched among areas, then among lines. If there are multiple lines, add a number to indicate which you mean:

grid-area: v / v 2

area

2nd line

Auto-placement with a given size

Grid items without grid-area (or grid-area: auto) are automatically placed in the next free cell.

To give auto-placed items a specific size:
grid-area: span 2 / span 5
finds the next free slot that has size for a cell of 2 rows high and 5 columns wide.

Gaps

Adding empty space between rows and columns (by default none):

grid-row-gap: 2ex;
grid-column-gap: 0.3em

or

grid-gap: 2ex 0.3em

Note: If you use the grid shorthand, set the gap after the grid, because the shorthand resets all properties, including the gap

Baseline alignment

Just as table cells, grid items can be baseline-aligned:
align-self: baseline example

Use for documents

The (deeply nested) structure of documents rarely matches what Grid expects, but if it does, just use it!

Some of the limitations:

The end

https://www.w3.org/Talks/2017/0615-CSS-Amsterdam

W3C

To Lead the Web to its full potential

To Anticipate the Trends

To Increase your company value

Join W3C

https://www.w3.org/Consortium/join

or contact: Annette Kik or Bernard Gidon

Bert Bos <bert@w3.org>
GPG fingerprint: 7744 0204 52A5 14D9 147D
2A13 2D7A E420 184B 5BA4

Front-End Developer New! Front-End course on W3Cx!