1. Web Design
  2. HTML/CSS
  3. CSS

How to Build Web Form Layouts With CSS Grid

Scroll to top

In this tutorial we will explore how to build a couple of different web forms using CSS Grid. For each example we will first use floats, and then see how the same layout could be done using CSS Grid.

If you don’t have any previous knowledge of CSS grid, take a look at our beginner’s series Understanding the CSS Grid Layout Module. Let’s begin!

1. Basic Sign up Form

In this layout we’re going to divide the form into two columns so we can display the labels on the left, and the input fields on the right. 

With “Traditional” CSS

A traditional approach to this layout might use floats to give us our columns. Notice that we don’t have a wrapper for the form element; we will directly style the labels and inputs.

1
<form>
2
    <label for="firstName" class="first-name">First Name</label>
3
    <input id="firstName" type="text">
4
5
    <label for="lastName" class="last-name">Last Name</label>
6
    <input id="lastName" type="text">
7
8
    <!-- more inputs -->
9
</form>
1
form {
2
    overflow: hidden;
3
}
4
5
label {
6
    float: left;
7
    width: 200px;
8
    padding-right: 24px;
9
}
10
11
input {
12
    float: left;
13
    width: calc(100% - 200px);
14
}
15
16
button {
17
    float: right;
18
    width: calc(100% - 200px);
19
}

You’ll notice we’re using calc() here, which allows us to make our left column fixed at 200px wide, whilst the right column remains fluid.

Here is the result, with some additional styles for aesthetics:

With CSS Grid Layout

Our goal when using “Grid” is to define two columns, and then place each element in its required column.

The first step is to define our grid on the parent element form:

1
form {
2
    display: grid;
3
}

Then, we need to divide that grid using grid-template-columns:

1
form {
2
    display: grid;
3
    grid-template-columns: 200px 1fr;
4
}

Based on the above CSS, the first column will have a fixed width of 200px whilst the second will take 1fr (“one fraction”) of the remaining available space.

We now need to define the placement for our labels and inputs. To do that, we will use grid-column with specific values for the grid lines:

For more on how grid lines work, take a look at this quick tip:

Based on these grid lines, we will apply the following rules for our labels, inputs and the button:

1
label {
2
    grid-column: 1 / 2;
3
}
4
5
input,
6
button {
7
    grid-column: 2 / 3;
8
}

The labels will find themselves in the column which begins on line 1 and ends on line 2. The inputs and button will be placed in the column which begins on line 2 and ends on line 3.

Finally, we use grid-gap to add a gutter of 16px between the rows and columns :

1
form {
2
    display: grid;
3
    grid-template-columns: 200px 1fr;
4
    grid-gap: 16px;
5
}

2. Contact Form

In this layout, we want to achieve the following:

  1. Column heights should be equal, so the sidebar and the form wrapper are the same height.
  2. We want to further divide the form (the right hand side) into two columns, altering the button so it fills the full width.

It’s perfectly possible to build this layout using floats. However, we will need to set a min-height for the left column, otherwise it won’t assume the full height. There are other “traditional” approaches to this issue, but none are particularly pretty.

With “Traditional” CSS

To sum up, with floats we need to:

  1. Add min-height to the left column.
  2. Float the contact and form wrappers.
  3. Add a clearfix or overflow: hidden; to preserve the wrapper height.
  4. Float the form elements and add margins between them.
  5. Reset floating for the textarea and send button, and then make them fill the full width.

That’s quite a bit of work, right?

A better approach would be to solve this with either Flexbox or Grid. In this particular case, I would prefer to use Grid since we’re arranging elements both horizontally and vertically.

With CSS Grid Layout

Let’s begin by declaring a grid on our wrapper and dividing it into two columns.

1
.wrapper {
2
    display: grid;
3
    grid-template-columns: 1fr 2fr;
4
}

Our form element also needs to be declared a grid:

1
form {
2
    display: grid;
3
    grid-template-columns: 1fr 1fr;
4
    grid-gap: 20px;
5
}

After applying the above rules, we will get the following:

We need to let the last two elements to fill the full width by stretching them from grid line 1 to grid line 3.

1
.full-width {
2
    grid-column: 1 / 3;   
3
}

3. Profile Form

Time for our last form layout. In this example we have included an input for users to upload their profile photo. It should be placed at the top right.

With “Traditional” CSS

We’ll build this with the following markup:

1
<form action="">
2
    <p>
3
        <label for="">Your name</label>
4
        <input type="text">
5
    </p>
6
    <p>
7
        <label for="">Email</label>
8
        <input type="email">
9
    </p>
10
    <p class="input-file-wrapper">
11
        <label for="upload">Upload your photo</label>
12
        <input type="file" name="" id="upload">
13
    </p>
14
    <p>
15
        <button>Save</button>
16
    </p>
17
</form>

Briefly covering a traditional approach, we can achieve our layout with these steps:

  1. Add position: relative; to the form element.
  2. Absolutely position the file input to the top right. 
  3. Add padding to the form with the same width as the file input.
  4. Specify a fixed width for the file input.

With CSS Grid Layout

Let’s not dwell on the traditional approach too much. With Grid, we will divide the form into two columns as follows:

The first column will take twice the horizontal space of the second column, which we’ll achieve using fr units:

1
form {
2
  display: grid;
3
  grid-template-columns: 2fr 1fr;
4
  grid-gap: 20px;
5
}

Having established the grid, we need to place the form elements between grid line 1 and grid line 2:

1
form p {
2
  grid-column: 1 / 2;
3
}

The next step is to place the input file in the second column. In order to do that, we will place it between grid line 2 and grid line 3. Moving vertically, we’ll make it span rows from grid line 1 to grid line 2.

1
.input-file-wrapper {
2
  grid-column: 2 / 3;
3
  grid-row: 1 / 2;
4
}

Conclusion

Well done! We’ve covered several different examples for using CSS Grid when building web forms. As you’ll have noticed, we saved a lot of time and effort by writing a few lines of code, as opposed to using traditional layout techniques. You can use all of the above examples starting today, thanks to CSS @supports which help us in using a specific feature as an enhancement. 

Do you have any suggestions for improving these layouts? Let me know in the comments below!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.