Unlocking the Power of CSS Grid Layout

A presentation at Webconf.asia in June 2018 in Hong Kong by Rachel Andrew

Slide 1

Slide 1

@rachelandrew 
 Webconf.asia, June 2018 Unlocking the Power of 
 CSS Grid Layout

Slide 2

Slide 2

https://www.w3.org/TR/css-grid-2/

The CSS Working Group already have a first public working draft of Grid Level 2.

I have given up trying to answer all of the questions I get sent, instead trying to write articles that address those issues. It has however become very apparent where a lot of the issues people have with Grid originate.

The first of those is Sizing.

Slide 3

Slide 3

How big is that box? People are very confused about how big things are, and very confused about how grid and flexbox distribute space.

The reason it is confusing is that we have spent years using layout methods that are very straightforward when it comes to the size of items in our layouts.

We have sized things with length units, which make sense, be that pixels or ems or rems, we know what 100 pixels or 10 em means.

Slide 4

Slide 4

https://alistapart.com/article/fluidgrids

We have also sized things with percentages, using straightforward maths to figure out dimensions for flexible grids. Those percentages don’t look so pretty in our stylesheets, but they are understandable. We make sure we don’t end up with more than 100 % and everything will be ok.

Slide 5

Slide 5

https://twitter.com/devine_howest/status/959036561839960070

We got box-sizing: border-box and everything was made easier.

Slide 6

Slide 6

We got layout frameworks that even did all of the calculating for us.

Slide 7

Slide 7

https://www.smashingmagazine.com/2018/01/understanding-sizing-css-layout/ And then Flexbox and grid layout came along, and they seemed to behave a bit strangely. Elements in our designs became bigger or smaller than we thought they should.

The result being that people started to create flexbox based grids which used percentages, just like their floated forebears. With grid, the first thing most people seem to do is try to create layouts based on percentage, going back to what they know to work. Keeping away from the slightly mysterious fr unit, that never seems to quite do what they expect.

So I have pretty much declared this year as the year of “how big is that box”, because I think that understanding sizing is the route to finding solutions for layout patterns that we previously had to rely on JavaScript for. I’m not a JavaScript hater, but it makes me sad when it is invoked for things that we have CSS solutions for, and which can be done in a more straightforward way, a more performanant way in CSS.

Slide 8

Slide 8

How big is a grid? So lets have a look at how grid works out sizing, and learn some interesting and useful things along the way.

Slide 9

Slide 9

To learn about this we need to scroll way, way down the specification. Down to those bits that we web developers usually decide are for browser engineers, and ignore.

We get to the bit of the spec that defines the grid sizing algorithm.

And there we enter the rabbit hole, for to understand the grid sizing algorithm we need to know things about how we figure out how big things are in general.

And you’ll be glad to know I’m not going to line by line explain the algorithm to you today - if you have any questions after this talk come and ask me and I’ll have a go. Instead I’m going to highlight a few things that are interesting and useful about how grid works out sizing.

Slide 10

Slide 10

–11.1 Grid Sizing Algorithm “Each track has specified   minimum   and   maximum   sizing functions   (which may be the same).” https://drafts.csswg.org/css-grid-1/#layout-algorithm

The spec says that each track has specified minimum and maximum sizing functions (which may be the same). What are these?

Slide 11

Slide 11

❖ Fixed sizing: 
 lengths such as px or em, or a resolvable percentage

❖ An intrinsic sizing function 
 auto, min-content, max-content, fit-content

❖ A flexible sizing function 
 The fr unit https://drafts.csswg.org/css-grid-1/#layout-algorithm

There are three types of sizing we need to consider. Fixed sizing, Intrinsic Sizing or flexible.

Fixed sizing is something we are all familiar with, it’s how we’ve been doing layouts for years. Sizing things either as a length unit - be that pixels, ems or any other length. Percentages also fall into this type of sizing, as long as they can be resolved against something, for example a grid track sized as 20% resolves to a length which is 20% of the width of the grid container. Therefore when working out sizing resolvable percentages are treated in the same way as any other fixed length - even though we probably see them as flexible in our heads.

Next we have intrinsic sizing, you might be most familiar with auto, but we also have the specific intrinsic sizing keywords of min-content, max-content and fit-content.

Slide 12

Slide 12

Intrinsic Sizing auto Default size of grid tracks. Tracks sized auto

will stretch to take up space in the grid container. Auto when used for track sizing, can be generally thought of as being “big enough to fit the content”, we’ll look at what auto really means in a little more depth. However if you have ever created a grid with auto sized rows you will know that those rows expand to take the content you place into them, and do not cause overflows.

Something useful to know about auto and track sizing is that if you use auto for track sizing this will stretch by default, unlike the other sizing functions. Where you will tend to notice this is with column tracks.

Slide 13

Slide 13

https://codepen.io/rachelandrew/pen/ppYPZR

justify-content: start justify-content: stretch Therefore if this example I have used auto for the final column track. It is stretching to take up the remaining space in the inline direction, however the actual size created by the auto track, is what you see if you add justify-content: start to override that stretching behaviour.

This can make auto seem a bit mysterious in grid as it stretches by default.

Slide 14

Slide 14

Intrinsic Sizing: auto The auto-sized track will stretch in the inline direction.
Use justify-content: start to override the stretching behaviour. .grid { display: grid; grid-gap: 10px; grid-template-columns:
min-content
max-content
fit-content(10ch)

auto ; justify-content: start; } https://codepen.io/rachelandrew/pen/ppYPZR

So remember that the default for justify-content is stretch, and auto tracks will stretch. Don’t want that behaviour? Set justify-content start on the container or target the individual item with justify-item start.

We then have some new sizing keywords, these aren’t only for grid you can use them for sizing elsewhere. These keywords also form important concepts that we need to understand to understand how sizing is worked out.

Slide 15

Slide 15

Intrinsic Sizing min-content The smallest size the item can be, taking advantage of all soft-wrapping opportunities. You can use the keyword min-content for track sizing. This will make the track as small as it can be without the content breaking out of the track. In the case of a track containing text, the text will take all soft-wrapping opportunities, essentially becoming as wide as the longest word.

Slide 16

Slide 16

Intrinsic Sizing: min-content Grid tracks sized with min-content will become as small as they can without causing overflows. .grid { display: grid; grid-gap: 10px; grid-template-columns:

min-content min-content min-content ; } https://codepen.io/rachelandrew/pen/VyOpXj

In this example I have created three column tracks, all sized using min-content. Therefore the track content now impacts the track sizing, rather than us deciding how big the track will be, and then the content being forced into it.

Slide 17

Slide 17

https://codepen.io/rachelandrew/pen/VyOpXj

The word ‘columns’ is defining the size of track 1. This item has a width which defines the size of track 2 A 100px image defines the size of track 3 If any item in that track has a width of some sort, or contains something with a fixed width, then the size will be dictated by that width.

Slide 18

Slide 18

Intrinsic Sizing max-content The largest size the track can be, no soft- wrapping will occur. Overflows may happen. Using max-content for track sizing means that the track will get as big as it possibly can, based on the content or any width applied to items etc. The content will no longer wrap so you may get overflows if this causes the track to get larger than the space in the grid container.

Slide 19

Slide 19

Intrinsic Sizing: max-content Grid tracks sized with max-content will become as large as needed, and may overflow the grid container. .grid { display: grid; grid-gap: 10px; grid-template-columns:

max-content max-content max-content ; } https://codepen.io/rachelandrew/pen/xpNdxV

So here we have three tracks all sized with max-content, once again the browser needs to look at the content to determine the track sizes.

Slide 20

Slide 20

https://codepen.io/rachelandrew/pen/xpNdxV Tracks 1 and 2 need to be wide enough to fit the unwrapped text. A 100px image defines the size of track 3 You can see how the first and second tracks stretch out to the maximum size of content in that track. The second column track has an item with a width in it. The width of that item is constrained but the track it is in stretches wide enough for the longer content above to be at max-content.

Slide 21

Slide 21

Intrinsic Sizing fit-content Act like max-content until it reaches the passed in value. Then we have fit-content. This keywords acts like max-content, but you pass in a value. Once the track grows to that value it is clamped and won’t get larger than that.

Slide 22

Slide 22

Intrinsic Sizing: fit-content Grid tracks sized with fit-content will act like max-content until they hit the limit given. .grid { display: grid; grid-gap: 10px; grid-template-columns:

fit-content(10em) fit-content(10em) fit-content(15ch) ; } https://codepen.io/rachelandrew/pen/Mrdobm

So I have 3 tracks here, the first two clamped at 10em that last one at 15ch - fifteen characters.

Slide 23

Slide 23

https://codepen.io/rachelandrew/pen/Mrdobm

Track 3 is 
 fit-content(15ch) Columns 1 and 2 are both 
 fit-content(10em). Track 1 wraps at 10em. Track 2 is max-content. Remember these concepts, as we’ll be seeing how they apply generally in a bit.

Slide 24

Slide 24

Flexible lengths Sizing with fr units The fr unit describes a flexible length Before that let’s look at the fr unit, which is a unit designed for grid layout.

Slide 25

Slide 25

Flexible lengths The fr unit is a <flex> unit and represents a portion of the available space in the Grid Container. .grid { display: grid; grid-gap: 10px; grid-template-columns: 2fr 1fr 1fr; } https://codepen.io/rachelandrew/pen/QaXvPe

It is a flex unit, defining a flexible length. A portion of the space in the grid container. If I define three tracks one of 2fr and 2 of 1fr. The available spaces divided into 4 and shared out, two parts to track 1, 1 part each to track 2 and 3.

Slide 26

Slide 26

https://codepen.io/rachelandrew/pen/QaXvPe

2fr 1fr 1fr Like this. Now this does lead people to believe that the fr unit shares out all of the space evenly, 12 tracks of 1 fr should be 12 equal tracks, not quite as we will see as we dig deeper.

Slide 27

Slide 27

Minimum & Maximum sizing functions So now we know the different ways we can size tracks, we can figure out the minimum and maximum sizing functions for each track.

Slide 28

Slide 28

minmax() The minmax() function is part of the grid layout specification, and gives us an easy way to start thinking about minimum and maximum sizing.

Slide 29

Slide 29

Minimum Sizing Function The minimum size for these two tracks is 100px, and 10em. .grid { 
 display: grid; grid-template-columns:
minmax(100px, auto) minmax(10em, 20em); } If you use minmax() for your track, then the minimum size of that track is the value used for the first value passed to minmax(). It won’t get smaller than that.

In this case 100px, or 10em.

Slide 30

Slide 30

Minimum Sizing Function The minimum size of these two tracks is auto. .grid { 
 display: grid; grid-template-columns:
10fr fit-content(10em); } If you use fr units or fit-content, then the minimum size of that track is auto.

Slide 31

Slide 31

Minimum Sizing Function The minimum size of the first track is 100px, the second track is 50px (10% of 500). .grid { width: 500px; 
 display: grid; grid-template-columns:
100px 10%; } Otherwise you used a length or a percentage, in which case the minimum sizing function is that length, or the percentage resolved to a length.

Slide 32

Slide 32

Maximum Sizing Function The maximum size for these two tracks is 400px, and 20em. .grid { 
 display: grid; grid-template-columns:
minmax(100px, 400px) minmax(10em, 20em); } If you use minmax() for your track, then the maximum size of that track is the value used for the second value passed to minmax(). It won’t get larger than that.

Slide 33

Slide 33

Maximum Sizing Function The maximum size for the first track is max-content. For the second track the maximum is 10em. .grid { 
 display: grid; grid-template-columns:
auto fit-content(10em); } If you used auto or fit-content then this should be treated as max-content, unless you have passed a value to fit-content in which case that becomes the max.

We now know what the minimum and maximum size of our tracks should be, and can work out how big our tracks are and ultimately how big our grid is.

Slide 34

Slide 34

https://codepen.io/rachelandrew/pen/aEgwKY

200px 200px 200px 200px 200px 620px 410px The simplest case will be if we have a fixed size for our tracks. The minimum and maximum sizing functions are the same as a length, or as a percentage which can be resolved to a length.

So in this example everything is a fixed size, nothing is intrinsically sized, or using an fr unit. We have tracks that are 200 pixels wide, 20 pixels tall and there is a gap of 10 pixels between each track.

So here is where pretty much all of our existing float based grid systems stop - everything in those systems is a fixed length, or a percentage.

Slide 35

Slide 35

https://codepen.io/rachelandrew/pen/goNRVp 200px 200px 200px 620px Auto sized row expands to make room for content However in most cases we will want to take advantage of the ability of grid to create flexible grids, or to use intrinsic sizing of some sort. At the very least we usually want to allows rows to grow to contain the content in them. We might used a fixed sized grid for our columns, but the simplest uses of grid tend to leave the rows to auto. Therefore the browser needs to work out how much space the row needs to fit the tallest item in the row.

Slide 36

Slide 36

https://codepen.io/rachelandrew/pen/BJgdKL Auto sized row expands to make room for content 1fr 1fr 1fr More likely I am going to want to use a flex sizing function, the fr unit to size my tracks, and allow the content to define the row height. This gets a bit more interesting in terms of working out the size of the rows.

Because after working out how much content there is and expanding the rows this may well have a knock on effect in terms of the size of 1fr.

Slide 37

Slide 37

What is a fr unit anyway? A track sized with 1fr, is actually sized minmax(auto, 1fr). The minimum size is auto. .grid { 
 display: grid; grid-template-columns: 1fr 1fr 1fr; } I mentioned earlier that having a set of 1fr tracks doesn’t quite mean they will be equal sized.

If the track is sized with fr units then it is as if we have used the following sizing function minmax(auto, 1fr). So the minimum size is auto.

Grid needs to give the tracks an auto minimum and then share out the remaining space in proportion. This means that in this example, we have three 1fr tracks, however they are not equal with, if I add a very long word, or something with a width defined to the first track the auto minimum is much larger for that track and we no longer have three equal width columns.

Slide 38

Slide 38

https://codepen.io/rachelandrew/pen/BJgdKL 1fr 1fr 1fr Like this.

Slide 39

Slide 39

What is a fr unit anyway? Make the minimum size 0, to force three equal width columns - even if that means overflows. .grid { 
 display: grid; grid-template-columns: 
 minmax(0,1fr) minmax(0,1fr) minmax(0,1fr); } Which leads us to a useful bit of knowledge. If you do want three equal tracks using fr units, then you need to make the minimum sizing function zero, by explicitly using minmax(0,1fr)

Slide 40

Slide 40

minmax(0,1fr) minmax(0,1fr) minmax(0,1fr) This then might cause overflows. Which is why the default is auto, as if there is space, we’re assuming you would rather the bigger thing got some space rather than overflowed.

However that can seem a little unintuitive if you were expecting 3 tracks of 1fr to be three equal sized tracks. It often turns out that way, but it isn’t quite what is happening.

So this seems like quite a lot of work if you think about it. The browser is having to work out what size it thinks the fr is, then look at the track and figure out what the minimum size of the content, then re-do the algorithm if that size has changed to make sure we are distributing space accordingly.

And that’s not all. Grid items don’t just span one track.

Slide 41

Slide 41

1fr 1fr 1fr Often a grid area spans several tracks, and therefore the content that can change the track sizing is spread over multiple tracks.

I’ve gone back to 1fr tracks here, which when our item containing the long word was placed into it make the first column track much wider. When we allow it to span two tracks, then the space it needs is over two tracks not one and so it can fit into 2 tracks, so the first track does not need to grow larger.

Slide 42

Slide 42

As many flexible columns as will fit Use auto-fill or auto-fit along with repeat and minmax, to create as many flexible columns with a minimum size as will fit into the container. .grid { display: grid; grid-gap: 10px; grid-template-columns:
repeat(auto-fill, minmax(200px, 1fr)); grid-auto-rows: 100px;
} https://codepen.io/rachelandrew/pen/WdVjdg

Then we have everyone’s favourite trick. The ability to add as many columns as will fit into the grid container by using repeat notation and the auto-fill and auto-fit keywords.

What is happening here might make more sense now we have looked at sizing. We are asking grid layout to auto fill as many column tracks as will fit in the container. We are handing out a minimum size of 200 pixels, so the columns won’t collapse smaller than that, and a maximum of 1fr. So 1fr of the available space.

Slide 43

Slide 43

https://codepen.io/rachelandrew/pen/WdVjdg

And so we can get nice arrangements of boxes,

Slide 44

Slide 44

https://codepen.io/rachelandrew/pen/WdVjdg Which will be responsive. And you can see we have these gaps in the arrangement.

Slide 45

Slide 45

Dense Packing Mode Using the value dense for grid-auto-flow will cause items to be displayed out of document order. .grid { display: grid; grid-gap: 10px; grid-template-columns:
repeat(auto-fill, minmax(200px, 1fr)); grid-auto-rows: 100px;
grid-auto-flow: dense; } https://codepen.io/rachelandrew/pen/ZvgKNY

So we can then set auto-flow to dense

Slide 46

Slide 46

https://codepen.io/rachelandrew/pen/ZvgKNY

So we are able to create a grid with a flexible number of flexible columns, and pack it densely, and the browser just does this for us. With a few lines of CSS. It’s magic.

There are so many creative possibilities here. Once we get anyway from always thinking of a grid as the Bootstrap-like 12 column grid, we have much more freedom to create interesting layouts.

Slide 47

Slide 47

Upside down and back to front Then there is something very important about grid layout. It really doesn’t matter which way up your grid is.

Slide 48

Slide 48

The grid-area property Order of the lines: • grid-row-start • grid-column-start • grid-row-end • grid-column-end .item { grid-area: 1 / 2 / 3 / 4; } My original CSS Grid presentation, long before grid shipped in browsers went through all of the properties for grid layout and explained them with demos.

I would explain that you could define all four lines of a grid are with the grid-area property and that the order of the lines was

grid-row-start

grid-column-start

grid-row-end

grid-column-end

This is the opposite of how we declare lines in everything else in CSS.

Slide 49

Slide 49

Logical Properties and Writing Modes The answer is that these values have moved away from the underlying assumption that content on the web maps to the physical dimensions of the screen, with the first word of a sentence being top left of the box it is in. The order of lines in   grid-area   makes complete sense if you had never encountered the existing way that we set these values in a shorthand. We set the two start lines first, then the two end lines.

This means that if we change the writing mode of our document to a vertical one, the position of a block remains relative to the writing mode of the document, rather than the physical properties of the screen.

Slide 50

Slide 50

Inline dimension or axis Horizontal Writing Mode Block
dimension 
 or axis In any writing system with a horizontal writing mode - whether the text is left to right like English or right to left like Arabic the inline dimension is along the rows of text left to right or right to left.

The Block dimension runs down the page top to bottom. You’ll sometimes see mention the inline or the block axis when working with grid or flexbox, and this is what it means. If something is being aligned on the block axis and you are working in a horizontal writing mode. The blog axis is the one that the blocks lay out on as they display down the block dimension of the page.

Slide 51

Slide 51

Block dimension
or axis Vertical Writing Mode Inline
dimension 
 or axis If we were working in a document with a vertical writing mode then the inline direction would be top to bottom, the block dimension running horizontally.

Slide 52

Slide 52

Inline axis Block axis Grid Layout in Horizontal Writing Mode We can see here how in grid layout, in a horizontal writing mode the inline axis runs horizontally and the block axis vertically.

Slide 53

Slide 53

flex-direction: row Main axis Cross axis flex-direction: column Cross axis Main
axis Flex Layout in Horizontal Writing Mode Flex layout is a little more complex in this regard because of the fact that we can have a flex-direction of row or column. In flexbox it makes more sense to refer to the main and cross axis.

The main axis is the one dictated by the flex-direction. By default this goes along the row (and therefore the inline axis)

The cross axis runs across down the columns (the block axis).

So we when are setting the start and end lines of a grid area, all we know is that we have start and end lines. We don’t actually know if we have top right bottom or left.

Slide 54

Slide 54

Horizontal LR So if this is my three column two row grid and I want a grid-area - in a horizontal, left to right writing mode - to cover the first two column and first two row tracks (click) like this.

Slide 55

Slide 55

Horizontal LR grid-row-start: 1 grid-row-end: 3 grid-column-start: 1 grid-area: 1 / 1 / 3 / 3; grid-column-end: 3 We can see the column and row start and end lines and how - in the grid area property we set both starts then both ends.

And if we are in a language like Arabic running right to left, it stats the same. However start is now on the right.

Slide 56

Slide 56

Horizontal RL grid-row-start: 1 grid-row-end: 3 grid-column-start: 1 grid-area: 1 / 1 / 3 / 3; grid-column-end: 3 We can see the column and row start and end lines and how - in the grid area property we set both starts then both ends.

And if we are in a language like Arabic running right to left, it stats the same. However start is now on the right.

Slide 57

Slide 57

Vertical LR grid-column-start: 1 grid-column-end: 3 grid-row-end: 3 grid-area: 1 / 1 / 3 / 3; grid-row-start: 1 And if we end up working with a writing mode that has our content running vertically, we have this.

The grid essentially works in the same way whichever way up it is. The line-based positioning works the same whichever way up it is.

Slide 58

Slide 58

The Firefox Grid Inspector You will find the Firefox Grid Inspector very useful here.

These are screenshots from Firefox of the example I just demonstrated. Firefox DevTools will add line numbers and a grid outline so you can see exactly how the positioning works.

Tomorrow you’ll be finding out much more about writing modes from Hui Jing.

Slide 59

Slide 59

Alignment and the Grid But now that we know how grid respects writing modes. Another area of confusion will hopefully make more sense.

How does alignment work in grid layout?

Alignment also considers the writing mode of the document and so we don’t think about left and right, top and bottom. We again think about start and end in each dimension.

Slide 60

Slide 60

❖ Align the tracks: 
 this requires extra space in the grid container

❖ Align the items 
 move content around inside the area it has been placed into We have two different things we might want to align in our grid layout.

The tracks themselves, assuming there is extra space in the grid container.

The items themselves.

Slide 61

Slide 61

Box Alignment Specification https://www.w3.org/TR/css-align-3/

Alignment is defined in the Box Alignment specification, rather than the grid layout spec.

Slide 62

Slide 62

Aligning tracks The tracks created on this grid do not fill the width and height defined on the grid container. .grid { display: grid; width: 800px; height: 500px; grid-gap: 10px; grid-template-columns: 200px 200px 200px; grid-template-rows: 150px 150px; } https://codepen.io/rachelandrew/pen/RMMqLd Let’s look at aligning tracks first.

I have a grid container which contains some fixed size tracks. The total amount of space needed to layout those tracks is less than the width and height of the container.

This means we have some free space we can play with. By default the tracks are aligned to the start dimension in both rows and columsn.

Slide 63

Slide 63

https://codepen.io/rachelandrew/pen/RMMqLd start start So this is the start - in English anyway

Slide 64

Slide 64

align-content and justify-content Aligning tracks What should I do with free space in the Grid Container? The content properties deal with free space, what do we want to do with that leftover space.

Slide 65

Slide 65

❖ align-content 
 align tracks in the Block Dimension

❖ j ustify-content 
 align tracks in the Inline Dimension Align content works in th eblock dimension and justify content the inline dimension.

Slide 66

Slide 66

https://codepen.io/rachelandrew/pen/RMMqLd justify-content: end 
 Inline axis So, if I want all my tracks to move to the end of the grid in the inline direction - along the rows.

I use justify-content: end.

Justifying to the end line of the grid. What this means is that the free space is now placed before our tracks.

Slide 67

Slide 67

align-content: center 
 Block axis I want them in the centre, in the block dimension.

Align-content centre. Our free space is placed above and below our tracks.

What we are doing here is distributing space, we decide where we want our tracks and therefore what happens with the space leftover. SO just like flexbox.

Slide 68

Slide 68

Keyword values ❖ space-between ❖ space-around ❖ space-evenly .grid { display: grid; width: 800px; height: 500px; grid-gap: 10px; grid-template-columns: 200px 200px 200px; grid-template-rows: 150px 150px; justify-content: space-between; align-content: space-around; } We can use the keywords, space-between, space-around or space-evenly.

Slide 69

Slide 69

justify-content: space-between 
 Inline axis align-content: space-around 
 Block axis If you have used flexbox you have probably used the values space-around and space-between. You can use this with grid tracks too.

Align-Content space-between, justify-content space-around.

Our free space is divided up and placed between, or on either side of the items. Note that this will make the gaps bigger, and any item crossing the gaps will get bigger.

Slide 70

Slide 70

https://codepen.io/rachelandrew/pen/QmmzYx As you can see here, we have a large item spanning over two columns and two rows.

Slide 71

Slide 71

https://codepen.io/rachelandrew/pen/QmmzYx justify-content: space-between 
 Inline axis align-content: space-around 
 Block axis With space-around in the block dimension and space between inline that block gets a lot bigger as it absorbs the larger track space.

But that is justify and align content. Only useful if you have additional space in your grid after placing tracks.

Works pretty much like flexbox justify-content.

And this all, as you might have guessed works exactly the same way if we use a different writing mode. Start in the inline direction is always where a sentence starts. Start in the Block dimension will go down the blocks of the page.

Slide 72

Slide 72

https://codepen.io/rachelandrew/pen/wmmNaj justify-content: end 
 Inline axis align-content: center 
 Block axis Like this.

Slide 73

Slide 73

Writing Modes Once again the grid works the same way whichever way up it is. .grid { display: grid; inline-size: 800px; block-size: 500px; grid-gap: 10px; grid-template-columns: 200px 200px 200px; grid-template-rows: 150px 150px; justify-content: end; align-content: center; writing-mode: vertical-lr; } https://codepen.io/rachelandrew/pen/wmmNaj And in the code you can see the use of block-size instead of height and inline-size instead of width

These are new logical properties which I really do not have time to explain now, however this week I published an article on Smashing which explains them in great detail.

Slide 74

Slide 74

https://www.smashingmagazine.com/2018/03/understanding-logical-properties-values/ You can find that here.

Slide 75

Slide 75

align-items and justify-items Aligning items Setting the align-self and justify-self values of individual Grid Items. We then have the items that are placed onto our grid.

Slide 76

Slide 76

❖ align-items / align-self 
 set alignment of items in the Block Dimension

❖ j ustify-items / justify-self 
 set alignment of items in the Inline Dimension

Slide 77

Slide 77

https://codepen.io/rachelandrew/pen/dmmQVg stretch stretch start start The default for align-items and justify items is stretch, unless the content has an intrinsic aspect ratio - for example an image. In which case it will be start.

This means that generally content will stretch over the area - for example a div with a background colour, will cover the entire area, but we don’t stretch images out of shape. You can of course change this and that is what our alignment properties are for.

Slide 78

Slide 78

https://codepen.io/rachelandrew/pen/dmmQVg justify-items: end 
 Inline axis

Slide 79

Slide 79

https://codepen.io/rachelandrew/pen/dmmQVg align-items: start 
 Block axis

Slide 80

Slide 80

https://codepen.io/rachelandrew/pen/dmmQVg If we use the Firefox Grid Inspector you can see that the areas are still the same, it’s just the alignment of items inside them we have changed.

Slide 81

Slide 81

align-self and justify-self Target individual items to set alignment. .grid { display: grid; width: 800px; height: 500px; grid-gap: 10px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr; align-items: start; justify-items: end; } .grid img { align-self: stretch; justify-self: stretch; } What align items and justify items is doing is setting the Align and justify self properties on individual items.

So if we did want that image to stretch rather than align to start, we could make it so and leave the other items alone.

Slide 82

Slide 82

https://codepen.io/rachelandrew/pen/dmmQVg Like this.

So … you have all this new ability with sizing, and all these new alignment features, all tied together with he fact that Grid layout properly respects writing modes which you can use to set languages intros writing modes, but also for creative purposes. and I hope that you understand the grid a little more. But, I wanted to finish with the third thing I am saying a lot this year.

Slide 83

Slide 83

Please stop asking me this question. “Where is my magic Grid Polyfill?” When I demo all of this stuff, typically someone will ask something which is essentially - can I have a magical polyfill which will fix grid in older browsers.

The answer is no. No you can’t. Here is why.

Slide 84

Slide 84

https://caniuse.com/#feat=css-grid

We have grid support in all of these browsers now, but what caniuse is pretty bad at showing is the unupgradables - the people stuck on old browsers because their device doesn’t support an upgrade.

Other than people in companies who refuse to upgrade from an old version of IE, increasingly those browsers are mobile browsers, in non-western countries, running on slower, older hardware. On expensive data plans.

Slide 85

Slide 85

To polyfill grid is to force expensive JavaScript onto the slowest browsers and devices. Why would you force a bunch of JavaScript onto those devices?

The things grid is doing perform incredibly well.

What does not perform well is JavaScript attempting to do what grid is doing. This isn’t an anti-JavaScript thing, it’s just a fact.

Slide 86

Slide 86

New CSS can help you create better experiences

in browsers that don’t support new CSS. By being amazingly lightweight in terms of required CSS, in addition to not requiring wrapper elements around each row, grid can enable you to make a better experience for people who don’t even support grid.

Slide 87

Slide 87

A 12 column layout This is all you need. No framework required. .grid { display: grid; grid-template-columns: repeat(12, 1fr); grid-auto-rows: 100px; grid-gap: 20px; } .four-cols { grid-column: auto / span 4; } .three-cols { grid-column: auto / span 3; } .six-cols { grid-column: auto / span 6; } The grid layout that allows a 12 column, flexible layout with all boxes in a row as tall as each other is four lines of code, plus a line of code for each unique positioned item. You can afford for those few lines of code to be downloaded by a browser that won’t parse them due to not supporting grid.

Slide 88

Slide 88

New CSS knows about old CSS And we don’t need to leave older browsers with no layout you can create fallbacks just using CSS for those older browsers.

Because new CSS knows about old CSS.

This lets you build a simpler, yet still usable layout for your old browsers, and your non-supporting browsers.

Slide 89

Slide 89

❖ Media Queries : 
 tailor your design according to features of the device

❖ Feature Queries : 
 tailor your design to the support in the browser Just as you build a layout tailored to small screen devices by using media queries, you can build a layout tailored to your non-grid supporting browsers using Feature Queries.

It’s the same thing. We’re providing good experiences to users no matter whether they are accessing content on a low-powered phone, an iPhone 10, a small laptop, or a top of the line Mac or Windows machine.

See these things as the same, what features does this device have, what features doe this browser have?

Slide 90

Slide 90

https://codepen.io/rachelandrew/pen/aqbdOy

By considering what happens if our user has almost nothing, we structure our content well. If that content then just loads in block layout, one thing after another. That will actually be pretty good for most small screen devices anyway, certainly better than a horrible janky experience of trying to create something else using JavaScript.

Slide 91

Slide 91

Adding a vertical centre line either side of the text Using generated content to add a border. header h1 { text-align: center; display: grid; grid-template-columns: 1fr auto 1fr; grid-gap: 20px; } header h1:before, header h1:after { content: ""; align-self: center; border-top: 1px solid rgba(37,46,63,.5); } https://codepen.io/rachelandrew/pen/aqbdOy

Perhaps that small device does have CSS Grid, I’m going to add a little header detail with one of my favourite tricks.

Slide 92

Slide 92

https://codepen.io/rachelandrew/pen/aqbdOy

So this looks nice in a grid supporting browser.

Slide 93

Slide 93

Feature Queries Test for a CSS feature, and apply the CSS if it exists in that browser. header h1 { text-align: center; display: grid; grid-template-columns: 1fr auto 1fr; grid-gap: 20px; } @supports (display: grid) { header h1:before, header h1:after { content: ""; align-self: center; border-top: 1px solid rgba(37,46,63,.5); } } https://codepen.io/rachelandrew/pen/aqbdOy

I’ve not had an issue with the generated content appearing in a non-grid supporting browser, as we’re using a border top on some content that has no width, it’s the fr units that cause it to stretch in the inline direction once we are in a grid layout. However, if you were adding something that would display - for example using generated content to insert an icon, or an emoji or something, you could wrap the generated content bit in a feature query.

So I’m checking with the browser if it supports the display property with a value of grid. That way we only generate the borders if we have grid layout to position them.

We don’t need to worry about browsers that don’t support grid reading the grid CSS, they just ignore it. You could wrap the whole lot in a feature query if you wanted - but there is no need to.

Slide 94

Slide 94

https://codepen.io/rachelandrew/pen/aqbdOy No Grid Grid So we have mobile with no grid, mobile with grid

And this image here

Slide 95

Slide 95

Creating circles from squares Use border-radius Don’t forget that old CSS still exists! header img { border-radius: 50%; margin: 0 auto 2em auto; } https://codepen.io/rachelandrew/pen/aqbdOy Nothing fancy, it’s a square image I turned into a circle using border-radius, that’s really well supported/

Slide 96

Slide 96

CSS Shapes Floating the image and curving the text round once the screen is wide enough to do so. header img { border-radius: 50%; margin: 0 auto 2em auto; } @media (min-width: 30em) { header img { float: left;

shape-outside: margin-box;

margin: 0 20px 0 0; 

} } https://codepen.io/rachelandrew/pen/aqbdOy As we get a bit wider, I’d like to do something neat with it. I’ll float it left and cause the text to curve round it by using shape-outside margin-box.

Slide 97

Slide 97

https://codepen.io/rachelandrew/pen/aqbdOy Like this. And it doesn’t matter about browsers that don’t support CSS Shapes because they just ignore it, and

Slide 98

Slide 98

https://codepen.io/rachelandrew/pen/aqbdOy because it is applied to a float, we get squared off text rather than the curved text.

THis is Firefox, who currently don’t support shapes, but will do later this year as I understand it. So once that feature ships in Firefox, those users will get the nice curve.

Slide 99

Slide 99

https://codepen.io/rachelandrew/pen/aqbdOy We start to get wider.

I then have this section, which is a chunky block of text.

which I’d like to break into two columns. As the co-editor of the multiple column layout spec I have to put a little bit of multi col somewhere, and the nice thing with multicol is it’s really well supported.

Slide 100

Slide 100

Multi-column layout Well supported, responsive by default.

section { column-width: 15em; } https://codepen.io/rachelandrew/pen/aqbdOy Let’s do column-width 15em, so we’ll only get two columns when the available space is wide enough to support them.

The problem with multicol is if someone is on a very short screen, a phone in landscape mode perhaps they might end up scrolling up and down to read. So let’s use a vertical media query checking for height.

Slide 101

Slide 101

Vertical Media Queries Do we have enough height to show the columns without vertical scrolling? @media (min-height: 500px) { section { column-width: 15em; } } https://codepen.io/rachelandrew/pen/aqbdOy Then we only get the columns if we have enough height. These vertical media queries can be really useful, we tend to always think about screen width - sometimes height is the important metric.

Slide 102

Slide 102

https://codepen.io/rachelandrew/pen/aqbdOy We get this, the columns only kick in once there is enough room for 2 15 em columns so we don’t need a width media query, and the height media query stops them showing on short screens. [click]

To finish off my article component I want to do something with the cards at the bottom of the layout now we have some room for them to display more than 1 in a row.

and finally I want to arrange those boxes into a grid, which lines up with my columns and where I can cause the cards which have an image to span two rows of the grid.

Slide 103

Slide 103

Creating columns of cards Matching the minimum grid width, and the gap to the multi- column width and column-gap. .resources { max-width: 60em; } .resources { margin: 1em auto; padding: 0; list-style: none; display: grid; grid-template-columns:
repeat(auto-fill, minmax(15em,1fr)); grid-gap: 1em;

} .resources li.image { grid-row: auto / span 2; } https://codepen.io/rachelandrew/pen/aqbdOy I’m setting resources to max-width 60 em and then using the grid auto-fill functionality to fill that container with columns which are a minimum of 15em. This means we only get more than one column over 15em, enough room for 2 15em columns plus the gutter we get two, and we max out with three.

If we have two columns they line up with the multicol element due to grid-gap being 1em which is the default column gap for multicol.

Slide 104

Slide 104

https://codepen.io/rachelandrew/pen/aqbdOy Of course this will only work for people with grid. So we need to make a decision about non-grid browsers. You could of course leave it alone. Or we can choose some other method. Let’s try display inline-block.

Slide 105

Slide 105

Using in-line: block as a fallback We only need to over-ride the width and margin in a Feature Query. @media (min-width: 40em) { .resources li { display: inline-block; width: 47%; margin: 0 1% 1em 1%; vertical-align: top; }

} @supports (display: grid) { .resources li { width: auto; margin: 0; } } https://codepen.io/rachelandrew/pen/aqbdOy

Slide 106

Slide 106

https://codepen.io/rachelandrew/pen/aqbdOy And we get this,

Using inline -block means that our cards still run left to right. An alternative if it is ok for the cards to display down the columns rather than along the rows would be to use multicol here just like we do in the first section.

Slide 107

Slide 107

Using multi-column layout as a fallback We don’t need to override the column-* properties. They are ignored once we are in grid layout. @media (min-width: 40em) { .resources { column-width: 15em; } .resources li { break-inside: avoid; }
} Here is a multi example

Slide 108

Slide 108

So this is another option.

The reason I’m showing this today though isn’t so much to show you how to do fallbacks with grid layout, though there are a few tips in there you might find handy. It’s because I need you to realise how little you need do achieve a good experience for all your users.

As you develop your site, think of this stuff component by component. It’s a lot easier than worrying about the whole site or application at once.

Slide 109

Slide 109

We can achieve a lot with a little CSS. The key thing is that to create a component that works in all these cases, from small to large screens from browsers without grid, to those without shapes to those with everything needs trivial amounts of code. Without needing to ask those on the most limited devices to download JavaScript that also causes a janky experience.

Slide 110

Slide 110

Before worrying if a technique performs well, ask yourself if you need it at all. In the drive to try and make new techniques look the same in old browsers we can start to do things that cause a suboptimal experience for the very users we claim to be trying to help by addin gthe polyfill.

Slide 111

Slide 111

Reframe the browser support conversation. Reframe the discussions you have around browser and device support with your clients or colleagues. It should never be “how do we make this look the same in all browsers” but “how do we give a good experience in all browsers”.

Don’t worry about making their experience the same.

Make their experience good.

Slide 112

Slide 112

We have the tools to provide great experiences for everyone. We are in a better position now to provide great experiences to everyone than we ever have been. Don’t let lack of support hold you back from realising amazing designs or great experiences for the people who have support for this stuff, but likewise don’t let all the shiny mean you forget about those who don’t yet have it.

It’s become a bit of a trite thing to say for conference stages that the web is for everyone, but I truly believe that. I’m not here to build shiny toys for rich people, and even with the way in which this medium has been used for some not great things of late, I still believe in the power of the web to change lives, allow content to be accessed and ideas shared.

Slide 113

Slide 113

https://noti.st/rachelandrew/pweu9Z Thank you! @rachelandrew https://rachelandrew.co.uk