Grid Basics
The grid is a layout system that allows you to create complex and responsive grid-based designs. It provides a way to divide the web page into rows and columns, making it easier to position and align elements.
I. Introduction to Grid
Resource
1. Setting up a Grid
1. Grid container
We can think about CSS Grid in terms of containers and items. When you make an element a grid container, it will “contain” the whole grid. In CSS, an element is turned into a grid container with the property display: grid
or display: inline-grid
.
Note: Only the direct child elements will become grid items here. If we had another element as a child under one of these child elements it would not be a grid item.
<!-- index.html -->
<div class="container">
<div>Item 1</div>
<div>Item 2
<p>I am not a grid item!</p>
</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
.container {
display: grid;
}
2. Columns and Rows
Columns are the vertical tracks in a grid layout. They are defined using the grid-template-columns
property.
.container {
display: grid;
grid-template-columns: 200px 100px 300px;
/* Three column tracks with widths 200px, 100px, and 300px */
}
Rows are the horizontal tracks in a grid layout. They are defined using the grid-template-rows
property.
.container {
display: grid;
grid-template-rows: 50px 100px auto;
/* Three row tracks with heights 50px, 100px, and auto */
}
The grid-template
property is a shorthand for defining both columns and rows together. The columns are specified after the forward-slash (/
), and the rows are defined before the slash.
.container {
display: grid;
grid-template: 50px 100px / 200px 50px 100px;
/* Two row tracks (50px, 100px) and three column tracks (200px, 50px, 100px) */
}
2. Explicit vs. Implicit Grid
Resource
Explicit grid tracks are the ones you define directly using the grid-template-columns
and grid-template-rows
properties. These properties allow you to specify the size and number of columns and rows in your grid layout.
Implicit grid tracks are automatically created by the grid layout when there are more grid items than the explicit grid tracks can accommodate. These implicit tracks are added as needed to fit the extra grid items. By default, the size of implicit grid tracks is determined by the grid-auto-rows
and grid-auto-columns
properties.
.container {
display: grid;
grid-template-rows: 30px 100px; /* Two explicit row tracks */
grid-auto-rows: 80px; /* Size of implicit row tracks */
}
3. Gap
The gap between grid rows and columns is known as the gutter or alley. Gap sizes can be adjusted separately for rows and columns using the column-gap
and row-gap
properties.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
row-gap: 20px; /* Gap between rows */
column-gap: 30px; /* Gap between columns */
}
Furthermore, we can use a shorthand property called gap
to set both row-gap
and column-gap
.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
gap: 20px 30px; /* row-gap: 20px, column-gap: 30px */
}
II. Positioning Grid Items
Resource
1. Grid Lines
Grid lines are the horizontal and vertical lines that divide the grid into rows and columns, respectively. They are created implicitly when you define grid tracks (rows and columns) and they cannot be explicitly created. Grid lines are numbered starting from 1, and they are used to position grid items within the grid layout. They are what we use to position grid items.
.container {
display: grid;
grid-template-columns: 50px 100px; /* Creates 3 vertical grid lines (1, 2, 3) */
grid-template-rows: 100px 200px; /* Creates 3 horizontal grid lines (1, 2, 3) */
}
2. Grid Cells
A grid cell is the intersection of a row track and a column track. It represents a single unit of space within the grid layout. Each grid cell can contain one or more grid items, depending on how the items are positioned and sized.
3. Positioning
- grid-column-start: This property specifies the grid line where the item should start in the grid column. The grid lines are numbered from 1 (for the start edge of the grid) to (n+1) (for the end edge).
- grid-column-end: This property specifies the grid line where the item should end in the grid column.
- grid-column: This shorthand property sets both the
grid-column-start
andgrid-column-end
in a single declaration.
.item {
grid-column-start: 2; /* Start at the 2nd grid line */
grid-column-end: 4; /* End at the 4th grid line */
}
/* equivalent to */
.item {
grid-column: 2 / 4; /* Start at the 2nd line, end at the 4th line */
}
- grid-row-start: This property specifies the grid line where the item should start in the grid row.
- grid-row-end: This property specifies the grid line where the item should end in the grid row.
- grid-row: This shorthand property sets both the
grid-row-start
andgrid-row-end
in a single declaration.
.item {
grid-row-start: 1; /* Start at the 1st grid line */
grid-row-end: 3; /* End at the 3rd grid line */
}
/* equivalent to */
.item {
grid-row: 1 / 3; /* Start at the 1st line, end at the 3rd line */
}
4. grid-area
The grid-area
property is a shorthand property that defines a grid item's position and size within the grid container. It can be used in two different ways:
1. Positioning with Grid Line Numbers
- The
grid-area
property can be used to specify the grid lines where the grid item should start and end, both horizontally and vertically. - The syntax is
grid-area: row-start / column-start / row-end / column-end;
.item {
grid-area: 1 / 2 / 4 / 6; /* Starts at row 1, column 2; ends at row 4, column 6 */
}
2. Naming Grid Areas
- The
grid-area
property can also be used to assign a name to a grid item. - This name can then be referenced in the
grid-template-areas
property of the grid container to define the layout of the grid visually.
In the example, the grid layout is defined using the named grid areas, and the period (.
) represents an empty cell in the grid.
.living-room {
grid-column: living-room
}
.kitchen {
grid-area: kitchen;
}
.toilet {
grid-area: toilet;
}
.closet {
grid-area: closet;
}
.container {
/* grid */
display: grid;
grid-template-columns: 20vw auto 15vw;
grid-template-rows: 20vh 40vh auto;
/* naming grid-areas */
grid-template-areas:
"living-room living-room living-room"
"kitchen bedroom toilet"
"kitchen closet toilet";
}
III. Other Grid Properties
Resource
1. Fractional Units
The most basic way to make grid items dynamic is by using fractional units (fr
). This unit distributes the remaining space in a grid container after allocating space to any grid tracks with a fixed size. When multiple grid tracks are assigned fr
values, the available space is divided according to the ratio of those fr
values.
/* All columns have equal width */
grid-template-columns: 1fr 1fr 1fr;
/* The second column is three times wider than the others */
grid-template-columns: 1fr 3fr 1fr;
/* A mix of fixed and fractional sizes */
grid-template-columns: 200px 1fr 150px 2fr;
2. resize
The resize
property is used to specify whether an element is resizable by the user, and if so, in what direction(s) it can be resized.
none
: the default value, the element cannot be resized by the user.both
: allows the user to resize the element both horizontally and vertically by dragging the element’s bottom-right corner.horizontal
: allows the user to resize the element horizontally by dragging the element’s right edge.vertical
: allows the user to resize the element vertically by dragging the element’s bottom edge.
.container {
display: grid;
resize: both;
overflow: auto; /* to enable scrolling if we resize the container to be smaller than our grid can accommodate */
}
3 .repeat()
The repeat()
function is used to create repeating patterns of grid tracks (rows or columns) within a grid container.
repeat(repetitions, size)
repetitions
: This can be either a positive integer value representing the number of times to repeat the track size, or the keywordauto-fill
orauto-fit
.size
: This can be a length value (e.g.,20px
,1fr
), a percentage value, or a flexible length (minmax(min, max)
).
grid-template-columns: repeat(4, 200px);
/* Creates 4 columns, each with a width of 200px */
grid-template-columns: repeat(2, 150px) repeat(3, 100px);
/* Creates 5 columns: 2 with width 150px, followed by 3 with flexible width of 1fr */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* Creates as many columns as possible with a minimum width of 200px and a maximum width of 1fr, based on the available space */
grid-template-rows: repeat(auto-fit, minmax(100px, auto));
/* Creates as many rows as needed to fit the content, with a minimum height of 100px and a maximum height determined by the content */
4. Minimum and Maximum Track Sizes
Example: The grid rows will have a size of 100px
, the smallest value from the list (100px
, 200px
, 300px
, 400px
, 500px
).
Example: A grid with 2 rows and 5 columns. The row heights will be either 200px
or 50%
of the container's height (whichever is smaller), and the column widths will be either 120px
or 15%
of the container's width (whichever is larger).
.grid-container {
grid-template-rows: repeat(2, min(200px, 50%));
grid-template-columns: repeat(5, max(120px, 15%));
}
5. Dynamic Minimum and Maximum Sizes
1. minmax()
This function is specifically used with Grid Layout. It defines a size range for grid tracks, allowing them to grow or shrink within a specified minimum and maximum size.
Syntax: minmax(min-size, max-size)
.
min-size
: The minimum size the grid track can be. It can be a length value (e.g.,150px
) or a flexible value likemin-content
,max-content
, or a percentage.max-size
: The maximum size the grid track can be. It can be a length value (e.g.,200px
) or a flexible value likemin-content
,max-content
, or a percentage.
The function is used with the following CSS properties:
grid-template-columns
grid-template-rows
grid-auto-columns
grid-auto-rows
Example: The grid container will have 5 columns, and each column track will have a minimum width of 150px
and a maximum width of 200px
.
- If the grid container is wider, the column tracks will grow up to
200px
, but not beyond that. - If the grid container is narrower, the column tracks will shrink down to
150px
, but not smaller.
.grid-container {
grid-template-columns: repeat(5, minmax(150px, 200px));
}
2. clamp()
This function allows constraining a value within a specified range.
Syntax: clamp(min-size, ideal-size, max-size)
min-size
: The minimum size the element can be.ideal-size
: The preferred size the element should be if possible.max-size
: The maximum size the element can be.
The function can be used anywhere, not just within a grid container, such as width
, height
, font-size
, padding
, margin
, etc.
Example: The grid container will have 5 column tracks. Initially, each column track will try to be 20%
of the container’s width (preferred value).
- If the
20%
width is less than150px
, the column tracks will be set to150px
. - If
20%
of the container’s width is greater than200px
, the column tracks will be set to200px
.
.grid-container {
grid-template-columns: repeat(5, clamp(150px, 20%, 200px));
}
6. auto-fit
and auto-fill
Resource
1. auto-fit
auto-fit
is a value used with the repeat()
function. It creates as many grid tracks (rows or columns) as possible while respecting the max-content
size of the grid items, not overflowing the grid container, and stretching the remaining grid tracks to fill the available space.
Syntax: repeat(auto-fit, size)
auto-fit
can also be used withminmax()
to define the size range for the grid tracks.- The grid tracks will stretch to fill the available space, up to the
max-size
specified inminmax()
.
**Example 1: ** The grid will create as many 200px
wide columns as can fit within the container's width.
.grid-container {
grid-template-columns: repeat(auto-fit, 200px);
}
Example 2: The grid container will create as many columns as possible, with a minimum width of 100px
and a maximum width of 300px
.
.grid-container {
/* fit as many columns as possible, each column has the min-width of 100px
when the page expands, each column can grow up to a max of 300px */
grid-template-columns: repeat(auto-fit, minmax(100px, 300px));
}
2. auto-fill
auto-fill
is also a value used with the repeat()
function. It creates as many grid tracks (rows or columns) as possible to fill the entire grid container, adding implicit grid tracks if needed, even if there are no grid items to fill them.
Syntax: repeat(auto-fill, size)
auto-fill
can also be used withminmax()
to define the size range for the grid tracks.- The grid tracks will stretch to fill the available space, up to the
max-size
specified inminmax()
.
**Example: ** The grid will create as many rows as needed to fill the container's height, with each row having an equal 1fr
height.
.grid-container {
grid-template-rows: repeat(auto-fill, 1fr);
}
Difference between
auto-fit
andauto-fill
auto-fit
creates only as many grid tracks as needed to fit the grid items.auto-fill
creates as many grid tracks as needed to fill the entire grid container, even if there are no grid items to fill the remaining tracks.As seen in the demonstration image below,
auto-fit
doesn’t create any more tracks after Item 3, butauto-fill
creates 3 more tracks to fill the entire grid, even though there are no more items to fill the remaining tracks.
7. Alignment
1. align-self
The align-self
property is primarily used in Flexbox and Grid layouts. It allows controlling the alignment of an individual child element along the parent container's cross-axis (perpendicular to the main axis).
2. justify-self
The justify-self
property is primarily used in Flexbox and Grid layouts. It allows controlling an individual child element's justification (alignment along the main axis) within the parent container.
While
align-self
andjustify-self
can be used on elements with a normal block-level layout (e.g.,display: block
), their effects will be limited. For optimal alignment control, it is recommended to use them with Flexbox or Grid layouts.
IV. Flexbox and Grid
Resources
1. Flexbox vs. Grid
Resource
1. One-dimension vs. Two-dimensions
- One-dimensional content: If you have content that needs to be positioned or aligned in a single dimension (either horizontally or vertically), Flexbox can make it easier to control how that content is positioned within a Flex container.
- Two-dimensional layout: If you want to accurately place content in a complex two-dimensional layout (both horizontally and vertically), Grid can be easier to use.
2. Content vs. Layout
- Content-first Design:
- In Flexbox, the content shapes the layout. The layout adapts and responds to the content within the flex container.
- Flexbox is well-suited for this approach because it provides control over the behavior of items (how they grow, shrink, their ideal size, and position in relation to each other) through logical rules based on the content.
- Flexbox layouts are dynamic, and the final layout is a consequence of the content and the flex container's dimensions.
- Layout-first Design
- In Grid, the layout shapes the content inside. The content must fit within the defined grid structure.
- Grid is an excellent choice for this approach because it gives you full control over the layout by defining grid row and column tracks.
- Content in a grid can only fill the spaces of explicit or implicit tracks, allowing you to define the overall layout structure first.
2. Combining Flexbox and Grid
If you want your overall layout to be a grid but want the grid items themselves to act as flex containers, you can nest Flexbox inside Grid. This allows you to benefit from the precise two-dimensional placement that Grid offers for the overall layout while also enabling the content inside each grid item to freely move and align using Flexbox.