How I use CSS Grid to Create a One-page Website
While there are other ways to achieving the same layout such as flexbox, I’m using CSS Grid only since that is the focus of this article.
Step 1 — Plan before coding
Planning before coding gets me to decide in advance
- the elements to be styled as grid-containers (aka parent)
- the no. of columns and rows I need for each grid-container
For this article, I’m reusing the outline I did for flexbox so that you can view the differences between using flexbox and CSS Grid.
Based on the above layout, I want to achieve the following:
A) A layout to display the content in a page. My footer sticks to the bottom of the page even when I don’t have much contents. If the content cannot be contained within a page, my page will extend accordingly.
body | grid-items:
columns: 1 | rows: 3
B) Navigation items can be switched from row to column arrangement depending on the screen size.
header | grid-items: nav1, nav2, nav3, nav4
(desktop view) columns: 4| rows: 1
(mobile view) columns: 1| rows: 4
C) Contents in main are centred.
main| grid-items: box 1 and box 2
columns: 1| rows: 2
Step 2 — Create your HTML file
Type out the html before styling.
Step 3 — Create CSS file
First, I remove the default margin and padding of
body elements, and add a height of 100%.
body to a grid-container, I add
display: grid to it. This automatically changes the direct children of
body to grid items.
Next, I work on creating the grid where I specify the width of my rows and the height of my columns.
To get the footer pushed down to the end of the page, I add
grid-template-rows: min-content auto min-content.
min-content: My first (aka header) row and last row (aka footer) will take up the minimum space they need.
auto: My second row (aka main) will take up the remainder of the parent container’s height.
For header, I transform the
header ul element into another grid-container. This transforms Nav1-4 to grid-items.
grid-template-columns: repeat(4, min-content). This creates 4 columns, each with a width of the minimum space they need.
Then I add
justify-content: space-evenly to space out the navigation items along the inline axis (row) of the grid container.
I add some styles to the header to make it look better.
Next, I work on
main, an element that wraps around two
divs with the class of
main into a grid-container so that I can use CSS Grid to place the two boxes in their respective position. After that, I used
grid-template-rows: min-content min-content and
justify-content: center to achieve my planned layout.
Now, I want to inspect the grid for
main element. I open the Grid Inspector tool in Firefox, and select
main under overlay grid. This will show the grid tracks in the
From the above screenshot, the grid tracks cover an area that is smaller than the grid container (main). This means we can make use of align-content to change its positioning along the block axis. I add
Styles are added to the main section to make it look better.
Styles are added to the
footer to make it look better.
Lastly, I change the arrangement of the navigation items based on the screen size using media query. This is done by changing the grid-template-columns property.
Recall that I had added
grid-template-columns: repeat(4, 1fr) to
header ul. By changing it to
grid-template-columns: none, no columns are explicitly defined and my grid layout will end up with having only 1 column.