SendForm.net

Why HTML Required Attribute Fails and When It Actually Works

A developer inspects a glowing HTML form on a large screen, highlighting where the required attribute works and where it fails.

The HTML required attribute forces a form field to be filled before the browser lets the form submit, but it only works on native, visible form controls inside a real <form> that submits the normal way. It quietly fails when the field is hidden, disabled, submitted with JavaScript, or when the input type does not support constraint validation. So if your required field lets an empty form through, the problem is almost always where or how the input lives, not the attribute itself.

What the required attribute actually does

Adding required to an input tells the browser this field cannot be empty when the form is submitted. It is a boolean attribute, so its mere presence turns it on. You do not need a value.

<form action="/subscribe" method="post">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" required>
  <button type="submit">Subscribe</button>
</form>

When someone hits submit with that field empty, the browser blocks submission and shows a native bubble ("Please fill out this field"). This is part of the HTML5 constraint validation API, and it works with zero JavaScript. The exact wording and styling of the message comes from the browser, not your code, which is why it looks different in Chrome, Firefox and Safari.

The attribute also flips a CSS pseudo-class. Empty required fields match :invalid, and filled ones match :valid, so you can style them without touching JavaScript.

Why the required attribute fails

Most "the required attribute isn't working" bug reports trace back to one of these situations. The browser is behaving correctly in every case, it just is not validating the field you think it is.

Situation Why it fails
Field is disabled Disabled controls are skipped by validation entirely and are not even sent to the server.
Field is hidden type="hidden" and CSS-hidden fields cannot be validated because the browser cannot focus them to show an error.
No wrapping <form> Constraint validation only runs on submit. No form, no submit, no check.
Submit via JavaScript Calling form.submit() bypasses validation completely. Only user-triggered or requestSubmit() submits validate.
novalidate on the form This attribute turns off all native validation for the entire form.
Button has formnovalidate That specific submit button skips validation (common on "Save draft" buttons).
Whitespace-only input A single space counts as "filled". required checks for empty, not meaningful, content.
The classic trap: submitting a form with document.forms[0].submit(). That method never runs validation. Use form.requestSubmit() instead, which behaves like a real button click and honors required.

The whitespace gap is worth calling out. required only guarantees the field is not empty, not that the value is sensible. A user typing one space passes. To catch that, pair it with a pattern attribute for stricter validation such as pattern=".*\S.*" to require at least one non-space character.

required is only one of several validation types; see HTML form validation for the rest.

When the required attribute actually works

For required to reliably block empty submissions, all of these need to be true:

  • The control is a real form element (input, select, textarea) inside a <form>.
  • The field is visible and enabled (notdisabled, not type="hidden").
  • The form is submitted by a genuine user action or requestSubmit(), not raw submit().
  • Neither the form nor the clicked button carries novalidate / formnovalidate.
  • The input type supports validation (nearly all do, but type="hidden", type="range", type="color", and buttons never fire it because they always have a value).

It works on more than plain text boxes. A required on a textarea element for longer input blocks empty messages, and on a <select> it forces a choice, as long as the default option has an empty value.

<select name="plan" required>
  <option value="">Choose a plan</option>
  <option value="free">Free</option>
  <option value="pro">Pro</option>
</select>

If that first option had value="free" instead of an empty string, the select would always be "filled" and required would do nothing.

Required on checkboxes, radios and file inputs

These behave differently enough to catch people out:

  • Single checkbox: required means the box must be checked. Perfect for "I agree to the terms".
  • Radio group: putting required on any one radio in a group (same name) makes the whole group required, so the user must pick one. See accessible radio button patterns for the full markup.
  • Checkbox group: there is no native way to require "at least one of several". required on a checkbox only requires that specific box. Multi-checkbox rules need JavaScript.
  • File input: required forces a file to be selected. Details and quirks live in this guide to the HTML file upload input.

Required vs aria-required

Native required already exposes the required state to screen readers, so you usually do not need anything else. aria-required="true" exists for cases where you cannot use the native attribute, for example a custom widget built from div s, or a field you deliberately validate yourself and do not want the browser blocking submission.

Rule of thumb: use native required whenever possible. Reach for aria-required only on custom or JS-validated controls where required would either not apply or would fight your own logic. Never rely on aria-required alone to enforce anything, it only announces, it does not block submission.

One caveat: aria-required tells assistive tech the field is mandatory, but it does no validation on its own. If you use it, you are responsible for actually checking the value in JavaScript or on the server.

Marking required vs optional fields

Deciding between required vs optional fields is a design choice as much as a code one. A few practices that hold up well:

  • Mark whichever is rarer. If most fields are required, label the few optional ones with "(optional)" instead of scattering asterisks everywhere.
  • Do not rely on color alone. A red asterisk is invisible to colorblind users and screen readers. Use the native required attribute plus visible text.
  • Ask for less. Every required field lowers completion rates. Cutting optional-but-required-looking fields is one of the reasons shorter forms get more submissions.
  • Validate on the server too. Native validation is a convenience for users. Anyone can bypass it by editing HTML or sending a raw request, so treat required as UX, not security.

That last point matters most. Client-side required improves the experience, but the real gate is your backend. For a broader picture of trustworthy submission handling, see how form submission security combines validation with CSRF protection and sanitization. And since validation only kicks in on submit, double-check where that submission goes with the guide to the HTML form action attribute.

Guide to building reliable HTML forms with required field validation

Build forms where the required attribute never silently fails

Our HTML forms guide walks through validation, submission handling and the exact markup that makes the HTML required attribute work every time, without the hidden-field and JavaScript-submit traps.

Read the HTML forms guide →

Most often the field is disabled, hidden, or the form is submitted with JavaScript's form.submit() , which bypasses validation. Check that the field is visible and enabled, the form has no novalidate attribute, and you use a real submit button or requestSubmit() .

No. Constraint validation only runs when a form is submitted. If your input sits outside a <form> element, there is no submit event to trigger the check, so required does nothing. Wrap the field in a form or validate manually with JavaScript.

Native required both announces the field to screen readers and blocks empty submission. aria-required="true" only announces it, doing no validation. Use native required whenever possible, and reserve aria-required for custom widgets or fields you validate yourself.

Not with native HTML. Adding required to a checkbox only requires that one box. For "pick at least one from several" you need JavaScript that checks the group on submit and sets a custom validity message, since the attribute has no group-level behavior for checkboxes.

No. Anyone can remove required in browser dev tools or send a raw request that skips it entirely. It is a user-experience helper, not a security control. Always re-check required fields on your server and combine that with proper input validation and CSRF protection.