Designing with CSS Grid Layout Copyright © 2017 SitePoint Pty. Cover Design: Natalia Balska Notice of Rights All rights reserved. No part of this book may be reproduced, stored in a retrieval system or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews. Notice of Liability The author and publisher have made every effort to ensure the accuracy of the information herein.
However, the information contained in this book is sold without warranty, either express or implied. Neither the authors and SitePoint Pty., nor its dealers or distributors will be held liable for any damages to be caused either directly or indirectly by the instructions contained in this book, or by the software or hardware products described herein. Trademark Notice Rather than indicating every occurrence of a trademarked name as such, this book uses the names only in an editorial fashion and to the benefit of the trademark owner with no intention of infringement of the trademark. Published by SitePoint Pty.
48 Cambridge Street Collingwood VIC Australia 3066 Web: www.com Email: books@sitepoint.com About SitePoint SitePoint specializes in publishing fun, practical, and easy-to-understand content for web professionals. Visit http://www.com/ to access our blogs, books, newsletters, articles, and community forums. You’ll find a stack of information on JavaScript, PHP, design, and more. Preface Layout in CSS has always been a tricky task: hacking solutions using positioning, floats, and the one-dimensional flexbox has never been very satisfactory.
Fortunately, there is a new tool to add to our arsenal: CSS Grid Layout. It is an incredibly powerful layout system that allows us to design pages using a two-dimensional grid - offering the kind of fine-grained layout control that print designers take for granted! Grid Layout’s been in development for a while, but has recently been made a W3C candidate recommendation and has been added to most of the major browsers, so is ready for prime time. This short selection of tutorials, hand-picked from SitePoint’s HTML & CSS channel, will get you up and running with Grid Layout and using it in your own sites in no time. Conventions Used You’ll notice that we’ve used certain layout styles throughout this book to signify different types of information.
Look out for the following items. Code Samples Code in this book is displayed using a fixed-width font, like so: <h1>A Perfect Summer's Day</h1> <p>It was a lovely day for a walk.</p> Tips, Notes, and Warnings Hey, You! Tips provide helpful little pointers. Ahem, Excuse Me. Notes are useful asides that are related—but not critical—to the topic at hand.
Think of them as extra tidbits of information. Make Sure You Always. pay attention to these important points. Watch Out! Warnings highlight any gotchas that are likely to trip you up along the way.
Chapter 1: An Introduction to the CSS Grid Layout Module by Ahmad Ajmi As web applications become more and more complex, we need a more natural way to do advanced layouts easily without hacky solutions that use floats and other less burdensome techniques. An exciting new solution for creating layouts comes with the CSS Grid Layout Module. In this introductory tutorial, I’ll introduce you to this relatively new CSS feature and I’ll show you using some examples how the CSS Grid Layout Module works. What is the CSS Grid Layout Module? The core idea behind the Grid Layout is to divide a web page into columns and rows, along with the ability to position and size the building block elements based on the rows and columns we have created in terms of size, position, and layer.
The grid also gives us a flexible way to change the position of elements with only CSS without any change to the HTML. This can be used with media queries to alter the layout at different breakpoints. A Grid Layout Example Let’s start with an example to see the power of Grid Layout, and then I’ll explain some new concepts in more detail. Imagine you want to create a Twitter app with four full height columns layout (Tweets, Replies, Search, and Messages), something abstracted and similar to the screenshot below.
Here is our HTML: <div class="app-layout"> <div class="tweets">Tweets</div> <div class="replies">Replies</div> <div class="search">Search</div> <div class="messages">Messages</div> </div> Then we will apply some CSS to the .app-layout container element: .app-layout { display: grid; /* 1 */ grid-template-columns: 1fr 1fr 1fr 1fr; /* 2 */ grid-template-rows: 100vh; /* 3 */ } } View a demo here Here is the explanation of what we’ve done in the previous CSS: 1. Set the display property to grid. Divide the container element into four columns, each column is 1fr (one fraction) of the free space within the grid container. Create one row and set the height to be 100vh (full viewport height).
As you can see, the Grid Layout Module adds a new value to the display property which is grid. The grid value is responsible for setting the .app- layout element to be a grid container, which also establishes a new grid formatting context for its contents. This property is required to start using Grid Layout. The grid-template-columns property specifies the width of each grid column within the Grid, and in our case it divides the .app-layout container to four columns; each one is 1fr (25%) of the available space.
The grid-template-rows specifies the height of each grid row, and in our example we only created one row at 100vh. A layout with two columns and two rows would look like this: And we would use the following CSS: .app-layout { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 50vh 50vh; } View a demo here We can also achieve the above example only on small screens by wrapping the code inside a media query. This opens up a great opportunity for us to customize the layout differently in different viewports. For example, we can create the previous layout only on viewports under 1024px as follows: @media screen and (max-width: 1024px) { .app-layout { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 50vh 50vh; } } View a demo here Grid Layout Module Concepts Now that you’ve seen a simple example, there are some new concepts that I’d like to cover to give you a better understanding of Grid Layout.
Although there are a lot of new concepts, I will only take a look at a few of them. Grid Item Grid items are the child elements of the grid container. In the above example, the .replies elements would qualify as grid items. Grid Lines A Grid Line is a line that exists on either side of a column or a row.
There are two sets of grid lines: One set defining columns (the vertical axis), and another set defining rows (the horizontal axis). From the above screenshot, which represents the first example, I’ve created four columns at 1fr each, which will give us five vertical lines. I also created one row, which gives us two horizontal lines. Let’s see how we can position a grid item inside the grid container.
Position Items by Using a Line Number You can refer to an exact line number in a grid by using the properties gridcolumn-start and gridcolumn-end. We then give these properties the start and end line numbers. Looking at the previous example, this is how the browser positions the elements by default for us: .tweets { gridcolumn-start: 1; gridcolumn-end: 2; gridrow: 1; } .replies { gridcolumn-start: 2; gridcolumn-end: 3; gridrow: 1; } .search { gridcolumn-start: 3; gridcolumn-end: 4; gridrow: 1; } .messages { gridcolumn-start: 4; gridcolumn-end: 5; gridrow: 1; } Looking at the code for the .tweet column, this is what each of the three lines in the CSS does: 1. Position the child element starting from the first vertical line on the left.
End the element’s position at the second vertical line. Position the element inside the whole row. You can change this by changing the order of elements with different positions, so the order of the elements will be:. And we can do it as follows: .tweets { gridcolumn-start: 4; gridcolumn-end: 5; gridrow: 1; } .replies { gridcolumn-start: 2; gridcolumn-end: 3; gridrow: 1; } .search { gridcolumn-start: 1; gridcolumn-end: 2; gridrow: 1; } .messages { gridcolumn-start: 3; gridcolumn-end: 4; gridrow: 1; } We can also use the gridcolumn shorthand property to set the start and end lines in one line: .tweets { grid-column: 4 / 5; grid-row: 1; } .replies { grid-column: 2 / 3; grid-row: 1; } .search { grid-column: 1 / 2; grid-row: 1; } .messages { grid-column: 3 / 4; grid-row: 1; } View a demo here This has changed the layout structure with only CSS while the markup is still as it was without any changes.
This is a huge advantage of using the Grid Layout Module. We can rearrange the layout of elements independent of their source order, so we can achieve any desired layout for different screen sizes and orientations. Position Items by Using Named Areas A grid area is the logical space used to lay out one or more grid items. We can name a grid area explicitly using the grid-template-areas property, then we can place a grid item into a specific area using the gridarea property.
To make this concept more clear, let’s redo the four-column example with the search column placed first: .app-layout { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 100vh; grid-template-areas: "search replies messages tweets"; } In the last line, we divide the grid container into four named grid areas, each name for a column. The next step is to position each grid item into a named area: .search { gridarea: search; } .replies { gridarea: replies; } .messages { gridarea: messages; } .tweets { gridarea: tweets; } View a demo here Slack Example What about using the Grid Layout Module to implement a more complex example, for example, creating the building blocks of the Slack layout. Since we are talking about layouts, we will abstract and simplify the Slack design to the building blocks represented in the grid. Something like this: From this layout we will create three vertical columns, and three horizontal rows, and we can visualize it using the grid lines as follows: Here is the HTML: <div class="app-layout"> <div class="teams">Teams</div> <div class="channels">Channels</div> <div class="header">Header</div> <div class="messages"> <ul class="message-list"> <li></li> <li></li> </ul> </div> <div class="input"> <input type="text" placeholder="CSS Grid Layout Module"> </div> </div> And the CSS: .app-layout { display: grid; height: 100vh; grid-template-columns: 100px 250px 1fr; grid-template-rows: auto 1fr auto; } Here I’m using the grid-template-columns property to create three columns at 100px, 250px, and the third column takes up the remaining available space.
The last line creates three rows: The first and third rows with auto height while the middle row takes up the remaining available space. The remainder of the CSS looks like this: .teams { grid-column: 1; grid-row: 1 / 4; } .channels { grid-column: 2; grid-row: 1 / 4; } .header { grid-column: 3; grid-row: 1; } .messages { grid-column: 3; grid-row: 2; } .input { grid-column: 3; grid-row: 3; } View a demo here We can also create the slack layout using named areas, which you can see in this demo. Grid Layout Module vs Flexbox Since many of you have started using Flexbox, you might wonder: When would it be appropriate to use Flexbox and when would it be more appropriate to use Grid Layout? I found a good explanation from Tab Atkins: Flexbox is appropriate for many layouts, and a lot of “page component” elements, as most of them are fundamentally linear. Grid is appropriate for overall page layout, and for complicated page components which aren’t linear in their design.