Mono has closed its doors. Read more in our blogpost.

Go to main content

The 10 Commandments of Good Form Design on the Web

1. Thou shalt provide clear, always visible labels for each field

There is a trend in web design to show form labels only when a field is focussed. This can be cool on a simple form like a username/password form, but for anything longer it is probably a bad idea.

When you have the space to show labels, do so.

Especially in a long form a user will review the input he or she entered; when you can’t read which field corresponds to which label there is no way to do a good review.

Image sequence illustrating the point

2. Thou shalt use a big enough font size

Your fonts have to be big enough to be legible. I recommend at least 14 pixels for body copy. 16 pixels is safe for most fonts. The sizing depends a bit on the context (mobile or not?) and how many other things are on the page. When in doubt, make things bigger.

As an added benefit, if you specify a font size of 16 pixels for input sizes, iOS will not zoom in anymore when you tap a field, simply because it is not needed.

Image sequence illustrating the point

3. Thou shalt provide easily tappable areas

It is likely these days that that someone is using your form on a touch device. Apple has always recommended a minimum 44px by 44px space for buttons as this corresponds roughly to a finger size. This is a good recommendation, although I find that if you are strict about this 44px size you will end up with a screen that is full of fields that feel too huge in a typical web application. I recommend sizing input fields between 32px and 40px in height.

The default input field in Bootstrap 3 is 32px in height, this is a good base size. Fields shouldn’t be smaller than that to be easily tappable.

Image sequence illustrating the point

4. Thou shalt size the input fields according to their expected input

A form that sizes the input fields according to their expected input is easier to read.

For example, when you are expecting a zip code, don’t put a 100% width input on the screen. Think about the minimum amount of characters a zip code has (in Belgium 4 and in Holland possibly 6), then size the input accordingly. The widest possible value is MM0000 so this should fit in your field, using your design’s font as well as the fallback font.

Keep in mind that on Linux the default sans-serif fonts are typically wide so it makes sense to test your designs with a wide font like Verdana, even though you specifically chose a compressed font for your design. On the web you never really know what the user will see in the end.

Image sequence illustrating the point

5. Thou shalt not customize checkboxes and radio buttons

All too often I spot a pretty radio button or checkbox that is broken in terms of interaction design. Historically radio buttons or checkboxes are customized using a Javascript library. These days it is possible to do it purely using SVG or CSS.

However, customising the look of the fields often leads to confusing keyboard navigation. 90% of forms I test with customised checkboxes or radio buttons don’t have focus styles and are hard to navigate by keyboard.

I love a nice looking form and a cool SVG animation as much as anyone, but you are actually doing your users a disservice by customising form elements without any added value.

What I mean by without added value is customising checkboxes and radio buttons purely for cosmetic reasons.

Widgets like select2 or date pickers can provide added value to a form that the default browser form elements can’t provide.

Image sequence illustrating the point

6. Thou shalt provide both a general error message and a field specific one

It is a good idea to provide both a general error message, and a field specific one. When a form gets submitted, the user will end up on the same page, but you don’t know if the error is in the viewport.

Put both an error on top of the form (and make sure it is in the viewport on both desktop and mobile) as well as field specific explanations about what is wrong with the inputted data.

Image sequence illustrating the point

7. Thou shalt make it clear what is optional and what is not

This one seems obvious, but all too often it is not clear which fields optional and which are not.

Using an asterisk * character next to the label is one of the clearest methods. I have been wrapping this * in an HTML element that says “Required field” so screen readers might read this content.

It also helps to group the required fields and the optional fields together if it makes sense in the context of the form.

Image sequence illustrating the point

8. Thou shalt hide what is not needed until it is needed

Often there are parts of the form that are dependant on other parts of the form. For example, on an e-commerce site your invoice address might be the same as your delivery address.

In this case it would be wise to hide all the delivery address fields unless the user specifies that the addresses should be different.

Don’t put too many form fields on one page. Try to group things logically and if necessary make it form with multiple steps. Clearly indicate how far the user is to complete the form.

Image sequence illustrating the point

9. Thou shalt minimize user input

Don’t ask for things that are not necessary. Entering data into forms is a chore and not a fun activity (for most people, that is).

Don’t ask for data that you don’t need and provide a clear explanation what the data is going to be used for in a visible disclaimer link on the page.

Image sequence illustrating the point

10. Thou shalt be clear what type of input is expected

Data comes in many formats. A phone number can be written with a +, a country code, an area code, or without any of these. What input do you expect?

The best course of action is to be liberal in what users can input and then transform the data to a common format. If the user typed Belgium as their country and they entered a phone number like 0495 20 12 12 you can assume it’s a cell phone number and store it as such.

However, it is not always realistic to be liberal in your input. The 2nd best method is to just provide an explanation below the field that specifies which input is expected e.g. “Enter your telephone number in the following format: +XX 000 000 000 where XX stands for your country code.”

Image sequence illustrating the point

Bonus: Thou shalt only validate a field when a user is done with it

A lot of forms these days validate whenever you leave the field. This is related to the way things work in modern Javascript MVM frameworks.

To validate forms before hitting that final submit button is not a bad idea, but give the user some time to correct their mistakes. All too often an error is thrown in my face while I am fully aware that I still need to fix the input in the field. Even worse is that sometimes a field validates while I am typing in it. Obviously “johan@” is not a valid e-mail address but why throw an error when I’m busy actually typing the correct e-mail address?

Delaying the validation until the user is entering data in the next field is a sensible thing to do.

Johan Ronsse

About the author

Johan Ronsse is an interface designer who is trying to find the balance between aesthetics and usability. He tweets as @wolfr_2.

Subscribe to our newsletter

Receive blog highlights and fresh insights into UX/UI and front-end development.

46 thoughts on “The 10 Commandments of Good Form Design on the Web”

  • No avatar

    22 May 2015 at 19:04

    Brilliant. I wish these were in stone somewhere.

  • No avatar

    22 May 2015 at 19:31

    Hi Johan!

    Great points about not wasting peoples time filing out info and/or getting them there; which is VERY important! I do have a question…. I notice that when I fill out all the forms info and hit “submit” and it comes back telling me I missed something (” please fill out your Phone number” or what ever), some forms keep all my data so I don’t have to re-enter everything and some don’t. How do I ensure or can I ensure that once the info is added to the form and I have to ask someone to enter something they missed, not to have to stat over – 95% guarantee we’ll never see then again! Do you recommend a service for this? Thanks

  • No avatar

    22 May 2015 at 19:41

    Great info! I needed exactly this information.

  • No avatar

    22 May 2015 at 20:05

    Great list, indeed.

    The only one I disagree with is your BONUS point. The original 10 are fine, but personally I like when it validates as you type. I am smart enough to know that johan@ is not done, and it’s not yelling at me with an error, but just letting me know it also knows it’s not validated yet. But on the flip side I believe it needs a green checkmark when it’s valid.

    If it’s only errors, maybe this is a problem, but if every field you fill out correctly it gives you a checkmark there is a sense of satisfaction & relief that you know you did everything correct & the form is guaranteed to work when you hit submit.

  • No avatar

    22 May 2015 at 20:44

    Great article! I was especially relieved by your blessing of violating the 44px minimum tappable area.

    I do agree with Andy’s comments about your Bonus point. If a form waited until I had already moved on to tell me I made a mistake, I would think “well, why didn’t you tell me when I was actually on that field??”

  • No avatar

    22 May 2015 at 21:25

    The maximum zip code length you stated is too short for many UK postcodes.

  • No avatar

    23 May 2015 at 07:19

    Dan, the easiest way it so submit the form asynchronously so there is no actual page refresh, thus retaining the information.

    Aside from that you could store the info in a cookie or localstorage so when users come back it’s still there e.g. when a browser crashes. This is recommended for any form where a user enters a lot of data in a single place e.g. the submission form of stack overflow.

    We used to have this on our old contact form – if you would navigate away from the tab and come back your message would still be there.

    Andy, I think I was not clear enough because other people have commented on this point as well saying they like inline validation.

    What I mean is that the validation should only happen after a Javascript blur (defocus) event on the field. I also like those forms where your input is validated field by field and you end up with a form full of green checkmarks. Then you indeed know you are doing well. I guess this could be summed up in another point about form design, to give the user good feedback.

    Drew, I don’t want to be the guy responsible for bad tappability, so take that comment with a grain of salt. I just find 44px high form fields to be a bit too big in relation to most other UI elements and in my opinion for a web app has to work on an iPad 32 px can work just fine.

    I have a feeling iOS has some kind of logic around the tapping so if you tap somewhat close to a field it still selected. What also helps is to attach (CSS block level) labels with the for=”” element so there is extra tappability.

  • No avatar

    25 May 2015 at 05:34

    Hi Johan,

    This is a great article! :) I agree with you that a form should have a validation function. That way, users who filled in the form can review all the details they have entered before finally confirming the submit button. Actually, contact form is sometimes neglected as part of the website design by some people because there’s already a plugin built-in on most website themes. So they only let name, email, message as default. Needless, did they know that tweaking contact form through the techniques you mentioned can have an impact to their business. Like the following:
    (1) It can avoid spammy emails.
    (2) You can get to know the person sending emails and add them on your listings.
    (3) You can directly pinpoint what they need and provide them easily with solutions. (talk about good customer service)
    (4) It can boost sales too (at some point i guess).

    Though, they have to be very specific with the contents of their form. Since some long forms with filler contents will provide negative impacts too right?

  • No avatar

    25 May 2015 at 14:34

    Nice Article :)

    I do find though that 5 and 3 can somewhat conflict each other. To make check and radio boxes more accessible I use icheck Also, I don’t think there is anything wrong with validating a form as you go from box-to-box, but not as you type.

    One irony is that THIS form has Name, Email and Website fields that are 100 characters wide! kind of violates rule 4 don’t you think?

  • No avatar

    25 May 2015 at 14:39

    Very good advice. I especially hate when people confuse placeholders with labels. Labels are way more semantic to denote a form field and they can be read by screen readers. While placeholders must be used to explain further what kind of data it is expecting. Like if you have a date input field, it makes perfect sense to put a placeholder of the expected format of the date it is expecting like dd-mm-yyyy or yyyy-dd-mm.

  • No avatar
    Gabriel Mateus

    25 May 2015 at 14:55

    Great info! Thanks, Johan.
    2015 and web designers still prioritizing what looks fine over what really works for the user.

    I recommend (this huge list) GoodUI for more good tips.

  • No avatar

    25 May 2015 at 15:07

    Nice list but i have to disagree with number 5. Why? Because many browsers (especially on desktop) have ugly and small inputs. Plus every new OS version will probably have different styling, so your users need to adjust to how it is displayed now.

    You can easily style them any way you want, as long as it fits the users expectation and follows design that is appealing to the user. Doing custom styling can be hard to get right, but there are many solutions who do it well. Many tests suggest that going past standard input types is fine as long as its still logical and fits the expectations.

    And lastly it depends on what kind of thing you are trying to make. So no, i don’t think the default implementations suit every situation and are often ugly and inconsistent across platforms.

  • No avatar

    25 May 2015 at 16:54

    Number 11: Thou shalt give textarea’s a max-width
    (not seen below)

    Still, nice list. Keeping it handy for the next form i make. :)

  • No avatar
    James C

    25 May 2015 at 17:42

    Great guide! Two thoughts:

    1) Re: the 44px thing, I agree that often it looks obnoxiously large, so instead I follow the rule of thumb that it should be 44px *including whitespace*. I.e., it can be smaller than 44px, as long as there’s nothing tappable right next to it.

    2) I have to disagree on the last point. Sure it’s mildly annoying to have a validation message seemingly nag you before you’ve finished typing, but wouldn’t it be even more annoying to have it tell you there’s a problem AFTER you’ve moved on to the next field? Forcing the user to go back = less efficient, no?

  • No avatar

    25 May 2015 at 18:53

    Nice list, especially the point about NOT using inline labels.

    Thanks for the good reminder again.

  • No avatar

    25 May 2015 at 21:13

    Nice check list. I definitely agree with the labels being visible always especially when the form is long.

  • No avatar

    26 May 2015 at 13:22

    I have to disagree with your solution to “Thou shalt make it clear what is optional and what is not”. You are doing the opposite of what u wanted to do: You mark mandatory fields with an asterisk. In my opinion when a user is confronted with a form he thinks that he has to fill out all fields. So it is better to mark the fields that are optional. You can do this with the word (optional) behind the label or make another fieldset with optional fields in it (which can be initially hidden like in point 8).

  • No avatar

    26 May 2015 at 13:35

    Great writeup. One issue we have with the Bonus Commandment is when the submit button is disabled until all fields are valid AND the last field of the form must be validated. Typically we validate on tab-out blur(), so the submit button WILL become enabled and receive focus when you tab out of that last required field — everything works fine — but if you don’t tab out after typing a valid email address you MIGHT sit there staring at the form wondering what’s wrong and why the Submit button isn’t enabled.
    It’s because the cursor is still in the last field, which is valid but has not yet triggered the validation.

    Other than validating on keyup, or making sure the last field in the form is not required, I haven’t found a perfect solution. I guess I’ll raise it with UX — they’re the ones insisting the Submit button be disabled.

  • No avatar

    26 May 2015 at 14:39

    One thing to add. Use of Full Name as a field. It might look good and be quicker for a user to complete, but it ruins the data. What if you wanted to use just the person’s first name for marketing purposes? How do you know the first word is their first name? Maybe they’ve entered a salutation? Imagine that first email, ‘Hi Mr’.

    Always split your data as far as possible. You wouldn’t make address one textarea – don’t make a name one textbox.

  • No avatar

    26 May 2015 at 15:56

    Great write-up – thank you!

    For #10, I would argue that the content you have in the placeholder should be outside of the input. If someone needs to refer back to the syntax after they start filling in a field, they will have to clear their input to see the placeholder syntax recommendation.

    There’s also a small typo in the last paragraph of #10
    “Enter your telephone nummer in the following format: +XX 000 000 000 where XX stands for your country code.”
    – should be number ;)

  • No avatar
    Amol Shinde

    26 May 2015 at 16:28

    Very Nice. This is very small things and sometime that small things make big issues.

    Thanks for this information :)

  • No avatar

    26 May 2015 at 16:29

    Great article, Johan – you’ve eloquently covered almost all of my bug-bears as both a regular user and front-end designer.

    Two things:

    1) Minor type in the last Bonus section: “All too often and error” should read “All too often an error”
    2) Fieldsets/Legends. I’m all for keeping forms short and breaking into separate pages where appropriate/necessary but Fieldsets/Legends are really underused in good form design. Aside from being very useful accessibility aids they also help focus the mind on appropriate form element grouping. For single page forms where a Fieldset/Legend may feel like visual overkill they can easily be hidden from visual view whilst still being accessible to screen readers.

  • No avatar

    26 May 2015 at 17:09

    Hi Johan!

    Great article, thank you. I thought you’d find this link helpful for point #7, however:

  • No avatar
    Lars Clausen

    26 May 2015 at 18:37

    Very good points. Extra good on the phone number parsing could be showing what you ended up parsing the number as.

    Two further improvements:

    Help the user when you can, e.g. if you have the zip code, prefill the city name. But don’t force it on the user.

    Use the input type attribute to give a better mobile experience. Just don’t use “number” for zip code, or you’ll have irate British storming your gates.

  • No avatar

    26 May 2015 at 20:05

    Bonus commandment: “Thou shalt place fields in their order of importance.” Make your form efficient. Place required fields first, optional fields after. In a contact form: message (required, of course), then email (likely required), then anything else (usually not) such as name, website, phone, address, browser, pet’s name, favorite food, color of favorite shoes, and other extraneous horse hockey.

  • No avatar

    26 May 2015 at 22:09

    I’d suggest to mark optional fields with ‘(optional)’. When you “do the heavy lifting yourself”, this should be the minority of fields. If a field is optional, ask yourself if it really isn’t redundant.

  • No avatar

    27 May 2015 at 02:54

    Why not change the “Submit” button to be “Validate” and do NO validation as fields are entered? User enters fields, hits button , and THEN client-side code (attached to “Validate” click event) validates each field. This “full-screen” validation has the advantage that fields can be cross-referenced for validation, if required. If a field is found to be in error, an error message is produced and the bad field is highlighted, with the cursor on it.

    No worries about the user having to “back up” to correct a field. And no worries about the user having to re-enter everything for the sake of one field in error.

    If the form validates OK with all fields correct, THEN the “Validate” button becomes “Submit” and the user gets a message saying: “Click ‘Submit’ to send your data.”

    I have tried this approach and it works very well.

    It also obviates the need for the stupid and pointless use of Captcha… The Submit button is only available after the form is validated and it reverts to a validation after the form is submitted. Any robot continually pressing the form button will never hit the server, and only a human interaction can reveal the Submit button.

    Great article, and really good points. Many thanks.

  • No avatar

    27 May 2015 at 03:39

    Thanks for the comments! I am happy that this blog post is receiving so much attention. It has been mentioned by Khoi Vinh, Smashing Magazine and . Yay!

    People have given feedback on the autoplaying GIFs being annoying – sorry for that, it’s our first experiment with this.

    As for (7) marking fields with asterisks, I think it depends a bit on how your form works. If there is only one field that is optional you can add the “(optional)” text to the label. This is good advice.

    However, if for example half of the fields are optional and half of them aren’t, I think it’s cleaner to use asterisks. In this case it is perhaps better – if possible – to group them by optional or not.

    Then again, if you want the optional data for marketing purposes (but don’t want to make it required) grouping by optionality is a bit idea.

    As for the Bonus point, this one has received a lot of feedback. Many people prefer a form that validates inline even as you type. One important point is that it’s technically difficult to predict how fast the user is or when you should validate. My suggestion to wait a bit is perhaps dangerous. So when should you validate? After a field blurs? What about the last field then (as people have noted).

    This is an important question, and it also depends on your form’s design and length. As Blakeyg mentioned fieldsets are vastly underused. If you have 3 sections on the same page, you could validate after each fieldset for instance.

  • No avatar
    Christopher Sanders

    27 May 2015 at 04:52

    I am in agreement with these things to consider when building a form on the web.

  • No avatar

    27 May 2015 at 10:53

    Gread info bro. Thank you :)

  • No avatar

    27 May 2015 at 12:44

    #5 – Thou shalt also know the difference between radio and checkbox input.

    Something I lamented about recently: designers who intentionally mock up checkboxes on forms, even if a user is expected to pick only one option, a.k.a. radios. I’m not very comfortable with the idea that thanks to more capable front-end features & tools the two are now interchangeable, and function is second-fiddle to appearance.

  • No avatar
    Lynn W. Young

    27 May 2015 at 15:19

    Great article! And, I really appreciate you dumb-ing it down for us people who aren’t versed in the technical jargon of web development.

  • No avatar

    28 May 2015 at 04:02

    Just a comment on “9. Thou shalt minimize user input”.

    I agree that minimsing the fields a user needs to complete is a great thing.

    But we’ve had situations where, in testing, users have preferred to see the fields pre-filled, rather than hidden altogether.

    The idea is to reduce cognitive load. Sometime hiding fields actually creates confusion: “Why haven’t they asked me my address? How will they know where to deliver it to?”. It also removes the ability for the user to adjust or amend previously collected information.

    Anyway, great post.

  • No avatar

    28 May 2015 at 05:57

    Hi guys, I’m just filling out this form to test how much of the article applies to my experience. Carry on! :-)

  • No avatar

    1 Jun 2015 at 23:52

    This has been such a helpful post. What form plugins do you recommend?

  • No avatar

    11 Jun 2015 at 14:03

    Really good article! I’ve read a lot about creating and validating forms, but this one gets the point and is really well illustrative! Thanks!

  • No avatar

    20 Jun 2015 at 12:09

    Thank u for this topic! I cannot recall reading do and don’t form article in ages!

  • No avatar
    Viktor Kid

    25 Jul 2015 at 03:53

    Great article Johan! A lot of these points are indeed ignored often which leads to less conversions and of course, a degraded user experience. I like forms with green checkmarks because it almost feels like instant gratification, a tap on your shoulder that makes the user want to continue filling in the form for the next “success”.

    One thing to point out: I read this on iPhone 6 and wanted to share your article but there was no easy sharing option, social sharing buttons please…

  • No avatar
    Jason Arnesen

    8 Dec 2015 at 18:38

    Great info. I really appreciate the time you put into your article and think it’s well thought out. Thanks for your insight.

  • No avatar

    12 Dec 2015 at 01:26

    Great article. Lots of nice, pithy gems in here and really well written. Excellent content, clear illustrations.

    I couldn’t help but laugh, though, to see the Subscribe form immediately following from the final point, in which:

    – Validation is delayed until after you submit, with an errror message on a new page
    – Data format is described, not demonstrated
    – Input field is not labelled
    – Submit button is a customised UI rather (ok, that commandment was talking about radio buttons and checkboxes, but the general principle of not messing about with user’s expectations of what a functional element should look like is still valid).


  • No avatar

    12 Dec 2015 at 10:08

    To be fair, you are comparing a standard WordPress install with my recommendations on custom forms.

    1. Is how WordPress works, unfortunately. I haven’t found a better CMS than WordPress.
    2. A comment, e-mail address and name don’t need a data demonstration
    3. This is actually a bug in WordPress that I noted too, I filed it and it will be fixed in the next version.
    4. Customizing buttons is okay, the point of the customizing UI point is that you often lose accessibility and worsen performance by doing so.


  • No avatar

    15 Feb 2016 at 05:42

    Excellent list and spot on for every single item!

    The animated GIF examples are particularly good.

    Nice one!

  • No avatar

    21 Mar 2016 at 06:11

    Good list! I try and implement a 2 stage validation in general.

    1. simple color/border/icon change on blur (success or error)
    2. descriptive text or expanded error when user returns to error fields

    The default WP submission form is a fiting cherry on top of your get article JR!

  • No avatar

    17 May 2016 at 10:10

    Thank you for this mini-Bible of form design, Johan. I was searching for something like that. I’m currently working on the redesign of quite a long form for (the form is here Everything that should be hidden is hidden, but the form still looks complicated. And I can’t get rid of the fields as they all are vital for the business specific. Could you please take a look at this form and give some ideas on how to improve it? Thanks!

  • No avatar

    5 Oct 2019 at 16:39

    You have covered the topic so well. Wow, the topic “The 10 Commandments of Good Form Design on the Web” is really helpful. Especially, your explanation under the headings of “Thou shalt size the input fields according to their expected input” and “hou shalt provide both a general error message and a field-specific one” are just quite on point. A well-covered article. Keep sharing info and stay blessed :)

  • No avatar

    2 Oct 2023 at 18:34

    I guess using an Ajax is the best idea to make a form, which make things much faster than the traditional methods.

Leave a comment

Your email address will not be published. Required fields are marked *