Coding

How I use CSS Grid and Flexbox to Create a One-page Website

CSS Grid for page layout and Flexbox for UI elements

aliceyt
aliceyt
Oct 29, 2019 · 6 min read

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. aside and 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.

Set-up

I remove the default margin and padding of html and 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.

I declare 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 header and footer contains only the content, and I want aside and article to expand to cover the remainder of the page while pushing footer to the end of the page, I add grid-template-rows: min-content auto min-content.
  • Columns: As I want aside to take up 1/4 of the page width and article to take up the remainder, I use grid-template-columns: 1fr 3fr. The fr unit represents a fraction of the available space in the grid container. As for header and footer, I don’t have to think about them since they spread across the two columns, taking up a width of 4fr.

Slot elements into grid cells

I specify each grid-item’s size and location position using the shorthand grid-column and grid-row properties.

Header and footer will cover the area of 2 columns. The longhand of grid-column: 1/3 is:

grid-column-start: 1;
grid-column-end: 3;

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.

grid-row-start: 2;
grid-row-end: 3;

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.

The 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.

Mobile view

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.

Summary

To recap, the layout properties we’ve used in this article are:

Grid

  • display: grid
  • grid-template-columns and grid-template-rows (note the plural form)
  • grid-column and grid-row (note the singular form)

Flexbox

  • display: flex
  • flex-direction
  • flex-grow

Refer to Resources to learn more.

Afternote:

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 aside and article on 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!

The Startup

Medium's largest active publication, followed by +567K people. Follow to join our community.

aliceyt

Written by

aliceyt

Read to write and 📝 to 📖 || Articles are organised by category on https://github.com/tiffam/medium_articles

The Startup

Medium's largest active publication, followed by +567K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade