How I use CSS Grid and Flexbox to Create a One-page Website
CSS Grid for page layout and Flexbox for UI elements
While we can use either CSS Grid and Flexbox for a webpage layout, CSS Grid tends to be used for page layouts while Flexbox tends to be used for aligning UI elements. Let’s create a webpage to see how this pans out in real code. I’ll be using a common design as below:
Step 1 — Plan before coding
The trick to coding layouts is to plan beforehand.
I’ll identify the parent and child elements first based on the layout method. Below are my workings based on the design.
Determine number of rows
I’ll sort the elements on the page into groups horizontally. Elements are represented as boxes, and those along the same (imaginary) line are considered to be in the same row e.g.
article. Were they to start or end on a different line, I would consider them to be on different rows.
Do note that the three elements and its container within
article are ignored here as they are not part of the grid.
Determine the number of rows
I’ll sort the elements into groups vertically. Elements along the same (imaginary) line will be considered in the same column.
Create a guide
After determining the number of columns and rows, I now have a guide that I can follow when coding. In it, I’ll also mark out the grid lines and note down the parent and child elements.
Step 2 — Create the HTML file
For a simple layout, I’ll type out all the html before I work on the CSS.
Step 3 — Create CSS file
After which, I’ll create the CSS file and link it to my html file.
I remove the default margin and padding of
body elements, and add a height of 100%.
Create the grid
CSS Grid can be intimidating at first as there are a number of ways to create a grid. Hence, it is less confusing to keep to one particular syntax when learning.
display: grid on the
div with the class of grid-wrapper. This transforms the
div to a grid-container. Its direct children are now grid-items. Elements that are within its direct children will remain unaffected.
Next, I specify the width of grid rows and the height of grid columns.
- Rows: Since
footercontains only the content, and I want
articleto expand to cover the remainder of the page while pushing
footerto the end of the page, I add
grid-template-rows: min-content auto min-content.
- Columns: As I want
asideto take up 1/4 of the page width and
articleto take up the remainder, I use
grid-template-columns: 1fr 3fr. The
frunit represents a fraction of the available space in the grid container. As for
footer, I don’t have to think about them since they spread across the two columns, taking up a width of
Slot elements into grid cells
I specify each grid-item’s size and location position using the shorthand
Header and footer will cover the area of 2 columns. The longhand of
grid-column: 1/3 is:
It just means that it starts on the first vertical line, and ends on the third vertical line.
Likewise, aside’s declaration of
grid-row: 2/3 means that it starts on the second horizontal line, and ends on the third horizontal line.
Below is the end result from using CSS Grid:
Creating flex-container and flex-child
Next, I work on spacing out the image elements, which are shown as gray boxes.
div with the class of flex-wrapper is wrapped around my images. To transform it into a flex-container, I add
display: flex. There is no need to change the direction of the flex-items as they will be laid out from left to right by default.
To improve on the responsiveness of the page, I want my flex-items’ width to adjust according to the page width. This can be achieved by setting
flex-grow: 1 on all three images.
Lastly, I work on the mobile view.
In mobile, we tend to lay things out downwards rather than sideways as the screen size is limited. To achieve this, I can do this in a step:
Add a media query to apply
display: block on my grid-container when the screen size is small. That’s a pretty neat way right?
The flex-items inside of
article need more work as they are still laid out in a row. To change from row to column, I add
flex-direction: column to the flex-container.
For styling purpose, I also add a
margin-bottom: 20px to each flex-item to create a gap between the images.
With that, I have completed my webpage!
As always, the last step will be to check if there is any alignment issues at different breakpoints by changing the width of the browser.
To recap, the layout properties we’ve used in this article are:
grid-template-rows(note the plural form)
grid-row(note the singular form)
Refer to Resources to learn more.
I edited the CSS in my CodePen after two feedback from two readers. Thank you both!
- at lines 68 to 79 to swop the order of
articleon mobile view.
- at line 18 to change height of 100% to auto. This will prevent the layout from breaking when the content in grid-wrapper overflows.
I also published Part 2 of this article where I modified the template to create an actual site. Have a read if you are interested!