CSS Grid Intro
Reference
January 21, 2018
I couldn’t hold off! Today I did the CSS Grid course. Start to finish in one day!
For quick reference:
- Setting Up A Grid
- Sizing Rows & Columns
- Sizing Grid Items
- Naming Grid Areas
- Naming Grid Lines
- Ordering Grid Items
- Aligning & Centering Items and Content
- Final Tips
Setting Up A Grid
First step is to create a container which will hold all of the grid items and set its display to grid
:
<div class="container"> |
To set the number of columns, add a grid-template-columns
property to the container. This can be set by pixels, rems, auto, repeat, etc. To set the number of rows, it’s grid-template-rows
:
.container { |
Note:
auto
will be sized automatically based on the content within the largest grid item.
Columns and rows are explicit if you specifically define how many there should be, and what their sizes should be; and implicit if you don’t define this information. When you have more container items than explicitly-defined rows and columns, the extra items will overflow to their best fit.
If you want a bit more control over what that “best fit” will be, you can use grid-auto-rows
and grid-auto-columns
to define the size of overflow areas. By default, overflow items will be put into the next row in the grid, but you can change the default behavior and make them overflow to a column with grid-auto-flow: column;
(default value is row
).
Sizing Rows & Columns
To create a gutter/margin within the grid, use grid-gap
. An interesting thing about grid-gap
: if you have this defined, it makes it so that setting column widths by percentage isn’t great! If you have 4 columns of 25%, it will actually go off the page because of the extra 60px of grid-gap
, using the example above. So percentages are ok if used in combination with auto
, but the better option is using fractional units fr
.
Fractional units works similarly to flex-grow
and flex-shrink
in Flexbox: they proportionally fill any unused space. So if you have 3 divs: div1
width is set to 50%, div2
is 3fr
, and div3
is 1fr
, div1
will take up 50% of the screen, then from the remaining unused space, div2
will get 75% of it, and div3
will get 25%.
You can also use a repeat()
function to define row and column widths. The grid will repeat whatever you have as the second argument, meaning you can create a mix of repeating grid areas. You can also use repeat
in conjunction with other definitions. Some examples:
.container { |
Auto-Fit & Auto-Fill
Another option for sizing columns & rows is to use auto-fit
and auto-fill
instead of explicit values:
.container { |
This says to leave it up to the grid to determine how many columns will be created, based on the viewport width. This enables the site to be responsive!!
There is a slight difference between auto-fit
and auto-fill
: auto-fill
will dynamically create the explicit grid area based on the viewport width, whereas auto-fit
will create the explicit grid area based on the number and contents of the grid items. So let’s say you want one grid item to always be on the right-most edge of your viewport: if you use auto-fill
this will be possible, but if you use auto-fit
, the item will only stay to the right-most side of the other grid items.
Minmax()
Now to get super-duper responsive layouts, minmax()
can be used together with auto-fit
or auto-fill
. Within a minmax()
definition, you declare the minimum and maximum widths or heights that the tracks should take up. As a result, the tracks will be determined based on the size of the window. For example:
.container { |
Sizing Grid Items
Individual grid items can also be resized in a different way to their default row/column pattern. To have a grid item go across multiple columns, add a span
instruction to that particular grid item: grid-column: span 2
. The same span technique works across rows: grid-row: span 4
.
Note: if you’re spanning 3 columns, but there are only two columns on that row, by default the 3-column grid item will be pushed down to the next row, leaving empty space: CSS Grid will always push items to wherever they can fit by default. Likewise, if you try to span more columns than are defined in the grid, new implicit columns will be created.
grid-column
and grid-row
are shorthand for grid-column-start
and grid-column-end
(and same for rows). So it’s possible to specify and exact location in the grid where the item should begin and end. Or you can condense it into two parts of the same line:
.my-grid-item { |
Note that to use the 1 / -1
technique, you have to define your rows or columns—whichever you want to apply this span to. So if you have only defined columns, and then try to set grid-row: 1 / -1;
, it won’t work. It’s also important to note that it will only be able to span explicit columns or rows; if other grid items have overflowed into implicit areas, the full-width span may not work in the way you want or expect it to.
Filling Empty Grid Spaces
If you have changed the sizing for some grid items, because of how overflow works, you might end up with holes in the layout—grid areas where the next grid item couldn’t fit. If order isn’t important, you can fill in these empty grid spaces by setting the container to dense; this way, when faced with empty spaces, the grid will check whether there is any grid item that can be used to fit the space.
.container { |
Naming Grid Areas
Going back to the layout of columns and rows, it’s also possible to name areas and then assign grid items to a named area, rather than referencing column or row numbers. For example:
.container { |
By identifying a name for each area of your grid and then assigning a grid item to that area, grid items will be stretched to fill up the whole area. This is also a good way to completely change the order for a responsive layout. From the example above, you could add a media query to change which sections are displayed where:
@media (max-width: 700px) { |
Another option for setting the layout is to name areas without first defining what those areas are:
.container { |
Naming Grid Lines
It’s also possible to name grid lines instead of grid areas, and then use those names to assign grid items. You would set this up by adding the line name inside square brackets []
when defining the column or row widths/heights. You can also give more than one name (separated by a space) to each grid line. For example:
.container { |
Ordering Grid Items
Grid areas can be ordered…especially useful for media queries if you want to change from the default order on smaller screens. We use the order: 1
property to define an order for an individual grid item. The default order for every item is 0
, so you can use -1
to move something to the top, or order all of the items.
Note: changing the order with CSS doesn’t change the order for accessibility purposes! If you move text around in the display, a screen reader will still read them in the order they appear in your HTML.
Aligning & Centering Items and Content
CSS Grid comes with 6 properties to help align individual grid items. They start with justify- for items on the row (x) axis, or align- for items on the column (y) axis. Unlike with Flexbox, these designations don’t change. For quick reference, the CSS Tricks Guide shows demos of each, but to quickly explain…
Justify/Align Items
Determines how unused space in a grid area will be allocated for all grid items. Default is stretch
which takes up all available space. Other options are start
, end
, and center
. These can be applied individually to the container, or combined in one row with place-items
:
.container { |
Justify/Align Content
Determines how unused space in the grid container will be allocated. Default is stretch
which takes up all available space. Other options are start
, end
, center
, space-around
, space-between
, and space-evenly
.
Justify/Align Self
Determines how unused space in the grid area for an individual grid item will be allocated. Default is to inherit the definition that was set for the whole grid.
Example of -content
and -self
is as follows:
.container { |
Cool Fact!
To center text within an individual item, you can set its display to grid
and use these properties:
p { |
Final Tips
So that’s all the basics covered! To wrap up the course we built a few demo sites using a mix of the properties above. Some final highlights & tips:
Nesting Grids
Grids can be nested within each other as much as you want. A good example is for cards, where you want the elements in the card to display a certain way, but also want the cards themselves to display well next to each other. In this case you would put display: grid;
on the wrapper containing the cards and on the card container itself. I wrote this example to demonstrate.
Flexbox vs. CSS Grid
Flexbox and CSS Grid can work well together, although there are some things that each can do that the other can’t:
- Flexbox gives you the option to order rows/columns from right to left or down to up with
row-reverse
andcolumn-reverse
. CSS Grid doesn’t have a built-in option for this. - If you want to stack elements in an inverted pyramid (i.e. overflow divs are centered if they’re in a row on their own), you have to use Flexbox; Grid can’t break its column definitions.
- Likewise if you want variable column widths on each row, Flexbox is the necessary choice.
- There is no concept of
grid-gap
automatic margins in Flexbox.
CSS Variables
Finally, not really related to CSS Grid but I also learned how to create and use CSS variables (aka custom properties) thanks to the Net Ninja’s newest YouTube tutorial series. Variables allow you to set a property value which you can then reference throughout your CSS; a good example is for color schemes…you set the color in a variable and then use the variable rather than a hex code. Then if you decide to change your color scheme, you only need to update the variable value, rather than every place that color appears. Brilliant!
CSS variables need to be declared within a selector, and the de facto way to do this is to declare them at the top of your CSS in a root element. Variables are declared and called with double dashes --
:
:root { |
Imagine this with much much more CSS and it’s pretty awesome to think of just changing the hex colors once. Awesome! Important to note though, not currently supported in IE.
Whew!
So that was a long and productive day!