EthicsComputerCourses
Join training +91 90532 10052

Forms & Error States

UI/UX Design · Lesson 21 of 30 Advanced 6 min read Updated

By the end of this lesson you will be able to design a short, friendly form, choose the right field types for Indian phone numbers and PIN codes, and write error states that tell people exactly how to fix a problem.

Forms are where users give you something: their name, number, address or money. They are also where many people give up. Every confusing label, surprise error or wiped field costs you a booking, a sign-up or a sale.

Start by asking for less

The best form field is the one you remove. Before designing, list every field and ask, "Do we need this now?" A clinic booking needs a name and a mobile number. It does not need a full address, email and date of birth before the first visit.

Think of a good chemist. He asks for the prescription and maybe your name. He does not ask for your father's occupation. Ask only for what the task needs.

Layout basics

  1. One column. People read forms top to bottom. Side-by-side fields get skipped.
  2. Labels above fields, left aligned, close to their field.
  3. Group related fields with a heading or a fieldset, such as "Patient details" and "Visit details".
  4. Mark optional fields with "(optional)" rather than marking every required field with a red star.
  5. One primary button at the end, with a clear verb: "Book visit", not "Submit".

Labels, not placeholders

A placeholder is the grey hint text inside an empty field. It disappears when you type, so people forget what the field was for. It is usually low contrast too. Never use a placeholder as the only label.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Label vs placeholder</title>
  <style>
    body { font-family: system-ui, sans-serif; padding: 16px; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 32px; color: #1a1a2e; }
    h2 { font-size: 15px; }
    input { display: block; width: 100%; box-sizing: border-box; min-height: 44px; padding: 8px 12px; border: 1px solid #6b7280; border-radius: 8px; font-size: 16px; margin-bottom: 16px; }
    label { display: block; font-weight: 600; margin-bottom: 4px; }
    .hint { display: block; font-weight: 400; color: #4b5563; font-size: 14px; }
  </style>
</head>
<body>
  <form>
    <h2>Placeholder only</h2>
    <input placeholder="Full name" aria-label="Full name">
    <input placeholder="Mobile number" aria-label="Mobile number">
  </form>
  <form>
    <h2>Visible labels</h2>
    <label for="name">Full name</label>
    <input id="name" autocomplete="name">
    <label for="mob">Mobile number <span class="hint">10 digits, we will send an OTP</span></label>
    <input id="mob" type="tel" inputmode="numeric" autocomplete="tel-national" maxlength="10">
  </form>
</body>
</html>

Type into the first form: the hint text vanishes, and now nothing tells you what each field is. The second form keeps the labels and adds a helpful hint. Read the label rules in more depth in Form Labels & Instructions.

Use the right field types

Field types bring up the right keyboard on phones and help autofill. That saves taps.

DataHTML type and attributesWhy
Mobile numbertype="tel", autocomplete="tel-national"Number pad; keeps leading zeros; browser can autofill
OTPinputmode="numeric", autocomplete="one-time-code"Number pad; phones can suggest the code from SMS
PIN codeinputmode="numeric", maxlength="6"Indian PIN codes have 6 digits
Emailtype="email", autocomplete="email"Keyboard with @
Nameautocomplete="name"One field: many people have one name, or names that do not split neatly

When to validate

Validation means checking whether the input is acceptable. Timing matters:

  • Too early: showing "Invalid number" after the first digit feels like being scolded mid-sentence.
  • Good default: check a field when the person leaves it (on blur), and check everything again on submit.
  • Once an error shows: re-check as they type, so the error disappears the moment it is fixed.

Write useful error messages

A good error message is specific, polite and tells people how to fix the problem. It appears right next to the field and does not rely on red colour alone.

WeakBetter
Invalid inputEnter a 10-digit mobile number, like 98765 43210
Error 422That date is in the past. Choose today or a later date.
Wrong!That OTP did not match. Check the latest SMS, or resend the code.

Run this example. Leave the mobile field after typing only a few digits, or press "Book visit" with empty fields.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Inline errors</title>
  <style>
    body { font-family: system-ui, sans-serif; padding: 16px; max-width: 360px; color: #1a1a2e; }
    .field { margin-bottom: 20px; }
    label { display: block; font-weight: 600; margin-bottom: 4px; }
    .wrap { display: flex; align-items: center; border: 1px solid #6b7280; border-radius: 8px; overflow: hidden; }
    .wrap span { padding: 0 10px; color: #4b5563; border-right: 1px solid #d4d4dc; }
    input { flex: 1; min-height: 44px; border: 0; padding: 8px 12px; font-size: 16px; min-width: 0; }
    .solo { width: 100%; box-sizing: border-box; border: 1px solid #6b7280; border-radius: 8px; }
    .error { display: none; color: #b91c1c; font-size: 14px; margin: 6px 0 0; }
    .invalid .wrap, .invalid .solo { border: 2px solid #b91c1c; }
    .invalid .error { display: block; }
    button { width: 100%; min-height: 48px; border: 0; border-radius: 8px; background: #5b21b6; color: #fff; font-size: 16px; font-weight: 600; }
    #done { color: #14532d; font-weight: 600; }
  </style>
</head>
<body>
  <form id="form" novalidate>
    <div class="field" id="f-name">
      <label for="name">Patient name</label>
      <input class="solo" id="name" autocomplete="name" aria-describedby="e-name">
      <p class="error" id="e-name">⚠ Enter the patient's name.</p>
    </div>
    <div class="field" id="f-mob">
      <label for="mob">Mobile number</label>
      <div class="wrap"><span>+91</span><input id="mob" type="tel" inputmode="numeric" autocomplete="tel-national" aria-describedby="e-mob"></div>
      <p class="error" id="e-mob">⚠ Enter a 10-digit mobile number, like 98765 43210.</p>
    </div>
    <button type="submit">Book visit</button>
    <p id="done" role="status"></p>
  </form>
  <script>
    const rules = {
      name: v => v.trim().length > 0,
      mob: v => /^[6-9]\d{9}$/.test(v.replace(/[\s-]/g, ''))
    };
    function check(id) {
      const input = document.getElementById(id);
      const ok = rules[id](input.value);
      document.getElementById('f-' + id).classList.toggle('invalid', !ok);
      input.setAttribute('aria-invalid', String(!ok));
      return ok;
    }
    Object.keys(rules).forEach(id => {
      const input = document.getElementById(id);
      input.addEventListener('blur', () => { if (input.value) check(id); });
      input.addEventListener('input', () => { if (input.getAttribute('aria-invalid') === 'true') check(id); });
    });
    document.getElementById('form').addEventListener('submit', e => {
      e.preventDefault();
      const results = Object.keys(rules).map(check);
      const firstBad = Object.keys(rules)[results.indexOf(false)];
      if (firstBad) { document.getElementById(firstBad).focus(); return; }
      document.getElementById('done').textContent = '✓ Visit booked. We have sent an SMS.';
    });
  </script>
</body>
</html>

You should see two fields and a button. A short number, after you leave the field, gets a thick red border, a warning icon and a message that explains the fix. Typing a valid number makes the error vanish at once. Submitting with errors moves focus to the first problem. A correct submission shows a success message. The pattern ^[6-9]\d{9}$ reflects that Indian mobile numbers have 10 digits and currently start with 6 to 9.

Error summary for long forms

On long forms, also show a short summary at the top after a failed submit, listing each error as a link to its field. People who scrolled past an error then know where to go. The accessibility course covers this in Error Messages & Validation.

Never lose what people typed

If submission fails because of a network problem, keep every value in the fields and say what happened: "We could not reach the clinic. Your details are saved here. Try again." Wiping a form is one of the fastest ways to lose a user forever.

Common mistakes

  • Placeholders as labels.
  • Generic errors like "Invalid input" or error codes.
  • Errors shown only at the top, far from the field.
  • Red colour as the only signal. Add an icon and text.
  • Clearing the form after an error.
  • Strict formats that reject spaces, dashes or lowercase letters.

Key points

  • Ask for the fewest fields the task needs, in one column with labels above.
  • Use visible labels; placeholders are only hints.
  • Choose field types that bring up the right keyboard and autofill.
  • Validate when a field is left, and re-check as people fix errors.
  • Error messages must be specific, polite, next to the field and not colour-only.
  • Keep what people typed, even when something fails.

Exercise

Add a "PIN code" field to the inline errors example. It should accept exactly six digits, use a numeric keyboard, and show the error "Enter your 6-digit PIN code, like 302001." Then rewrite these errors to be helpful: "Invalid date", "Field required", "Format error".

Show solution
HTML
<div class="field" id="f-pin">
  <label for="pin">PIN code</label>
  <input class="solo" id="pin" inputmode="numeric" autocomplete="postal-code" maxlength="6" aria-describedby="e-pin">
  <p class="error" id="e-pin">⚠ Enter your 6-digit PIN code, like 302001.</p>
</div>
JavaScript
pin: v => /^\d{6}$/.test(v.trim())

Add the rule to the rules object; the existing loop then wires up blur, input and submit checks for it. Rewrites: "Choose a date from today onwards", "Enter the patient's name", "Enter the amount in numbers, like 600".

Quick Quiz

1. Why should placeholders not replace labels?

2. When is a good default time to validate a field?

3. Which error message is most helpful?

Learn UI/UX Design with a mentor

Free lessons get you started. Our UI/UX Design training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call