Home Web Development Mastering CSS Grid

Mastering CSS Grid

By Pascal Thormeier
books-svg-icon Book
eBook $29.99 $20.98
Print $36.99
Subscription $15.99 $10 p/m for three months
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
eBook $29.99 $20.98
Print $36.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Chapter 1: Understanding the Basic Rules and Structures for CSS Grid
About this book
CSS Grid has revolutionized web design by filling a long-existing gap in creating real, dynamic grids on the web. This book will help you grasp these CSS Grid concepts in a step-by-step way, empowering you with the knowledge and skills needed to design beautiful and responsive grid-based layouts for your web projects. This book provides a comprehensive coverage of CSS Grid by taking you through both fundamental and advanced concepts with practical exercises. You'll learn how to create responsive layouts and discover best practices for incorporating grids into any design. As you advance, you'll explore the dynamic interplay between CSS Grid and flexbox, culminating in the development of a usable responsive web project as a reference for further improvement. You'll also see how frameworks utilize CSS Grid to construct reusable components and learn to rebuild and polyfill CSS Grid for browsers that don't fully support it yet. The concluding chapters include a quick reference and cheat sheet, making this book an indispensable resource for frontend developers of all skill levels. By the end of this book, you'll have thoroughly explored all aspects of CSS Grid and gained expert-level proficiency, enabling you to craft beautiful and functional layouts for web projects of any size.
Publication date:
June 2023
Publisher
Packt
Pages
330
ISBN
9781804614846

 

Understanding the Basic Rules and Structures for CSS Grid

Welcome to the first chapter of this book titled Mastering CSS Grid. As the title suggests, this book helps us to become pros at this layout technique and learn about all its specialties and details. Throughout the book, we’ll work on various tasks using grid layouts in an overarching project called Awesome Analytics.

In the first chapter of this book, we will start introducing you to CSS Grid. We must first establish its basic CSS rules to understand how the grid model works. To do that, we’ll look at how grids are structured and how we can visually represent them. We’ll learn about the CSS rules used to create grid layouts, how to combine them to achieve different arrangements, and how to use shortcut rules to shorten our code.

A look at how the development tools of Google Chrome and other Chromium-based browsers visualize grids will help us understand how we can debug and understand existing grids. This chapter will not work with our overarching project just yet—we’ll first cover some theory.

So, in this chapter, we will cover the following topics:

  • Understanding the basic rules related to CSS Grid
  • Using grid templates
  • Grid flow
  • Understanding special grid-related units, keywords, and functions
  • Using shortcuts
 

Technical requirements

For this chapter, we’ll need roughly the same things as for most chapters, as follows:

  • A modern browser that supports CSS Grid and offers grid debugging and a grid toolset
  • An integrated development environment (IDE) or text editor, such as WebStorm, VS Code, or Vim, with HTML and CSS syntax highlighting
  • Internet access is an advantage but not necessary

We can find several of the code examples on GitHub in this repository: https://github.com/PacktPublishing/Mastering-CSS-Grid/tree/main/chapter1.

All screenshots and examples have been made with a Chromium-based browser.

 

Understanding the basic rules related to CSS Grid

First, we need to know what grids are and what their purpose is. In short, grids aim to arrange items in a consistent manner. Grids provide clarity about content structure and sizing and allow us to steer where things are placed. Grids provide structure.

To achieve this understanding, we first have a look at some standard grid terminology, before creating our first CSS grid.

Defining grid terminology

We first need to establish some words we’ll use throughout the book. The following diagram will explain to us the most important terms:

Figure 1.1 – A grid and all its terms

Figure 1.1 – A grid and all its terms

We see many different elements here, as follows:

  • The grid is the whole structure. It consists of all arranged elements, the layout, and its attributes.
  • A grid is made up of grid cells. These grid cells can have different sizes, depending on the row and column definitions we give the grid. A grid cell doesn’t necessarily have content.
  • A grid has several grid lines. These are the lines that separate grid cells and make up the structure of the grid. They can be horizontal or vertical. In the diagram, three grid lines are marked: the two surrounding Column 1 and a single line between Row 1 and Row 2.
  • These grid lines can become gaps. Gaps are also sometimes called gutters. Gaps are used to separate grid tracks and allow us to add white space between elements. Gaps between rows don’t have to be the same size as gaps between columns.
  • Between two adjacent parallel grid lines, we see rows and columns of grid cells, also known as grid tracks or simply tracks. Two such tracks are marked in blue in the diagram: Row 5 and Column 1.
  • When we place content within a grid, we speak of them as grid items. Grid items can be images, div tags, text nodes, or any other HTML element we want to place and arrange. A grid item can be seen in Row 1, Column 4 in the diagram.
  • When we want to name specific groups of one or more cells, we speak of a grid area. Those grid areas are delimited by four grid lines and are, therefore, rectangles.

With these terms, we now have a common language to use when we talk about grids. We’ll use these terms throughout the book when defining grids.

Creating our first grid

In many ways, CSS Grid behaves like Flexbox. It needs a grid container and elements to align. In most cases, such as general page layouts or when working with teaser elements to link to additional content, we use <div> elements. Teaser elements can be built with <article> elements, too. We don’t have to, though! When working with semantic HTML, we might as well use the elements that fit best: <main>, <aside>, <header>, <footer>, <nav>, and more.

To start, let’s consider the following HTML structure. It resembles a standard Document Object Model (DOM) that we would use to structure any website and features most of the elements we would typically use when we develop a page’s layout:

<div class="container">  <header><!-- Header with a logo, navigation, etc. -->
    </header>
  <aside><!—Partially related things like social buttons --
   ></aside>
  <main><!-- Main content, headings, teasers, etc. -->
    </main>
  <footer><!-- Footer with contact, FAQ, etc. --></footer>
</div>

We see four elements that we want to align in a grid, as follows:

  • A header that might contain a logo or navigation
  • An element that will contain content not directly related to the main page content
  • An element for the actual content
  • A footer that displays things such as contact details, information about the company, a link to the FAQ, and similar additional controls

For ease of illustration, we will apply the following CSS upfront (the code has nothing to do with CSS Grid just yet and only serves illustration purposes):

/* 01_page_layout.html,  Micro-resetting */body { padding: 0; margin: 0; }
* { box-sizing: border-box; font-size: 25px; }
/* Making things visible on the page */
.container {
  border: 2px solid #555;
  padding: 8px;
  min-height: 100vh;
}
header {
  border: 2px solid #dd0808; /* Dark red */
  background-color: #ff6666; /* Light red */
}
aside {
  border: 2px solid #0ba7c6; /* Dark cyan */
  background-color: #74ddf2; /* Light cyan */
}
main {
  border: 2px solid #6f09e5; /* Dark purple */
  background-color: #b880f7; /* Light purple */
}
footer {
  border: 2px solid #c4be0d; /* Dark yellow */
  background-color: #f7f380; /* Light yellow */
}

This CSS code will color our containers and ensure we can track which element goes where. When loaded up in a browser, this results in four colored stripes along the screen. That’s what we expected. After all, our DOM does not have any content.

Things get interesting, though, when we add the following CSS code:

.container {  display: grid; /* Marks this class as a grid container */
}

When reloading, we see that CSS Grid has evenly distributed the four containers vertically. Since the outer <div> element has a fixed height, CSS will calculate the height of every element and rescale it to fit. Since we have not yet defined anything other than This is a grid, each element takes up the same amount of space:

Figure 1.2 – Our HTML is styled and displayed as a grid

Figure 1.2 – Our HTML is styled and displayed as a grid

CSS Grid has entirely taken over the placing and sizing of statically and relatively positioned elements within the grid. This, in turn, means that any other inline positioning method does not apply anymore. Any use of display: inline-block, display: table-cell, float, or vertical-align will have no effect. However, we can still use position: fixed, position: absolute, or position: sticky because the elements are not static anymore. Elements that have position: relative; attached to them can be moved around and are still affected by the grid.

There’s also the possibility to define an inline grid by using display: inline-grid;. The main difference is that the grid container behaves like an inline container instead of a block container. Therefore, we now know that display: grid defines a grid that behaves like a block element.

Let’s remove the colors briefly and see how the browser development tools indicate that we use a grid. Usually, Chrome shows grids with dashed lines. When we open the inspector and hover over the grid container in the Elements tab, we can see what we already knew from our color experiment. We can also click on the grid button that appears in the inspector to turn on grid debugging, which will show us the grid lines.

In the following screenshot, we can see the full grid representation in Chrome’s development tools:

Figure 1.3 – Chrome’s inspector showing us the different grid slots

Figure 1.3 – Chrome’s inspector showing us the different grid slots

Just as in the color experiment we did before, we see four grid rows, indicated by purple dashed lines. These lines also indicate the grid lines and would become larger once we introduce gaps. The blue areas we see are our grid cells. Currently, they don’t contain any grid items. The green border around the grid is our padding. It’s not related to the grid.

Arranging grid elements

So far, CSS Grid has taken care of arranging things for us—in our example, it automatically created four rows because there were four elements, spaced them evenly, and placed them in the same order as they appeared in the DOM.

However, often, we don’t want this, especially when wanting responsive layouts. For example, on a mobile, social media buttons might move to the bottom of the page and become sticky elements, whereas on a desktop they should stay in one place, such as the sidebar.

To be able to move elements, we first need to state the number of grid rows and grid columns explicitly. We achieve this by using the grid-template-rows and grid-template-columns rules, which go into the container element and will pre-create a grid structure for us. We specify the number of grid columns and rows by providing their size, separated by spaces. The size may vary from row to row and column to column.

The total number of grid cells may be larger than the total amount of elements we’d like to arrange. We can, for example, define a grid with three rows and three columns and only arrange five items within it—a case that’s common in galleries or news websites. The remaining grid cells remain empty.

For the time being, let’s work with 1fr. fr is a unit that has been introduced to CSS with CSS Grid and works exclusively with grids. 1fr essentially means: Take one unit of free space for this grid element. We will discuss the fr unit later in this chapter. So, if we used it for grid rows, this means taking one unit of free space for this grid row. The same applies to columns too.

Let’s change our example to a 2x3 grid of evenly spaced grid elements by applying the following CSS code to the container class:

.container {  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
}

As we can see, we used 1fr twice in grid-template-columns, resulting in two equally sized columns, and three times in grid-template-rows, resulting in three equally sized rows. When inspected, Chrome shows us that it has now created a grid structure, as indicated in the following screenshot:

Figure 1.4 – Chrome’s inspector showing us our 2x3 grid

Figure 1.4 – Chrome’s inspector showing us our 2x3 grid

CSS Grid assigns integers to all grid lines for us to use as coordinates. These integers increase from left to right and top to bottom, starting at 1. When we think of the grid as a coordinate system, its origin is in the top-left corner. This allows us to place grid items starting from the top left to the bottom right.

However, CSS Grid offers a second origin that lets us place items from the bottom-right to the top-left corner. It does so by also assigning negative integers to the same grid lines, starting at the bottom-right corner with -1.

Our grid so far would receive the numbers illustrated here:

Figure 1.5 – Grid line numbering

Figure 1.5 – Grid line numbering

Currently, all columns are the same size. If we want one column twice the size of the other, we increase the value of that column to 2fr. For example, if we wish to have a 1/4 sidebar and 3/4 main content slot, we adjust the grid-template-column rule to 1fr 3fr. Then, if wanted to have a 1/6 header, 1/6 footer, and the other 2/3 (4/6 in a six-column layout) for the main content, we would use the grid-template-rows: 1fr 4fr 1fr rule.

We see that the size of the grid rows and columns depends on the total number of free space units. If we think of a grid as 100% wide and 100% tall, we can calculate the size of each row and column as percentages. For example, in a layout with four columns of size 1fr, each column takes up 25% of the space.

In a two-column layout with sizes 1fr and 3fr, however, the total number of free space units is 4, resulting in 1fr being 25% wide and 3fr equaling 75% width. The total number of fr units determines the size of each fr unit.

Let’s adjust our example to this new layout:

.container {  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: 1fr 4fr 1fr;
}

This won’t affect the assigned numbers (they just stay the same), but we can see that this has the desired effect when inspecting, as illustrated in the following screenshot:

Figure 1.6 – Chrome’s inspector shows us our adjusted 2x3 grid

Figure 1.6 – Chrome’s inspector shows us our adjusted 2x3 grid

By re-applying the colors, we can now see the default arrangement for this grid. By default, CSS Grid fills grid elements from left to right, top to bottom. This grid resembles a painting by Piet Mondrian and is not exactly what we’d like:

Figure 1.7 – Our accidental neoplasticism painting, using CSS on HTML

Figure 1.7 – Our accidental neoplasticism painting, using CSS on HTML

But we still have not explicitly arranged the elements yet. For that, we use four different CSS rules: grid-column-start, grid-column-end, grid-row-start, and grid-row-end. We apply these to the elements we want to position—so, in our case, header (marked red), footer (marked yellow), aside (marked cyan), and main (marked purple).

By default, grid-row-start, grid-row-end, grid-column-start, and grid-column-end will have the auto value, meaning that CSS Grid will figure out the beginning row and column itself, again with the left-to-right, top-to-bottom method. Most of the time, this is enough. We can, however, define where to place any element explicitly.

Looking at the grid outline in Figure 1.6, we notice that the header and footer both have to span two columns. We achieve this with the span keyword for grid-column-end and grid-row-end. span tells the browser to enlarge the element until it encounters a grid cell with that name or for the amount specified. (But wait—grid cells can have names? Yes, they can. We’ll have a look at this a bit later in this chapter.)

So, grid-column-end: span 2; means enlarge the element to a width of two columns, and grid-column-end: span something; means enlarge the element to the gap named “something” (we will have a look at gap names later on too). If the element already starts at the second column, this will not do much. However, if it begins in the first column, it will fill two adjacent grid cells.

Let’s place the header and footer first since they work very similarly:

header {  grid-column-end: span 2; /* Make it reach to the end of
    the second column */
}
footer {
  grid-column-end: span 2; /* Make it reach to the end of
    the second column */
}

Let’s see if this does what we want. And indeed, it does. The default placing of the main and aside grid elements already makes them appear in the place we want them to. Since the header and the footer elements both take up two grid cells each, we’re left with two remaining grid cells for the main and aside elements.

These grid cells are occupied by the aside and main elements in the order of appearance in the HTML code:

Figure 1.8 – The header, sidebar, content, and footer elements arranged

Figure 1.8 – The header, sidebar, content, and footer elements arranged

Adding some breathing room (or gaps)

Right now, all the elements are aligned snuggly. However, we don’t always want this. Especially for elements arranged in a grid in the page content, we might wish to have some space in between. There are two approaches to this. Either we can use paddings and margins to try to get the spacing right or we can use CSS Grid’s column-gap and row-gap rules.

Usually, when working with paddings and margins as grid gutters, there is a risk of inconsistencies because we need to specify values for each grid element individually. Furthermore, we might want to use paddings and margins for other purposes, such as adding more margin to text or giving images a border effect. To mitigate these risks, CSS Grid offers two rules regarding gaps between elements: column-gap and row-gap.

These two rules are defined on the container level and govern the space between all rows and all columns. We can use any unit we’d like—so, px, rem, em, or even %. If the latter, the browser does the percentage calculation on the container’s size. So, if our container is 100px high and we define a 5% row gap, we have a 5px gap between every row.

However, if we do not define the height or width of the container, its size would be determined by its content and the gaps. So, for example, if the gaps are 5% of the container size, we have a circular dependency: the gap is 5% of the width and at the same time is contributing to the width.

The browser would first calculate the gap size by calculating 5% of the container’s size, assuming the gap has a current width of 0. It then sets the size of the gap, enlarging the container. The browser would then realize that the gap is now smaller than 5% of the size of the container, re-calculate the gap, and so on.

Mathematically speaking, this is the limit of a series. If you’re not familiar with calculus, you can skip the following part. We can define the total width of a container as the sum of the gap, g, and its element’s width, e. We can define the series and its limit as follows:

This limit might either converge to a single value or diverge off to infinity, if s is greater than or equal to 100%. Limits are hard to calculate, especially if they are of complex series. CSS Grid circumvents these calculations by simply downsizing the grid cell widths so that the total width doesn’t change. This effect is often undesired. Elements will overlap the container if no explicit size is given to it.

In summary, to avoid unexpected behavior in element sizing, it’s recommended to use non-relative units for gaps. With that knowledge, we can start practicing gaps.

Let’s add a 16px row gap and a 4px column gap to our modern art-like example and see how it behaves. We’ll apply the following code:

.container {  /* Grid definition */
  row-gap: 16px;
  column-gap: 4px;
}

And the result looks just like what we expected:

Figure 1.9 – Our grid now has spacing in it

Figure 1.9 – Our grid now has spacing in it

Notice that the inner padding of the grid container was already there. This is because row-gap and column-gap only affect the space between rows and columns, not around them.

We now know how to define basic grids. This allows us to define grids for most use cases already. However, these rules often need extra context by using explicit class names and perhaps even comments in the code. Otherwise, they’re hard to maintain, which might cause frustration and delay development. Let’s learn how we can be more explicit about the intent of our code.

 

Using grid templates

Working with larger grids can get confusing. For now, we used two rules on the container to define our grid size and then some seemingly arbitrary numbers to denote where an element should be placed in both rows and columns. For developers not familiar with the code, these seemingly arbitrary numbers and sizes could be hard to understand.

They would need to spend more time understanding the grid since it’s not very self-descriptive. However, CSS Grid offers us possibilities to be more explicit. We’ll now have a look at how to name rows, columns, and entire grid areas.

Naming grid rows and columns

To add more clarity to our grid definitions, CSS Grid allows us to name columns and rows.

When defining columns and rows with grid-template-columns and grid-template-rows, we can add names in between grid sizes with a syntax like this:

grid-template-columns: [sidebar-start] 1fr [sidebar-end content-start] 3fr [content-end];

Everything in square brackets is considered a name. We can also see that we’ve assigned two names to the middle grid line between the sidebar and the content, which we can separate by using spaces. Using explicit two names, such as sidebar-end and content-start, for the same grid line allows us to decouple the name from the structure: the sidebar doesn’t necessarily have to end where the content starts.

So, instead of using numbers when placing elements, we can use these names to explicitly state where an element’s placement starts and where it ends. If we wanted to align the header of our example with the new names, we would replace the numbers with the corresponding names, as shown here:

header {  grid-column-start: sidebar-start;
  grid-column-end: span content-end;
}

Unlike the case where we used numbers, we also added a grid-column-start rule to the code. Otherwise, CSS Grid wouldn’t know where the element starts (it defaults to auto) and would assume that it should only span a single column.

By naming rows and columns, we make our code more readable. In the template definition, we can see what the rows and columns are meant to contain. In addition, we now have more context on the grid items as well: the header, for example, spans from the start of the sidebar to the end of the content. Someone reading this code for the first time would understand its placement better, especially in a complex grid.

We can also define and use grid areas to place grid items. With grid areas, we have an almost visual representation of our grid within the code. The CSS rule we use to define grid areas is grid-template-areas.

This rule is sometimes accompanied by grid-template-rows and grid-template-columns to ensure we have size definitions for rows and columns, if necessary. This is especially necessary for fixed-size grid cells—for example, a 100px-wide sidebar or a 250px-high footer. If we work with fr only, using grid-template-rows and grid-template-columns isn’t obligatory.

We know, for example, the size of our grid columns: 1fr 3fr. And we also know the sizes of our rows: 1fr 4fr 1fr. If we wanted to give the grid areas names, we would probably use a system as illustrated in the next screenshot:

Figure 1.10 – Our grid with explicit names for every area

Figure 1.10 – Our grid with explicit names for every area

Using the six rows and four columns, we can also translate this to a system where we name each grid cell, as shown in the next screenshot:

Figure 1.11 – Our grid with explicit names for every cell

Figure 1.11 – Our grid with explicit names for every cell

Our grid sizes (1fr 3fr and 1fr 4fr 1fr) are represented by the number of grid cells we have for rows and columns. We can then, more or less, translate the system shown in the previous screenshot as CSS code:

.container { display: grid;
 grid-template-areas:
   "header header header header"
   "sidebar content content content"
   «sidebar content content content»
   «sidebar content content content»
   "sidebar content content content"
   "footer footer footer footer"
 ;
}

What CSS Grid will do now is automatically calculate the grid-template-rows and grid-template-columns rules. However, instead of having two columns and three rows of different sizes, CSS Grid will create four columns and six rows, each cell being the same size.

If we now want to place elements within the grid, we use the grid-area rule on our elements. So, to place the header, sidebar, content, and footer, we use the following code:

header {  grid-area: header;
}
aside {
  grid-area: sidebar;
}
main {
  grid-area: content;
}
footer {
  grid-area: footer;
}

This will take care of the entire grid-column-start, grid-column-end, grid-row-start, and grid-row-end configuration for us and places the elements correctly. We can see the new structure of the same-sized grid cells when inspecting and how the elements span them according to the template:

Figure 1.12 – How CSS Grid represents grid-area templates

Figure 1.12 – How CSS Grid represents grid-area templates

Usually, this is the most straightforward way to configure grids. It gives us a visual representation of our grid in the code and lets us assign elements to grid areas using a single CSS rule, making it very obvious where an element will go in the grid.

However, we can also combine it with grid-template-rows and grid-template-columns to give the areas specific sizes. If we, for example, wanted to make the sidebar 150px wide and the header and footer 200px tall, we would add the following definitions next to the grid-area definitions:

.container {  display: grid;
  grid-template-areas:
   "header header header header"
   "sidebar content content content"
   «sidebar content content content»
   «sidebar content content content»
   «sidebar content content content»
   «footer footer footer footer»
  ;
  grid-template-rows: 200px 1fr 1fr 1fr 1fr 200px;
  grid-template-columns: 150px 1fr 1fr 1fr;
}

This would result in a grid, as shown in the following screenshot:

Figure 1.13 – Our grid with explicitly sized rows and columns

Figure 1.13 – Our grid with explicitly sized rows and columns

When we use grid-template-area together with grid-template-rows and grid-template-columns, however, there is no need to define larger grid areas. We can thus simplify our grid-template-area definition, and therefore our grid, to the following:

.container {  display: grid;
  grid-template-areas:
   "header header"
   "sidebar content"
   "footer footer"
  ;
  grid-template-rows: 200px 1fr 200px;
  grid-template-columns: 150px 1fr;
}

And that works just as well:

Figure 1.14 – Our grid with explicitly sized rows and columns and a reduced number of rows

Figure 1.14 – Our grid with explicitly sized rows and columns and a reduced number of rows

Instead of six rows and four columns, we now only have three rows and two columns.

To summarize, grid areas allow us to specify our grid in a visual way without forgoing structural simplicity or flexibility.

 

Grid flow

So far, we’ve seen elements being placed by CSS Grid with the same rule: it starts from the top left and fills the grid with elements, row by row, to the bottom right. However, there’s a way that we can control how CSS Grid places new items within the grid, which is called grid-auto-flow.

The possible values for this function are set out here:

  • row (the default value): This fills elements row by row, from left to right. If an element does not have enough space to be placed in a row, it is moved to the next one.
  • column: Behaves the same as row, except for the direction—it will fill columns first, top to bottom, and move to the next column once the previous one is full.
  • dense: Tries to fill in any holes in the grid, no matter their placement. This is interesting if we have many different-sized elements that need no particular order, such as randomized mood images on restaurant websites.
  • row dense and column dense: These values are combinations of the previous three. They will first try to fill in rows and columns, respectively, and then fill any resulting holes. Since row is the default value, row dense is equivalent to just using dense.

Let’s inspect how the different values behave. For that, we’ll have a look at this code:

<style>  .container {
    display: grid;
    grid-template-columns: 100px 100px 100px 100px 100px;
    grid-template-rows: 100px 100px 100px 100px
      100px 100px;
  }
  .container > div {
    background-color: darkblue;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #ffffff;
    font-size: 24px;
    font-weight: bold;
  }
  .large {
    grid-column-end: span 2;
    grid-row-end: span 2;
  }
</style>
<div class="container">
  <div class="small">1</div>
  <div class="large">2</div>
  <div class="large">3</div>
  <div class="large">4</div>
  <div class="large">5</div>
  <div class="small">6</div>
  <div class="small">7</div>
  <div class="small">8</div>
  <div class="small">9</div>
  <div class="small">10</div>
  <div class="small">11</div>
  <div class="small">12</div>
  <div class="small">13</div>
</div>

This code will create a 5x6 grid with equally sized, quadratic cells. This contains thirteen squares, composed of nine small (1x1) and four large (2x2) squares. Because of the lack of space, we use an extra row for any spill-over grid cells we might have.

We told CSS Grid to first add a small square, then add four large ones, and then add the other eight small ones. We have not defined the grid-auto-flow property for now, so it defaults to row. Therefore, CSS Grid will start with the first row, add the small square, then two large ones, and then go to the second row, notice that there’s not enough space, move on to the third row, add two more large ones, and then fill the rest up with small ones. And indeed, it does:

Figure 1.15 – CSS Grid arranging squares by rows

Figure 1.15 – CSS Grid arranging squares by rows

There is a noticeable gap in the top left of the grid. Also, the extra row we’ve added has proven useful by housing the extra square.

We can expect roughly the same behavior if we swap the value of grid-auto-flow from rows to columns:

Figure 1.16 – CSS Grid arranging squares by columns

Figure 1.16 – CSS Grid arranging squares by columns

Now, we’ve ended up with three gaps. Since CSS Grid cannot fit the third large square, it moves to the second column and repeats the filling process.

Those gaps are annoying, though, aren’t they? With dense, we can tell CSS Grid to fill these gaps. The plain value of dense is only a short form of row dense, so we don’t need to differentiate those cases. However, it will produce a—well, dense layout:

Figure 1.17 – CSS Grid arranging squares in a dense grid by rows

Figure 1.17 – CSS Grid arranging squares in a dense grid by rows

A dense column layout, achieved by using column dense, works the same way:

Figure 1.18 – CSS Grid arranging squares in a dense grid by columns

Figure 1.18 – CSS Grid arranging squares in a dense grid by columns

The layout is similar: some parts are rotated and mirrored, and the rest is filled up, column by column. Thinking about it, we can get pretty artsy with grids. Maybe there’s some pixel art made with CSS Grid out there—who knows?

Grid flow gives us even more control over how a grid behaves, should we not know its content in advance. Think of user-generated content or randomly selected items. Grid flow fills any resulting gaps for us and guarantees a pretty grid.

 

Understanding special grid-related units, keywords, and functions

Let’s now look at the units and CSS functions that CSS Grid has introduced. Many of these are specifically for CSS Grid; however, some might be useful for Flexbox layouts and other use cases.

The fractional unit

The only actual unit that was introduced with CSS Grid is fr—this stands for fractional unit and denotes a fraction of the total space. Think of it like a cooking recipe—for example, two parts of oil mixed with three parts of flour. So, when we want to have a total mixture of 500 grams, we can divide it by five and multiply by the number of parts. So, with 500 grams, we have 200 grams of oil (two parts) and 300 grams of flour (three parts). Now, replace parts with fr, and you’ve understood how the unit works.

When defining grid templates, we can mix in other units, such as px or rem, to denote fixed-size grid cells. CSS Grid will then take the total width, deduct the fixed-size cells, and then calculate the parts again. Returning to the cooking example, say that our recipes tell us to mix two parts of oil with three parts of flour, bake, and then add 100 grams of rosemary as decoration.

If our finished product weighs 600 grams, and we need to calculate the amount of flour and oil, we first subtract the 100 grams of rosemary from the 600 grams and then calculate the weight of the parts again.

The main difference between percentages and fractional units is their basis of calculation. While percentages use the entire size of the grid to calculate their exact values, fr uses what is left over after all fixed-size elements are subtracted.

Sizing keywords and functions

Not only can we use units when defining grid column and row sizes, but we can also give them a general behavior. For that, CSS Grid offers four different keywords and three functions we can use. Most of them are related to the content of the grid cell and will be calculated once the size of the content is known, allowing us to have different-sized grids for each content variant.

The four keywords are min-content, max-content, fit-content, and auto. We can use these keywords as values for grid-template-columns and grid-template-rows instead of using any value with a unit.

The three functions are min(), max(), and minmax(). We can also use these as a substitute for any value with a unit.

First, we can tell the cell to always fit its absolute possible minimum size with min-content. This can be useful if we have images and text aligned in a grid, and the image sizes should define the grid sizes. For the following screenshot, we used an image with a fixed width of 200x200 pixels.

The grid columns are defined as min-content 1fr 4fr. The min-content sizing keyword ensures that the grid cell’s width does not go below 200px, the smallest non-wrappable content:

Figure 1.19 – An image resizing a grid cell

Figure 1.19 – An image resizing a grid cell

As well as images, min-content also takes text into account. If the minimum width of a grid cell, for example, is determined by the longest word in that cell, that word’s pixel width will then be the minimum size. This can have funny effects when paired with word-break: break-all; as the minimum width is then calculated by the widest character:

Figure 1.20 – CSS Grid breaks the text—the widest character, “W”, defines the cell’s width

Figure 1.20 – CSS Grid breaks the text—the widest character, “W”, defines the cell’s width

The second keyword we can use is max-content, which will calculate the maximum possible content size and use this as the grid-cell sizing. So, instead of using the longest word, this will calculate the width of the entire sentence and use that. When paired with images, it will use the image’s max-width or max-height value, depending on if we’re sizing a row or column.

The third keyword is fit-content, a mixture of min-content and max-content. It will behave like the fr unit, but with a minimum value of min-content and a maximum value of max-content.

To illustrate, let’s think about a grid with four columns and a total of 200px width. Each column is evenly spaced with 1fr, except for the first column, which has a sizing of fit-content(50px). We now put an image of 80px width in that first column. Instead of resizing the image to 50px width, it will increase the size of the cell to 80px and reduce the size of all the others by 10px each.

To summarize, we would use the following CSS code:

.fit-content-grid {  display: grid;
  width: 200px;
  grid-template-columns: fit-content(50px) 1fr 1fr 1fr;
}

And we apply it to the following HTML structure:

<div class="fit-content-grid">  <img src="assets/80.png" alt="80x80">
  <div>A</div>
  <div>B</div>
  <div>C</div>
</div>

We can see how the image stays the same size in the following screenshot:

Figure 1.21 – A grid using fit-content to allow a cell to grow if the content does not fit

Figure 1.21 – A grid using fit-content to allow a cell to grow if the content does not fit

We can see that the entire width stays at 200px. The columns containing letters are significantly smaller than the one containing an image. The cell has expanded to fit the content.

However, if we removed the image—for example, with JavaScript—the cell size would go back to 50px. If we used max-content instead, it would result in a column width of 0px since there is no content.

The last keyword is auto. This also behaves a lot like the fr unit but with a little twist. It is interchangeable with 1fr if only 1fr is used. Consider the following grid declaration:

.grid {  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

This declaration behaves the same as the following one:

.grid {  display: grid;
  grid-template-columns: auto auto auto;
}

The following screenshot shows the equivalence:

Figure 1.22 – Two grids: one of them uses fr units, and the other uses the auto keyword

Figure 1.22 – Two grids: one of them uses fr units, and the other uses the auto keyword

Both grids are the same width and share the same number of columns. The top one uses fr units, and the bottom one uses the auto keyword. We can see that all columns are the same size.

However, when we mix the two, auto receives a different share of the available space than the columns using fr: instead of taking up a unit of space, the auto-sized cell will resize to fit its content and the fr cells will take up that remaining space. This behavior is equivalent to using a fixed unit value: fr will always divide the leftover space.

To illustrate this behavior, let’s consider the following declaration:

.grid {  display: grid;
  width: 500px;
  grid-template-columns: auto 1fr 3fr;
}

The size of the first column depends on its content. An image with a width of 120px means that the grid cell will be 120px wide. 1fr of space would therefore be 95px, a quarter of the remaining space. Likewise, if we use an image with a size of 40px, the first column will be 40px wide and 1fr of space would equal 115px, a quarter of the remaining 460px of the entire grid.

The same applies to text. When we consider the previous grid definition and apply it to the following HTML, CSS Grid will make the first column the largest and squeeze in the other two, which will only take up as much space as their content needs:

<div class="grid">  <div>
    Lorem ipsum dolor sit amet
    Lorem ipsum dolor sit amet
    Lorem ipsum dolor sit amet
  </div>
  <div>
    Short
  </div>
  <div>
    Text
  </div>
</div>

The result looks like this:

Figure 1.23 – Spacing with auto and the fr unit

Figure 1.23 – Spacing with auto and the fr unit

If we want to explicitly state a minimum and maximum size for our grid cells, we can use a function called minmax(). This function does precisely what one would think: it sets a minimum and a maximum for the size of a value. When paired with the fr unit, we can give cells relative sizes but keep them at a minimum and maximum size. Remember the example with word-break: break-all;?

The min-content keyword, in combination with word-break: break-all;, resized the column to the width of the largest character, which is undesirable. We can mitigate such issues by using minmax() and assigning it a minimum value, as shown here:

<style>.container {
   width: 500px;
   display: grid;
   grid-template-columns: minmax(50px, min-content) 1fr 3fr;
   gap: 25px;
}
div {
   word-break: break-all;
}
</style>
<div class="container">
  <div>
    Hello, World!
  </div>
  <div>
    Some other column
  </div>
  <div>
    Some other column
  </div>
</div>

From this code, the first column has a width of 50px, the defined minimum size:

Figure 1.24 – Spacing with minmax

Figure 1.24 – Spacing with minmax

However, if larger content is found within the cell, such as an image, it will be enlarged:

Figure 1.25 – Spacing with minmax and larger content in the first cell

Figure 1.25 – Spacing with minmax and larger content in the first cell

We can also use the min() and max() functions for grid sizing. min() takes the smaller of two values and is often used with a relative and an absolute value, while max() takes the larger of two values, respectively.

For example, a column with min(50vw, 200px) sizing would result in a width of 50% up to a screen size of 400px. From 401px onward, the column would stay at 200px since that would be smaller than 50% of 401px, behaving like a combination of max-width and width.

Likewise, a column with max(50vw, 200px) sizing would result in a 200px-wide column for all screen sizes smaller than 400px. It thus behaves like a combination of min-width and width.

Repetitive column and row definitions

Imagine a gallery of images: it should be 800px wide and 1600px tall. Each image should take up 100px by 100px, resulting in 8 columns and 16 rows, all equally sized. If we wrote out this grid definition, it would look like this:

.gallery-container {  width: 800px;
  height: 1600px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr
    1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

This grid definition has several issues. The first is its readability. The brain can only quickly count about four items at a glance—a concept known as subitizing—and so when more than four or five similar items occur at once in an unfamiliar pattern, the brain doesn’t immediately know the number of items and has to count manually.

The second problem is its maintainability. Code repetition is usually not good for maintainability since it forces us to change the same thing multiple times. For example, imagine that we now got the requirement to fix the image width to 100px but keep the container at 100vw.

To do that, we would adjust every row and column to be 100px instead of 1fr. The resulting code would be even less readable since each cell now takes five instead of three characters to define. The result would look roughly like this:

.gallery-container {  width: 100vw;
  display: grid;
  grid-template-columns: 100px 100px 100px 100px 100px
    100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px 100px 100px
    100px 100px 100px 100px 100px 100px 100px 100px 100px
      100px;
}

Grid definitions such as these do work—don’t get me wrong—but there’s a tool that allows us to define multiple columns and rows in a much cleaner way: the repeat() function. Instead of writing 100px 24 times, we would rewrite the code using repeat(number, size definition), as shown in the next code snippet:

.gallery-container {  width: 100vw;
  display: grid;
  grid-template-columns: repeat(8, 100px);
  grid-template-rows: repeat(16, 100px);
}

Essentially, the repeat() function replaces the use of multiple identical columns.

We can even mix it with other cell definitions. For example, a grid-column-template value of 100px repeat(10, 1fr) 100px would result in 10 equally sized columns, surrounded by 2 columns of 100px width each:

Figure 1.26 – The repeat() function mixed with other sizing definitions

Figure 1.26 – The repeat() function mixed with other sizing definitions

When we need to define large amounts of alternating sizes, such as 50px 100px 50px 100px 50px 100px, we can also use the repeat() function: repeat(3, 50px 100px). Any valid size definition works, except repeat() itself. Sadly, we cannot nest repeat() calls, so something such as repeat(3 100px repeat(3, 1fr) 100px) won’t work.

The repeat() function already seems very useful, but it gets much fancier with its two accompanying keywords, auto-fill and auto-fit. We use these instead of numbers to define how many grid cells we want. So, instead of repeat(3, 100px), we would write repeat(auto-fill, 100px) or repeat(auto-fit, 100px).

The auto-fill value will add as many grid cells as possible to a row or column. For example, if a container is 375px wide and we define the grid-template-columns rule as repeat(auto-fill, 100px), there will be three columns with a left-over value of 75px. The number of rows and columns is, therefore, dependent on the size of the container. The following code example illustrates this:

<style>  .container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
    gap: 5px;
    height: 50px;
    margin-bottom: 100px;
  }
  .small {
    width: 375px;
  }
  .large {
    width: 750px;
  }
  .container div {
    background-color: darkred;
    height: 20px;
  }
</style>
<p>Width: 375px;</p>
<div class="container small">
  <div></div>
  <!-- Repeat 10x -->
</div>
<p>Width: 750px;</p>
<div class="container large">
  <div></div>
  <!-- Repeat 10x -->
</div>

The result of the previous code would look like this:

Figure 1.27 – The repeat() function mixed with other sizing definitions and using auto-fill

Figure 1.27 – The repeat() function mixed with other sizing definitions and using auto-fill

On the other hand, we have auto-fit. This keyword tries to fill the entire grid width (when used for grid-template-columns) or height (when used for grid-template-rows). This value is generally practical when working with minmax() and fr as the size definitions, as we allow the grid cells to grow and shrink.

The repeat(auto-fit, minmax(100px, 1fr)),)) value, for example, will result in a minimum column width of 100px. If the container is smaller than the current amount of columns times 100px, it will remove one column, rearrange the layout, and fill the entire width again by enlarging the columns. These values already allow us to build very responsive grids that are useful for article listings or image galleries.

The following screenshot shows the difference in behavior:

Figure 1.28 – The repeat() function using auto-fit

Figure 1.28 – The repeat() function using auto-fit

We can see that the columns now fill the entire container, whereas they were the same size when using auto-fill, auto-fit adapts the width of all columns.

CSS Grid offers us many possibilities to define the sizes of grid rows and columns and even allows us to add responsiveness without the need for media queries. To summarize, CSS Grid offers us an extra unit to define relative sizes, keywords to react size grid cells according to their content, and functions to keep sizes in defined ranges and to simplify repetitive grid definitions, with even more keywords to steer the number of grid cells.

 

Using shortcuts

A complex grid definition can result in a lot of code. Luckily, we can shorten much of the code by using shortcuts and combined definitions. Let’s look at some now.

The grid attribute

The most general and, by far, the most powerful shortcut we can use is simply called grid. This attribute receives a ton of arguments and is a shortcut for these attributes:

  • grid-auto-flow
  • grid-auto-rows (we’ll cover this in-depth in a later chapter, so don’t worry too much about that now)
  • grid-auto-columns (we’ll also cover this in a later chapter)
  • grid-template-areas
  • grid-template-columns
  • grid-template-rows

Not necessarily in that order, though. The official formal type definition of this shortcut is as follows:

grid =  <'grid-template'>                                   |
  <'grid-template-rows'> / [ auto-flow && dense? ]
    <'grid-auto-columns'>?  |
  [ auto-flow && dense? ] <'grid-auto-rows'>? /
    <'grid-template-columns'>

This looks complicated and, given, a lot like TypeScript. It tells us that the grid attribute can either receive an entire grid template or separate definitions for grid rows or columns. Optionally, we may also specify the grid flow with a flag (either at the row or column definition) and add values for grid-auto-rows and grid-auto-columns. Grid rows and columns are separated by a forward slash.

The shortcut may receive one of the following three combinations:

  • A grid definition that we would usually use with grid-template-areas
  • grid-template-rows, the auto-flow keyword (optionally with dense), and grid-template-columns (equivalent to using grid-auto-flow: columns;)
  • The auto-flow keyword (optionally with dense), grid-template-rows, and grid-template-columns (equivalent to using grid-auto-flow: rows;)

Mind the position of the auto-flow keyword in the last two combinations. The keyword’s position determines how the grid flows.

To illustrate, let’s have a look at an example:

.grid {  display: grid;
  grid-auto-rows: 100px;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: row dense;
}

This grid has four columns, all equally sized, and uses automatically generated rows of 100px height. The grid-auto-flow property is set to dense to fill gaps and rows, so it fills rows first.

But we can rewrite this with the grid attribute to the following:

.grid {  display: grid;
  grid: auto-flow dense 100px / repeat(4, 1fr);
}

The rewritten code is noticeably shorter than the first. Less code means we don’t have to send as many bytes over the wire, making requests and rendering faster, and we can see what the grid looks like at a glance.

The shortcut syntax isn’t as self-explanatory as the expanded syntax, but it can save us valuable time once it’s in our muscle memory.

The grid-template attribute

If we want to use both grid-template-rows and grid-template-columns and combine these into a single attribute, we can use grid-template. This attribute allows us to specify each row and column and even grid-template-areas more compactly.

The most basic way to use grid-template is to specify the rows, add a forward slash, and then add the columns. For example, if we want to specify three rows of 150px, 1fr, and 200px, as well as four columns of 1fr each, we could write this as follows:

grid-template: 150px 1fr 200px / repeat(4, 1fr);

Notice how we can use any valid grid-template-rows and grid-template-columns values. We can also mix in grid-template-areas values. For that, we specify the grid areas as rows with their height and add column sizes after a forward slash.

To illustrate how we can leverage this shortcut, let’s have a look at our page example that used grid-template-areas:

.container {  display: grid;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer"
  ;
  grid-template-rows: 200px 1fr 200px;
  grid-template-columns: 150px 1fr;
}

We can rewrite this using grid-template to the following definition:

.container {  display: grid;
  grid-template:
    "header header" 200px
    "sidebar content" 1fr
    "footer footer" 200px /
    150px 1fr
  ;
}

We have now integrated grid-template-rows and grid-template-columns into the grid-area definition. By adding the height values for each row next to the row, we’re able to tell immediately how tall a given row is. We added the column widths at the end of the grid-template value, separated with a single forward slash.

The grid-row and grid-column attributes

Instead of having four different CSS rules to define the span and placement of an item within a grid, we can arrange it using grid-row and grid-column. Both use the same argument as grid-row-start and grid-row-end, and grid-column-start and grid-column-end, respectively.

So, we’d originally place an element like this:

.item {  grid-row-start: 2; /* Make it begin in the second row */
  grid-row-end: span 3;
  grid-column-start: 4;
  grid-column-end: span 5; /* Make it reach to the ninth
    column */
}

However, we can shorten it to this:

.item {  grid-row: 2 / span 3;
  grid-column: 4 / span 5;
}

We can also use named columns, like so:

.item {  grid-row: navigation / footer;
  grid-column: sidebar / content;
}

Any valid value for the expanded attributes is also valid for the shortcuts.

The gap attribute

Last but not least, there is a shortcut for gap definitions called gap. Instead of using row-gap and column-gap, we can either use gaps with a single value to denote a valid size for both row and column gaps or specify row gaps and column gaps separately with two different values, much like padding and margin.

Let’s assume we have the following grid definition with row gaps and column gaps:

.grid {  display: grid;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer"
  ;
  row-gap: 15px;
  column-gap: 30px;
}

We can then use the gap attribute to shorten the code, like so:

.grid {  display: grid;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer"
  ;
  gap: 15px 30px;
}

If we used the same values for row-gap and column-gap, we could even shorten the gap value to a single value, much like margin and padding.

Shortcuts help us to reduce the verbosity of our code. They can help us to be less repetitive and communicate our grid with more clarity. Some of these shortcuts, especially grid, might need more effort to write but can save us much time once we’re familiar with them. Using them isn’t mandatory, either. Some developers prefer shortcuts; some don’t.

 

Summary

In this chapter, we’ve now looked at the basic terms, structures, rules, attributes, units, and functions of CSS Grid. We’ve seen that a grid doesn’t have to look like just a bunch of rows and columns, with CSS Grid allowing us to build complex layouts with relatively small tools.

With grid-template-rows, grid-template-columns, grid-area, and grid-template, we can specify what the grid looks like, how large different grid tracks are, and how many of them there are. Moreover, we can precisely define where an item will be placed inside the grid with grid-area, grid-row, grid-column, and their specific start and end variants, such as grid-column-start or grid-row-end. Then, gap definitions help us separate items without the need for complex padding and margin definitions on the items.

To practice the things we’ve learned now, we will have our first look at Awesome Analytics, our overarching project, in the next chapter. We will learn how to apply grids to existing structures and how to work with CSS Grid to achieve the layouts we’d like.

About the Author
  • Pascal Thormeier

    Pascal Thormeier from Zurich, Switzerland, is a seasoned senior web dev and software engineer. With almost two decades of experience in web development, Pascal worked on countless large and small projects and has proven his skills with award-winning projects on many occasions. He has a flair for all things tech and enjoys fiddling with electronics as much as he enjoys complex software projects.

    Browse publications by this author
Mastering CSS Grid
Unlock this book and the full library FREE for 7 days
Start now