1. Web Design
  2. UX/UI
  3. Forms

How to Build a Responsive Form With Flexbox

Scroll to top

In this tutorial, we’ll learn how to take advantage of flexbox to create a responsive form. What’s interesting (and exciting at the same time) is that flexbox allows us to build our form without using any media queries.

Before we start, let’s look at what we’ll be working towards (checkout the larger version to see how the form layout changes):

Form Structure

Right then, first things first, let’s dig into the form’s structure. We’ll mark it up as follows:

  • We’ll use the .flex-outer unordered list to group the various form elements
  • and the .flex-inner unordered list to group the checkboxes. 
  • Almost all form controls come with their associated label.

That’s it! By defining just two unordered lists (we could have used ordered lists as well), we’ve built a very clean form. Here’s what it looks like:

1
<form>
2
  <ul class="flex-outer">
3
    <li>
4
      <label for="first-name">First Name</label>
5
      <input type="text" id="first-name" placeholder="Enter your first name here">
6
    </li>
7
    <li>
8
      <label for="last-name">Last Name</label>
9
      <input type="text" id="last-name" placeholder="Enter your last name here">
10
    </li>
11
    <li>
12
      <label for="email">Email</label>
13
      <input type="email" id="email" placeholder="Enter your email here">
14
    </li>
15
    <li>
16
      <label for="phone">Phone</label>
17
      <input type="tel" id="phone" placeholder="Enter your phone here">
18
    </li>
19
    <li>
20
      <label for="message">Message</label>
21
      <textarea rows="6" id="message" placeholder="Enter your message here"></textarea>
22
    </li>
23
    <li>
24
      <p>Age</p>
25
      <ul class="flex-inner">
26
        <!-- list items here -->
27
      </ul>
28
    </li>
29
    <li>
30
      <button type="submit">Submit</button>
31
    </li>
32
  </ul>
33
</form>

Note: we use the p element instead of the label element before the .flex-inner list. This is because, in this particular case, it doesn’t make any sense to use the label tag. This tag should be used only to associate a text label with a form control.

Here’s the markup for the checkboxes:

1
<ul class="flex-inner">
2
  <li>
3
    <input type="checkbox" id="twenty-to-twentynine">
4
    <label for="twenty-to-twentynine">20-29</label>
5
  </li>
6
  <li>
7
    <input type="checkbox" id="thirty-to-thirtynine">
8
    <label for="thirty-to-thirtynine">30-39</label>
9
  </li>
10
  <!-- more list items here -->
11
</ul>

With the markup ready, the unstyled form looks like this:

This won’t be the fanciest form you have ever seen, but it works! It’s semantic, accessible, and fluid; aspects which are arguably more important than anything.

At this point, we’re ready to start applying some styles to it.

Form Styles

Let’s begin by adding normalize and autoprefixer to our pen settings:

Next we’ll identify the flex containers. In our case, the following elements:

  • Each of the list items of the .flex-outer list. 
  • The .flex-inner list which contains all the checkboxes.

Additionally, we want to vertically center the flex items across the cross-axis.

To achieve this behavior, we set up some initial CSS rules:

1
.flex-outer li,
2
.flex-inner {
3
  display: flex;
4
  flex-wrap: wrap;
5
  align-items: center;
6
}

The next step is to specify the widths for the flex items. We begin with the flex items of the .flex-outer list.

The main requirements:

  • The width of the labels should be at least 120px and at most 220px. 
  • The width of the form elements that come after the labels should be at least 220px.

What does this give us? Each label along with its associated form element will be displayed on a single horizontal row when the width of the form totals at least 340px. In any other case, all form elements (apart from the checkboxes as we’ll see in a moment) will stack vertically.

Note: the aforementioned values are arbitrary–you can modify them according to your needs.

1
.flex-outer > li > label,
2
.flex-outer li p {
3
  flex: 1 0 120px;
4
  max-width: 220px;
5
}
6
7
.flex-outer > li > label + *,
8
.flex-inner {
9
  flex: 1 0 220px;
10
}

Submit Button

Lastly, for the submit button, which is also a flex item, we define a few basic styles:

1
.flex-outer li button {
2
  margin-left: auto;
3
  padding: 8px 16px;
4
  border: none;
5
  background: #333;
6
  color: #f2f2f2;
7
  text-transform: uppercase;
8
  letter-spacing: .09em;
9
  border-radius: 2px;
10
}

Checkboxes

Let’s now style the checkboxes. Remember that their flex wrapper has a minimum width of 220px.

First, we set the width of the flex items which are immediate parents of the checkboxes to 100px:

1
.flex-inner li {
2
  width: 100px;
3
}

Then, we take advantage of the justify-content property to align them across the main-axis. Note that this property has different values, but for this example, we’re only interested in the space-between value:

1
.flex-inner {
2
  justify-content: space-between;
3
}

This value works well and allows us to achieve a consistent alignment for the checkboxes and their respective labels. One thing we should mention is that this property value may distribute the elements of the final row awkwardly. At certain viewport widths you’ll see something like this:

Notice the alignment of the last two flex items. If, for some reason, you don’t like that layout and you prefer them to appear next to each other, you can try something like this: 

  • Remove the justify-content property from the flex wrapper.
  • Use percentages to add a fixed width to the flex items (e.g. width: 50%).
  • Use media queries to override this width. For instance, when the viewport width is greater than 992px, give flex items width: 25% instead of width: 50%.

Most of all, it’s important to understand two things:

  • Flexbox gives us great flexibility for quickly building beautiful forms
  • and all the aforementioned values work well for this specific example. For your own designs, you’ll probably need different values. For example, here the labels of the checkboxes are pretty small and for this reason we give their parent a fixed width (i.e. 100px). However, if they have different widths, it might be smarter to give them flex: 1 100px

Final Styles

Before we leave, let’s add some more aesthetics to make things more presentable. Pick apart the CSS tab in the demo below to see where colors and spacing have been added:

Conclusion

As you can see, with minimal markup and the power of flexbox, we managed to build a responsive form. Hopefully now, you’ve gained some useful knowledge that will help you build your own flexbox forms. 

Next Steps

If you want to take this form a step further, I have two challenges for you:

  • Improve its appearance by overriding the default styles (e.g. add custom checkboxes)
  • and make it dynamic. For instance, if you’re familiar with WordPress, see if it’s possible to create a Contact Form 7 or a Ninja Form which preserves the structure and styles of this form.
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.