# CSS Grid Layout

## Summary


When displaying content on a webpage, there's often a need to layout the content in a particular way. For example, we may want the header and footer sections to span the entire width of the viewport while the main content be organized as a three-column layout. Header section itself may be divided into a fixed-width logo section to the left and a flexible-width title section to the right. 

CSS Grid Layout is a standard that gives user interface designers a powerful system to implement layouts with ease. It's part of the CSS3 specification standardized by W3C.

It's meant to complement and not replace earlier systems such as CSS Flexbox.

## Discussion

### Why should I adopt CSS Grid when there's already CSS Flexbox?

Traditionally, layout was done using HTML tables. Then came CSS properties `display`, `float` and `position` that allowed us to control the layout. While these are still relevant, Flexbox came along to provide an easier way to distribute space and align content. 

The limitation with Flexbox is that it does layout only in one direction. Thus, items can be laid out horizontally but not vertically at the same time. Even if the items were to wrap across multiple lines, items on each line will not be aligned to those on other lines. Via nesting, Flexbox can be used to create two-dimensional layouts but CSS Grid is easier to use. 

CSS Grid is capable of aligning items both horizontally and vertically. Interestingly, items within the grid can also overlap, which neither Flexbox nor a HTML table element is capable of doing. 

CSS Grid doesn't replace Flexbox. Grid items can be flex parents and vice versa. 


### Which are the key building blocks of CSS Grid?

CSS Grid has the following parts:  

    + **Container**: This is the element that contains the grid within it. It's defined by CSS `display: grid`.
    + **Item**: Immediate child elements of a container are grid items. Grandchildren and further nested elements are not considered as grid items.
    + **Line**: A grid is split into rows and columns using grid lines. Lines also define the container's borders. Lines are numbered, starting from 1. Thus, a grid of m rows will have m+1 horizontal lines; of n columns will have n+1 vertical lines.
    + **Track**: A grid track is a generic term for a grid row or column. It's the space between two adjacent grid lines.
    + **Cell**: This is an intersection of a row and a column. It's the smallest unit of the grid that can be referenced.
    + **Area**: This consists of one or more adjacent grid cells.

### What are the different ways of specifying width in CSS Grid?

Grid items, rows and columns can be sized **explicitly** using CSS properties `grid-template-rows` and `grid-template-columns`. For example, `grid-template-columns: 90px 50px 120px` defines three columns with exact sizes. 

What if we had five items but only two columns are defined? The extra three grid items will be sized **implicitly**. If `grid-auto-flow: column`, we'll end up with five columns. If `grid-auto-flow: row`, we'll end up with three rows with the last row having only one item. 

For explicit sizes we can use `px`, `em`, `%`, etc. Fractional sizes (`fr`) can also be used. Thus, `grid-template-columns: 1fr 2fr` will make two columns, with the second one twice as wide as the first. While `px` specifies **fixed** sizes, `fr` specifies **flexible** sizes. Fractional sizes are calculated based on remaining space after other length values have been processed. For example, given `grid-template-columns: 3rem 25% 1fr 2fr`, the calculation would be `1fr = ((gridwidth) - (3rem) - (25% of gridwidth)) / 3`. The value `auto` will stretch grid item to fill remaining space. 


### How do I control the alignment of content in CSS Grid?

A grid item can be aligned within its cell or area using CSS property `justify-self` for horizontal alignment and `align-self` for vertical alignment. These effectively adjust margins for the items. Each of these properties can take values start, end, center, or stretch.  

What if we wish to apply the same alignment to all grid items? This is done by specifying CSS properties at the container level. Use `justify-items` for horizontal alignment and `align-items` for vertical alignment. As a shortcut, there's also `place-items` that specifies alignment in both directions. 

What if all the grid's tracks take up a space smaller the container? Then `justify-content` and `align-content` becomes useful not just for alignment but also for adding spaces in the right places to fill the container. These effectively adjust padding for the container. Some allowed values include normal, start, end, center, stretch, space-around, space-between, space-evenly, baseline, first baseline, and last baseline. 

Alignment works for both inline and block elements. 


### What are named areas and where are they useful?

We can make an item span multiple columns using `grid-column-start`, `grid-column-end`, `grid-row-start`, and `grid-row-end`. Shortcuts for these are `grid-column` and `grid-row`. For example, `grid-column: 3 / span 2` says that item will start from third column and span two columns. 

**Grid areas** offer a simpler way to avoid using grid line numbers. Areas can be only rectangles. Areas are named for easy referencing. Gaps can exist between areas but not between cells within an area. Gaps themselves can be set using `grid-row-gap` and `grid-column-gap`, with `grid-gap` as a shorthand to set both. Grid gaps are also called *gutters*. 

Within HTML elements, use CSS property `grid-area` to name the target area. This tells exactly in which area this content must be placed. The mapping of grid cells to grid areas is done using the `grid-template-areas` property. For a responsive design, we could use media queries to switch between different definitions of template areas without duplicating the content.  


### When there's nested grids, what's the use of subgrids?

Consider the use of grids to lay out cards. With nested grids, each card has an inner grid that's used to organize card title, an image and a description. Layout of contents in the inner grid is independent of the outer grid. Moreover, one card is not aware of alignment of contents in another card. This means that if some card titles run into multiple lines, subsequent content within the inner grid will not be aligned across cards (the outer grid). 

Subgrid solves this problem. A subgrid defers the definition of its rows and columns to its parent grid container. Content of the subgrid influence the sizing and alignment of its parent container. 

A subgrid can be created with `{ display:grid; grid-template-columns:subgrid; grid-template-rows:subgrid; }`. It's possible to create rows-only or columns-only subgrid. Within the subgrid, we may not want extra spacing between rows. This is achieved with `row-gap:0`. 


### Could you share additional technical details on CSS Grid?

It's interesting to note that grid line numbers can be negative. Value -1 refers to last line; value -2 is last but one line; and so on. Also, fractional widths can be floating point numbers. 

With fractional units, available space is filled up but it still obeys the minimum size of container or the content within. Sizes are not calculated upfront. Only after content is placed into grid items, the sizes of grid tracks are calculated. 

By default, grid items will be stretched to fit the grid area. Avoid using percentages in paddings or margins on grid items. Number of rows and columns can be defined using `grid-template-areas`, `grid-template-rows` and `grid-template-columns`. If there's conflict, the larger number will be used. 

Don't assume you need breakpoints, for example, to reflow content with varying number of columns. Sizing with only percentages will not help you exercise the full power and flexibility of CSS Grid. CSS Grid is simple enough to be used directly. Don't look for a grid framework. 


### What are some resources for beginners to learn CSS Grid?

From the many online resources to learn CSS Grid, we mention a few: A Complete Grid Guide by CSS-Tricks, Rachel Andrew's Grid by Example and Layout Lab by Jen Simmons.

An interactive CSS Grid cheatsheet from Ali Alaa is handy.

For debugging CSS Grid, there are browser add-ons that developers can use. Firefox DevTools comes with Grid Inspector to inspect the grid and show line numbers and grid area names. 

Most browsers support CSS Grid, including partial support from IE11. See Can I Use to see current support.

## Milestones

1940

The Swiss formalize the use of grids as a design tool. They see grids as bringing order to a design layout. 

1996

Frame-based layout via stylesheets is proposed. 

Dec  
2005

**CSS3 Advanced Layout Module** is proposed. By April 2009, this becomes **CSS Template Layout Module**. The idea of CSS Grid Layout closely follows from these early drafts. However, these early proposals are not adopted by browser makers. 

Jul  
2009

W3C publishes a working draft of **CSS Flexible Box Layout** or Flexbox. After multiple revisions, first Candidate Recommendation of Flexbox is released in September 2012. 

Apr  
2011

Microsoft needs a flexible layout tool for the web and native app development on Windows. With some inspiration from Silverlight, Microsoft ships IE10 with an implementation of a grid layout behind `-ms-` vendor prefix. This is followed with a W3C working draft of **CSS Grid Layout**. Thus, for the first time W3C gets a draft along with a working implementation.  

Aug  
2011

After many months of internal development, Twitter open sources **Bootstrap**. It's a CSS framework that enables easier creation of layouts based on a 12-column grid. CSS Grid provides a more flexible layout since designers need not start with 12 columns. 

May  
2017

W3C publishes **CSS Grid Layout Module Level 1** as a Candidate Recommendation. This is also the year when many major browsers start supporting CSS Grid. 

Feb  
2018

W3C publishes the first working draft of **CSS Grid Layout Module Level 2**. Level 2 adds subgrid capabilities and allows nested grids to participate in the sizing of parent grids. It also adds aspect-ratio-controlled gutters. In December 2019, Firefox becomes the first browser to implement subgrids and continues to be the only browser even in December 2020.