How to design a form

When designing a form, you should have one goal in mind: The user should be able to complete the form quickly and without confusion. This saves the user's time, and it limits the amount of data submitted in a "wrong" (from the developer's view) way.

Inside the <form> element you can use the full power of the HTML markup language, meaning you can use <h1>, <h2>, ..., <h6> to create headlines, <p> and <br> to break the lines, and <b>, <i> and <u>, to mention some examples.

<form>
  <h1>Register user</h1>
  <p>Fill out this form to register your user.</p>
  <h2>Personalia</h2>
  <p>
    <label for="name"><b>Your name:</b></label><br>
    <input type="text" name="name" id="name" autofocus>
  </p>
  <p>
    <label for="email"><b>Your e-mail</b></label><br>
    <input type="email" name="email" id="email">
  </p>
  <h2>About you</h2>
  <p>
    <label for="name"><b>Write about you</b></label><br>
    <textarea name="name" rows="8" cols="80">
    </textarea>
  </p>
</form>

At this point I would recommend reading Nick Babich's Medium post "Designing More Efficient Forms: Structure, Inputs, Labels and Actions". He talks about how to design a form so that user's have an easier time completing it. In the paragraphs below I will further talk about useful attributes you can use to enhance the user experience.

If your form is the main focus on your page, you could use the attribute `autofocus` in the first input element, so that the users can start adding information as soon as they enter the page. E.g. at google.com, the most important feature is the search form. It then makes sense to add the `autofocus`, allowing users to start searching at once. If your form is a non-important part of the page, e.g. it's a contact form on the bottom of an article, you should not use the `autofocus` attribute.

<form>
  <label for="search">Search:
    <input type="text" name="query" id="search" autofocus>
  </label>
</form>

If you have some input elements that the users shouldn't add information to until they have completed some other input elements, you could use the attribute `disabled` on those elements. If you later want to remove the attribute, you need to use JavaScript.

<form>
  <label for="length">Length:
    <input type="number" name="length" id="length">
  </label>
  <label for="width">Width:
    <input type="number" name="width" id="width">
  </label>
  <label for="area">Area:
    <input name="area" disabled></input>
  </label>
</form>

You can give an element a default value using the value attribute. You should use this with caution as users can skip pre-entered values. But it could help the user if you e.g. fill out the location based on geolocation.

<form>
  <label for="city">City:
    <input type="text" name="city" value="Trondheim">
  </label>
</form>

Lastly, if you want to have control over how the user navigate a form using the tab button, you can use the global attribute tabindex. Some users will want to move trough the form more quickly, thus using their tab button. Browsers will navigate trough the form in the order they are listed in the HTML document. If you for some reason don't want this, the tabindex will let you decide the order.

The attribute can take three different values:

A negative value means that the element should focusable, but shouldn't be reachable via sequential keyboard navigation (tab button).

  • 0 means that the element should be focusable and reachable via sequential keyboard navigation, but its relative order is defined by the platform convention.

  • A positive value means that the element should be focusable and reachable via sequential keyboard navigation. Its order is defined by the value of the attribute: the sequential follow the increasing number of the tabindex. If several elements share the same tabindex, the order follows their position in the document.

An element with a 0 value, an invalid value, or no tabindex value should be placed after elements with a positive tabindex.

<form>
  <label for="name">Full name
    <input type="text" name="name" id="name" tabindex="1">
  </label>
  <label for="email">Full name
    <input type="email" name="email" id="email" tabindex="2">
  </label>
</form>

Last updated