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:

<grid-area name>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:

Header
ContentEmptySidebar
Footer


This design has four items, which we name item 1 to 4 in our stylesheet, and assign a name using grid-area:

.item-1 {
   grid-area: Header;
}

.item-2 {
   grid-area: Content;
}

.item-3 {
   grid-area: Sidebar;
}

.item-4 {
   grid-area: Footer;
}


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:

.Container {
   display: grid;
   grid-template-columns: auto 30px 150px;
   grid-template-rows: auto;
   grid-template-areas:
      "Header Header Header"
      "Content . Sidebar"
      "Footer Footer Footer";
}


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:

.Container {
   display: grid;
   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:

.Container {
   display: grid;
   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:

.item-1 {
   grid-column: 1 / 2;
   grid-row: 1 / 2;
}

.item-2 {
   grid-column: 5 / 6;
   grid-row: 2 / 3;
}


item-1
item-2


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:

.Container {
   grid-auto-columns: 60px
   grid-auto-rows: auto
}


Since we specified three extra columns, 60px wide, using grid-column, the grid now looks like this.

item-1
item-2



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:

ValueEffect
rowAutomatic placement of items in rows in coding order
columnAutomatic placement of items in columns in coding order
denseAutomatic placement of items in the grid, where there is room, regardless of coding order
row denseAutomatic placement of items in rows in the grid, where there is room, regardless of coding order
column denseAutomatic 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):

item-1 item-6


The code for the container with the six items is:

<DIV CLASS="Container">

   <DIV CLASS="item-1">item-1</DIV>
   <DIV CLASS="item-2">item-2</DIV>
   <DIV CLASS="item-3">item-3</DIV>
   <DIV CLASS="item-4">item-4</DIV>
   <DIV CLASS="item-5">item-5</DIV>
   <DIV CLASS="item-6">item-6</DIV>

</DIV>


The class .Container that goes with it is at this point:

.Container {
   display: grid;
   grid-template-columns: 40px 40px 40px 40px 40px 40px;
   grid-template-rows: 25px 25px;
}


And the classes for item-1 and -6 are:

.item-1 {
   grid-column: 1;
   grid-row: 1 / 3;
}

.item-6 {
   grid-column: 6;
   grid-row: 1 / 3;
}


We want the remaining items to float. Here we specify flow as rows, so we add this to the container:

.Container {
   display: grid;
   grid-template-columns: 40px 40px 40px 40px 40px 40px;
   grid-template-rows: 25px 25px;
   grid-auto-flow: row;
}


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:

item-1item-2item-3item-4item-5item-6


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:

item-1item-2item-3item-4item-6
item-5


If we had used grid-auto-flow: column instead, it would have looked like this:

item-1item-2item-4 item-6
item-3item-5



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:

ValueEffect
startThe grid is aligned with the container's left border
endThe grid is aligned with the container's right border
centerThe grid is centered horizontally in the container
stretchThe grid is stretched to fill out the container horizontally. Only possible if the at least one column does not have fixed width.
space-between The columns in the grid are separated and evenly distributed horizontally. The distances between the outer columns and the container's border are unaffected.
space-aroundThe 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.
space-evenlyThe columns in the grid are separated and evenly distributed horizontally. This includes the distance between the outer columns and the container's borders.


justify-content: start


justify-content: end


justify-content: center


justify-content: stretch


justify-content: space-between


justify-content: space-around


justify-content: space-evenly



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:

ValueEffect
startThe grid is aligned with the container's top
endThe grid is aligned with the container's bottom
centerThe grid is centered vertically in container
stretchThe grid is stretched to fill out the container vertically. Only possible if the at least one row does not have fixed height.
space-between The rows in the grid are separated and distributed evenly. The distances to the container's top and bottom are unaffected.
space-aroundThe 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.
space-evenlyThe 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.


align-content: start


align-content: end


align-content: center


align-content: stretch


align-content: space-between


align-content: space-around


align-content: space-evenly



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.