CSS grid creates complex, responsive web designs more easily and consistently across browsers. In simple words, you create a grid where you place elements pretty much anywhere, thereby creating pretty good responsive websites, but before we proceed we need to understand the boring stuff.
The Boring Terminologies
Gid container It's the element on which display: grid is applied. It is the direct parent of all the grid Items.
grid items Grid items are the children of the grid container,
grid line
The dividing lines that make up the structure of the grid, i.e the column grid lines or row gridlines; these lines by default cannot be seen unless you set a border to it.
grid track
The space between 2 adjacent grid lines
grid area The area surrounded by 4 grid lines.
grid cells
A single unit of the grid
Grid Properties
Here you've got 2 sets of properties. One applied to the parent, the other to the child. It's pretty much similar to the flexbox.
so here is the list of parent properties that we'd be discussing
- display:grid
- grid-template-columns
- grid-template-rows
- grid-auto-columns
- grid-auto-rows
- grid-auto-flow
- auto-fix
- auto-fill
- minmax()
- grid-template-area
- grid-area
display:grid if you remember using display: flex on a container. you'd noticed that the layout might sometimes change. i.e the elements might be placed in a single line. this is because flex is 1-dimensional.
if you apply display: grid on a container, the layout will remain the same, well thats because the grid is 2-dimensional.
display: grid is applied to the parent. unless you apply this property you cannot work on the elements as a grid, obviously.
there are 2 values that you can apply that are associated with the grid, i.e
->display:grid (generates a block-level grid)
->display:inline-grid (generates an inline-level grid. i.e takes space according to the grid)
grid-template-columns this basically tells us how many columns do you need inside the container. The value it accepts is the width of each col. these values can be in any format px,%, rem, etc...
let's look at the following example grid-template-columns: 300px 300px 300px; here we create 3 columns with 300px width each. say you add another 200px on the right side, you'll basically be defining one more column.
a pretty interesting unit I came across is the "fr". this unit is basically a fractional unit. the fr unit works wrt the free space of the container. If we have 1fr 1fr 1fr this basically means that the free space is divided equally among 3 elements. Free space refers to the empty space that is left after adding your elements and their margins.
if we come across a situation where each column has the same width, instead of defining it multiple times in the grid-template-columns property we can use the following shorthand: repeat(3,100px); where 3 represents the no of columns and 100px represents the width of each column. we can also use this in conjunction with different columns. eg grid-template-columns: repeat(3,100px) 300px;
grid-template-rows same as the above. instead of defining column size[width], we define row size[height].
if the no. of columns are more than the elements we create an empty row by default. with the width specified of that given row.
if you plan on using fr for row and your design is acting possessed, it is most likely because you haven't set a fixed height; if you don't set a height there will be no free space as it's gonna a default property of fit-content.
before we proceed further I'd like you to understand the concept of implicit and explicit. so, basically what programmers define within a container is called explicit. such as the width and height of a cell/row/column and the default nature of what follows because of the explicit action is called implicit. such as the overflow elements move down to a new row.
now that you know the difference let's move forward!
grid-auto-rows/grid-auto-columns if the width of the column and the height of the row is not mentioned explicitly, using grid-auto-rows/columns you can set default values for all rows and columns. grid-auto-rows:300px; grid-auto-columns:100px;
grid auto flow if the elements are more than the columns defined. the above property specifies what approach should be taken!
grid-auto-flow: row; here we stack in a new row below the existing one. grid-auto-flow: column; here we add the elements besides the existing one.
auto-fit, auto-fill, and minmax() function these properties basically help us to make our layout responsive, i.e if you want the browser to automatically show fewer columns in a mobile browser & more in the desktop view, without many media queries to dictate this responsive behavior.
up until a certain viewport, auto-fit and auto-fill act similarly. the difference between the two is made apparent when the viewport gets wide enough to fit another column, at that point the browser is faced with 2 approaches to deal with this problem.
say, the viewport is expanded enough to accommodate another column, the browser checks if it has more elements than the number of columns. If it does, it adds it to the newly empty space.
If the viewport is reduced, the column size would obviously reduce, at this point the items are pushed back to the original location. i.e back to the row below.
now, what if the viewport is still expanded to accommodate another column, but this time there are no more elements to accommodate it. does it just fill it with empty spaces or does it stretch the element size to fill the empty spaces? The answer to either one of those two lies with either auto-fit or auto-fill
Think of it this way,
auto-fill just wants to make sure everything is filled, even if it is with empty boxes.
while auto-fit makes sure it's a perfect fit by stretching the elements :)
grid-template-area and grid-area using these 2 elements we can pretty much easily size and place elements according to our needs. I'm just gonna list out steps and hope you follow:) step 1) write all the main div elements you wish to position step 2) each div has a unique class name step 3)create a mock layout of the divs using grid-template-area
grid-template-area: "a a a" "b b f" "c . e" step 4) assign each mock value to a class of your div. eg .header{ grid-area:"a" }
this .header div will take the entire width of the first row
eg .aside{ grid-area:"b" }
this .aside will take the first 2 spans.
" . " represents empty space.
the benifit of the above is that you can make the website adaptive so easily
eg:
@media screen and (max-width:768px){
.container{
grid-template-area: " . a ."
"b b b"
"e f c"
}
}
grid-gap
as the name suggests it provides gap between columns and rows.
grid-gap:30px;
the above statement is actually a shorthand of grid-column-gap:30px and grid-row-gap:30px