HTML & CSS Tutorials

CSS Flexbox Responsive Form Layout With Source Code

Last modified on October 30th, 2022
HTML & CSS

By the end of this tutorial, you’re going to design this cool registration form very quickly using CSS Flexbox with step-by-step instructions from scratch. As you can see, it’s also responsive and will look nice on any screen. Finally, I’ll be using a bit of javascript for the slider functionality.

Set Background Colour Full Screen

As you can see from the final output, the registration form is nicely centered horizontally and vertically on the viewport of the browser.

To do that, create a section element with an id called registration-page inside the body tag.

<body>
    <section id="registration-page">
    </section>
</body>

Now, make the section HTML element to fit the viewport of the browser. There are a few CSS techniques to achieve this. I’m going to use height:100% property in this tutorial.

Recommended
CSS Make A Div Full Screen

As you know, the section is a block-level element that will stretch the width to match its parent width, which is the body element in this case, and its width is 100% by default, so I do not have to be explicit about it inside the #registration-page CSS rule.

To stretch the height of the section HTML element to fit the screen, add height:100% to it as well as inside the html and body CSS rules.

Finally, add the background colour to match the final output.

html, body {
    height:100%; 
}

#registration-page {
    height:100%;
    background:#78a7ba; 
}

As you can see from the above screenshot, the background color of the #registration-page did not fill the whole screen, because the body tag has some default margin which also triggers the scroll bar to appear.

Instead of getting rid of the default margin of the body tag, get rid of all default margins of the HTML elements.

To do this, create a wildcard CSS rule using asterisks (*) and set the margin to 0 like below. This doesn’t only get rid of the default margin of the body tag, but also the scroll bar.

* {
    margin:0;
}

Make The Registration Form Center To The Screen

Now, let’s create a form HTML element with a class name .signup-form inside the #registration-page and add the text “Registration Form” inside so that I know where exactly the position of the form element is in the viewport of the browser.

<body>
    <section id="registration-page">
        <form class="signup-form">
            Registration Form
        </form>
    </section>
</body>

Note: As you can see, I haven’t added any of the form attributes in the starting form tag because this tutorial is purely for the design of the registration form.

Adding just 3 properties of CSS Flexbox to a #registration-page will make its child center horizontally and vertically on the viewport, in this case, the child is the form element.

  • display:flex will covert an HTML element to a flexbox.
  • justify-content: center will make the child element center horizontally on the screen.
  • align-items:center will make the child element center vertically on the screen.
#registration-page {
    height:100%;
    background:#78a7ba; 
    display:flex;
    justify-content: center;
    align-items: center;
    overflow:scroll;
}

Registration Form Responsive Width

Now, I want the form to take the full width of the screen in the small screen as well as give the maximum width so that it will not exceed when the screen is bigger.

.signup-form  {
    flex:1;
    background-color: #EFF0F1;
}  

Setting flex:1 to the .signup-form will stretch the width of the signup-form to fit the screen and that’s what I want for the small screen.

But not for the bigger screen.

For that, set the max-width to 600px.

Also, add the border radius and border to match the final design.

.signup-form  {
    flex:1;
    max-width:600px;
    background-color: #EFF0F1;
    border-radius: 10px;
    border: 1px solid #999;
}

Recommended
Must-Know CSS Flexbox Responsive Multi-Column Layout Explained

Registration Form Header

First, replace the text “Registration Form” with a div with the class name .form-header inside the .signup-form and add an h1 tag with the text “Create Account” inside.

<form class="signup-form">
   <div class="form-header">
      <h1>Create Account</h1>
    </div>
</form>

First, add padding to the top and bottom of the form-header as well as to the border at the bottom.

.form-header {
    padding:15px 0;
    border-bottom:1px solid #cccccc;
}

Then, change the font size, text align and color of the h1 element.

.form-header h1 {
    font-size: 28px;
    text-align:center;
    color:#666;
}

Add Custom Font To The Form

  1. The first step is to import the desired font at the top of the style.css file, in this case, Roboto.
@import url('https://fonts.googleapis.com/css?family=Roboto');

Note: Feel free to choose your favourite font from the Google Font Collection.

2. The second step is to set the font-family property inside the wildcard CSS rule (*) so that the font will be applied to all the text in the registration form

* {
    margin:0;
    font-family: "Roboto", sans-serif;
}

Recommended
CSS Make Background Image Full Screen

Registration Form Body (Name)

As you can see from the final output, the form body has a two-column layout and is responsive as it becomes a one-column layout when on the small screen.

The good news is making a two-column layout is so easy with CSS flexbox.

After the form-header end tag, define div with a class name form-body which is where all of the input elements would go in.

 <div class="form-body">
 </div>

To create a two-column layout, define a div with a class name .row.

<div class="form-body">
  <div class="row"></div>
</div>

In there, declare two div elements with the class name .input-group. one for the first name and another one for the last name.

 <div class="form-body">
   <div class="row">
     <div class="input-group"></div> // First name
     <div class="input-group"></div> // Last name
   </div>
 </div>

Finally, add the label and input field inside each input-group.

 <div class="form-body">
   <div class="row">
     <div class="input-group">
       <label>First name </label>
       <input type="text" placholder="Enter your first name">
     </div>
     <div class="input-group">
       <label>Last name</label>
       <input type="text" placholder="Enter your last name">
     </div>
   </div>
 </div>

Now that I have the basic skeleton of the two-column layout, let’s convert the .row element to flexbox so that I can arrange its children (.input-group) side by side.

.row {
    display:flex;
    flex-direction:row;
}

I do not have to specify the flex-direction:row because of its default behaviour of the flexbox.

That’s why as soon as I specified display: flex to the .row, the .input-group elements aligned next to each other automatically.

To give equal width to both of the .input-group, add flex:1; to it.

Also, add the border so that you can see the actual size of each .input-group.

.input-group {
    flex:1;  
    border: 1px solid red;
}

Now, let’s move the input field below the label and stretch its parent width.

To do that, covert the .input-group element to a flexbox.

Then, mention flex-direction:column explicitly inside the .input-group CSS rule. This is so that its children will be stacked full width which are the label and input field.

.input-group {
    flex:1;  
    display:flex;
    flex-direction:column; 
}

Finally, add the margin to all sides of the .input-group so that they do not touch each other.

.input-group {
    flex:1;  
    display:flex;
    flex-direction:column; 
    margin: 10px 5px;
}

Now, let’s style the label and input field to match the final output.

label {
    color:#1BBA93;
    font-size: 17px;
    font-weight: 500;
}

input[type="text"] {
  font-size: 18px;
  height: 34px;
  padding-left: 10px;
  padding-right: 10px;
  color: #666;
  border: 1px solid #d6d6d6;
  border-radius: 4px;
  background: white;
  outline: none;
}

For the input field, I could use the class names but I just used attribute to show you how that’s done.

Finally, change the background of the .form-body as well as give some more padding.

.form-body {
    background:white;
    padding:5px 10px;
}

Now, let’s make the form responsive by converting two columns into a single column when the screen size is less than 500px using CSS breakpoints.

Add flex-direction:column to the .row and that’s it.

@media only screen and (max-width: 500px) {
    .row{
      flex-direction:column; 
    }
}

Recommeded
How To Create A Header / Banner in HTML & CSS

Registration Form – Email Field

The Email row has only one column, so all we have to do is create a div element with .row like before. Instead of creating two .input-group elements, just create one.

And the rest will work like a magic!

After the ending .row div for the name field, add the HTML code for the email field.

<div class="row">
  <div class="input-group">
    <label>Email </label>
    <input type="email" placholder="Enter your email address">
  </div>
</div>

Finally, add the input[type=”email”] to the existing CSS rule like so.

input[type="text"],
input[type="email"] {
  ...
}

Registration Form – Password Fields

Password fields are a two-column layout very similar to the name fields.

After the email field, add the HTML code for the password.

 <div class="row">
   <div class="input-group">
     <label>Password </label>
     <input type="password" placholder="Enter your your password">
   </div>
   <div class="input-group">
     <label>Confirm Password</label>
     <input type="password" placholder="Enter your password again">
   </div>
 </div>

Then add the input[type=”password”] to the existing CSS rule for input field.

input[type="text"],
input[type="email"],
input[type="password"] {
  ...
}

Gender & Hobbies – Radio Buttons & Checkboxes

Let’s create another two-column layout right after the passwords. On the left add three radio buttons with corresponding labels for gender and add the four checkboxes with labels for hobbies.

Radio buttons are great when a user can choose only one option among others such as gender. On the other hand, checkboxes are great for selecting multiple items such as hobbies.

<div class="row">
   <div class="input-group">
     <label>Gender </label>
  </div>
   <div class="input-group">
     <label>Hobbies</label>
   </div>
</div>

Rather than adding radio buttons right after the gender label, define div with the class name .radio-group. Then create another div and add the radio button and its label inside for male as well as female and other.

This way I can easily arrange them side by side using CSS flexbox.

<div class="row">
  <div class="input-group">
    <label for="">Gender</label>

    <div class="radio-group">

      <div>
        <label for="male">
          <input type="radio" name="gender" id="male">
          Male
        </label>
      </div>

      <div>
        <label for="female">
          <input type="radio" name="gender" id="female">
          Female
        </label>
      </div>

      <div>
        <label for="other">
          <input type="radio" name="gender" id="other"> Other
        </label>
      </div>

    </div> <!-- .radio-group -->
  </div> <!-- .input-group -->

  <div class="input-group">
    <label for="">Hobbies</label>
  </div>
  
</div>

When the form content exceeds the height of the viewport on the mobile view, the form cuts off on the top.

To fix that, set the margin-top and bottom of the signup form to auto.

.signup-form {
  flex: 1;
  max-width: 600px;
  border-radius: 10px;
  background-color: #EFF0F1;
  border: 1px solid #999;
  margin-top: auto;
  margin-bottom: auto;
}

Now, I can scroll the form up and down to view the entire content.

Okay.

Now, let’s position all three radio buttons beside each other.

Add display:flex to the .radio-group CSS rule.

.radio-group {
    display:flex;
}

Then add flex:1; to the div elements inside .radio-group to give equal width to them.

.radio-group div {
   flex:1;
}
CSS flexbox responsive registration form - radio buttons

Now change the color of the labels to dark grey.

.radio-group label {
    color:#666;
    cursor:pointer;
}

Next, hobbies…

 <div class="input-group">
   <label for="">Hobbies</label>
   <div class="checkbox-group">
     <div>
       <label for="music">
         <input type="checkbox" name="hobbies" id="music">
         Music
       </label>
     </div>

     <div>
       <label for="cooking">
         <input type="checkbox" name="cooking" id="cooking">
         Cook
       </label>
     </div>

     <div>
       <label for="travel">
         <input type="checkbox" name="travel" id="travel">
         Travel
       </label>
     </div>

     <div>
       <label for="movies">
         <input type="checkbox" name="movies" id="movies">
         Movie
       </label>
     </div>

   </div> <!-- .checkbox-group -->
 </div><!-- .input-group -->

Similar to the radio group, create a new CSS rule called .checkbox-group and add display:flex; property in there and also add flex:1; property to its children divs.

Rather than creating a separate CSS rule, use the existing one by adding CSS rule name to it separated by a comma.

.radio-group, .checkbox-group {
  display:flex;
}

.radio-group div, .checkbox-group div {
  flex:1;
}

.radio-group label, .checkbox-group label  {
  color:#666;
  cursor:pointer;
}

Nice!

Registration Form – Select Drop Down / Range Slider

Right after the end of the two-column layout for the gender and hobbies, declare another two-column layout for the source of income and Income.

The Source of income is going to be a select drop-down menu with three options: Employed, Self-Employed, and Unemployed.

On the right, the income will be a range slider with a label on the right.

<div class="row">
  <div class="input-group">
    <label for="">Source of Income</label>
    <select>
      <option>Employed</option>
      <option>Self-Employed</option>
      <option>Unemployed</option>
    </select>
  </div>
  <div class="input-group">
    <label>Income</label>
    <div class="range-group">
      <input type="range">
      <label>14</label>
    </div>
  </div>
</div>

To style the select drop-down menu to match the rest of the form, add select to the existing input CSS rule.

input[type="text"],
input[type="email"] ,
input[type="password"],
select  {
  font-size: 18px;
  height: 34px;
  padding-left: 10px;
  padding-right: 10px;
  color: #666;
  border: 1px solid #d6d6d6;
  border-radius: 4px;
  background: white;
  outline: none;
}
CSS flexbox responsive registration form - select drop down range slider

At this stage, the ranger slider is not stretched and the label is not positioned on the right like in the final output.

To achieve that, make the range input width flexible and the range input label fixed width.

Thanks to CSS Flexbox again, all you have to do is to add display:flex; to the .range-group then add flex:1; to the range input which will stretch the slider to the right.

range-group {
  display: flex;
}

.range-group input {
  flex: 1;
}
CSS flexbox responsive registration form - select drop down range slider

Style the input range label to match the final design.

  .range-group label {
    margin-left: 10px;
    background-color: #1BBA93;
    color: white;
    border-radius: 5px;
    padding: 5px;
    font-size: 17px;
    text-align: center;
  }
CSS flexbox responsive registration form - input range slider label design

Registration Form – Update Range Slider Label

Unlike other input controls, the range slider does not show the label when it moves. You need to add a snippet code of JavaScript in order to get the functionality working.

First, attach an onChange event to the range input element with a callback function called changeSliderValue().

Pass this.value as an argument to the function which will set the value between 0 and 100 based on the slider position which is the default numeric range.

<input type="range" onChange="changeSliderValue(this)">

Then declare the changeSliderValue() function inside the script tags just before the ending </body> tag and pass the value as a parameter. Then console.log the value.

...
   <script>
        const changeSliderValue = (value) => {
            console.log(value)
        }
    </script>

 </body>

</html>

For the income, change the default numeric range from 1-100 to 20-200 so that the user can choose their yearly income between 20 K and 200 K. We can easily add a few HTML attributes to the input range element to achieve that.

<input type="range" onChange="changeSliderValue(this.value)" min="20" max="200" step="5" value="20>

Add the value of min and max attributes to 20 and 200 respectively. The step attribute will make sure the slider value will change by 5 rather than the default 1.

Finally, update the label with the slider value.

<script>
  const changeSliderValue = (value) => {
    document.getElementById("rangeSliderLabel").innerText = value + " K";
  }
</script>

Registration Form – Upload File & Number Only

As you can see from the final output, there is an upload profile picture option on the left and an age input field on the right.

As usual, create a two-column layout with .row class and two .input-group inside. Luckily one of the input types is a file for opening a folder and selecting the file from.

Age can only be an integer, so an input type number would be appropriate for that.

Add the following HTML code right after the ending </div> of the income .row two coloumn layout.

<div class="row">
  <div class="input-group">
    <label>Upload Profile Picture</label>
    <input type="file">
  </div>
  <div class="input-group">
    <label>Age</label>
    <input type="number">
  </div>
</div>

Then, add these two input types to an existing input CSS rule.

Also, add the width:100% so that the width of the input type file will match with the rest of the design.

input[type="text"],
input[type="email"],
input[type="password"],
input[type="file"],
input[type="number"],
select {
  width: 100%;
  font-size: 18px;
  height: 34px;
  padding-left: 10px;
  padding-right: 10px;
  color: #666;
  border: 1px solid #d6d6d6;
  border-radius: 4px;
  background: white;
  outline: none;
}

Registration Form – Textarea Input

Use <textarea> input element for bio which will be a single column layout.

<div class="row">
  <div class="input-group">
    <label for="">Bio</label>
    <textarea> </textarea>
  </div>
</div>

To match the style with other input fields, just add the text area to the existing input CSS rule.

input[type="text"],
input[type="file"],
input[type="email"] ,
input[type="number"] ,
select, 
textarea {
  ...
}

At this stage, increase the height of the textarea to 100 px and disable the resize feature that comes with the textarea element by default.

textarea {
  resize: none;
  height:100px;
}

Registration Form Footer

Add the footer HTML code, right after the ending .form-body div tag.

<div class="form-footer">
  <button class="btn">Create</button>
</div>

By default, the button will align to the left. To move it to the right, add display: flex; and justify-content: flex-end; properties to the .form-footer.

.form-footer {
    display:flex;
    justify-content: flex-end;
}

Style the button to match the final design.

.btn {
    padding:10px 20px;
    background-color: #1BBA93;
    font-size:17px;
    border:none;
    border-radius:5px;
    color:#bcf5e7;
    cursor:pointer;
}

Finally, stretch the button to full width on the mobile view by adding flex:1; to the .btn selector.

/* MOBILE VIEW */
@media only screen and (max-width: 500px) {
    .row{
      flex-direction:column; 
    }

    .btn {
        flex:1;
    }
}

Have a question? Feel free to comment below and I’ll get back to you as soon as I can.

Download Full Source Code