Adaptive design using grid (CSS). Part 2: Placing of elements
Explicit sectioning of the UI using grid-template-areas
Placing items in our grid can be done explicitly. For most people, this is likely to be the method making the most sense. If you have named your items using the grid-area parameter (explained in Part 3), you can use grid-template-areas, which can have the following values:
The name of the grid area, as specified using grid-area.
A full stop, meaning an empty cell
For the code to work properly, all areas must be specified.
Let's look at an example, so it makes sense:
Consider a standard layout as favored e.g. by WordPress, we need a header, a footer, both using the entire width, a slim sidebar for log-on and an area for the page content. The sidebar must have a fixed width, and there must be some empty space to the left of the sidebar, which is done using an empty cell with a fixed width, So, we need a 3x3 grid, that gives us a layout that looks like this:
This design has four items, which we name item 1 to 4 in our stylesheet, and assign a name using grid-area:
Now we are ready to specify that we want a grid with three columns, where the width of the first is auto and the next two are 30 and 150px wide, in that order. The height for all rows are going to adjust to the content, i.e. set to auto, and last, but not least, we have to specify which cells are used for which items in our layout:
Important: All rows must have the same number of cells stated!
We now have a functional grid. From here it is a matter of adjustment to make it look nice.
Explicit sectioning of the UI using grid-template
The parameter grid-template is a shorthand version of grid-template-rows, grid-template-columns and grid-template-areas. The syntax is grid-template: "grid-template-areas" | grid-template-rows / grid-template-columns (notice the slash used as separator). You can specify all three values as none, at which the parameters are set to their initial values.
It is the type of shorthand code that probably causes more confusion than less code, which is the main idea with the shorthands, so that alone is sufficient grounds for recommending not to use grid-template. There is also the matter of grid-template not doing a reset of the implicit grid properties (grid-auto-columns, grid-auto-rows and grid-auto-flow), which you want in most cases, so you may end up with some undesired side-effects with your code as well.
Just to demonstrate the syntax, the code for the container above will look like this instead using grid-template:
"Header Header Header" auto
"Indhold . Sidebar" auto
"Footer Footer Footer" auto / auto 30px 150px
Implicit sectioning of the UI
Instead of an explicit placement of items in grid, you can have an implicit placement. It is a different way of thinking placement of items than the explicit, and not as intuitive. On the other hand, you can get a dynamic structure that the explicit placement don't allow.
You have two approaches to implicit placement, and they can be combined without any problems.
Auto-generated columns and rows using grid-auto-columns and grid-auto-rows
The method takes its beginning in a grid as we know them, e.g. a container with two columns, 40px wide, and two rows, 25px high:
grid-template-columns: 40px 40px
grid-template-rows: 25px 25px
What the implicit declarations can do, is to allow referencing to places that don't exist, i.e. in a 2x2 grid, you can place an item in the third row, cell number five.
If you, for the grid above, specify that you want item-1 at row 1, cell 1 and item-2 in row 2, cell 4, using grid-column and grid-row (see Part 3 for details), the code looks like this:
grid-column: 1 / 2;
grid-row: 1 / 2;
grid-column: 5 / 6;
grid-row: 2 / 3;
Default width and height (track size) for the auto-generated rows/columns is 0px, which is useless in practice, but you can specify track sizes for auto-generated rows/columns, using grid-auto-columns and grid-auto-rows, e.g. an container with auto-generated columns that are 60px wide and automatic adjustment of height:
Since we specified three extra columns, 60px wide, using grid-column, the grid now looks like this.
Flow of items using grid-auto-flow
You may want to have items on your UI with a fixed place and other items floating around on the remaining space, dependent on the size of the viewport. For this purpose we have grid-auto-flow, which can have the following values:
Automatic placement of items in rows in coding order
Automatic placement of items in columns in coding order
Automatic placement of items in the grid, where there is room, regardless of coding order
Automatic placement of items in rows in the grid, where there is room, regardless of coding order
Automatic placement of items in columns in the grid, where there is room, regardless of coding order
Note: Dense places items after where there is room for them, which may not be an appropriate order for the readability of the page. Therefore, dense should be used with a bit of care.
Let's look at an example:
If we have a container with six items, named item-1 to -6, in a 6x2 cells grid, where item-1 and -6 form a left and right column on the page (e.g. a navigavion pane to the left and a columns with adds to the right):
Because we are using grid-auto-flow, we don't need to specify where we want item-2 to -5 placed. They will automatically be placed in a row between item-1 and 6, like this:
In the example here, all items have the same size, but that does not have to be the case, you could easily have items of different sizes. If for example item-3 becomes twice as wide as the other items, the items in the group item-2 to -5 are rearranged:
If we had used grid-auto-flow: column instead, it would have looked like this:
Horizontal alignment of grid in the container
The grid you have made, does not necessarily have to take up the entire space in the grid container. It might be something like all columns having fixed width and in total taking up less space than the width of the container. Aligning the grid horizontally in the container is done using justify-content. It is completely similar to alignment of text and items in flexbox. The values for justify-items are:
The grid is aligned with the container's left border
The grid is aligned with the container's right border
The grid is centered horizontally in the container
The grid is stretched to fill out the container horizontally. Only possible if the at least one column does not have fixed width.
The columns in the grid are separated and evenly distributed horizontally. The distances between the outer columns and the container's border are unaffected.
The columns in the grid are separated and evenly distributed horizontally. The distance between the outer columns and the container's border are half the distance between the columns.
The columns in the grid are separated and evenly distributed horizontally. This includes the distance between the outer columns and the container's borders.
Vertical alignment of grid
The grid you have made, does not necessarily have to take up the entire space in the grid container. It might be something like all rows having fixed height and in total taking up less space than the height of the container. Aligning the grid vertically in the container is done using align-content. It is completely similar to vertical-align for text and vertical alignment of items in flexbox. The values for align-content are:
The grid is aligned with the container's top
The grid is aligned with the container's bottom
The grid is centered vertically in container
The grid is stretched to fill out the container vertically. Only possible if the at least one row does not have fixed height.
The rows in the grid are separated and distributed evenly. The distances to the container's top and bottom are unaffected.
The rows in the grid are separated and distributed evenly. The distances between the outer rows and the borders are half the distance between the rows.
The rows in the grid are separated and distributed evenly. The distances between the outer rows and the borders are the same as the distance between the rows.
Horizontal and vertical alignment of grid at the same time
The variable place-content is a shorthand for align-content and justify-content. The syntax is place-content: align-content / justify-content (notice the slash as separator). The variable is supposedly not supported by the Edge browser at the time of writing (August 2019), so it is a variable that one should give some thought, before using, or at least test whether it has started working, since the page was written. As always, the recommendation from here is to avoid using shorthand variables as you loose some legibility of the code.
The shorthand variable grid
You can gather all your variables for your grid in a variable called grid. The syntax is grid: grid-template-rows grid-template-columns grid-template-areas grid-auto-rows grid-auto-columns grid-auto-flow. Considering the legibility of the code, the use of this shorthand is discouraged.