A required email field keeps helper text visible, shows one field-level error, and marks the input invalid only after submit.

Program

Required fields work best when the hint is always available and the failure state is shown near the control that needs attention.

required_field_hint.html
Visuals: captured from real browser rendering
<form id="signup" novalidate>
  <label for="email">Email</label>
  <input id="email" type="email" required aria-describedby="email-hint email-error">
  <p id="email-hint">Use a work email address.</p>
  <p id="email-error" hidden>Enter an email address.</p>
  <button>Continue</button>
</form>
<style>
  #email[aria-invalid="true"] { border: 2px solid #dc2626; }
  #email-error { color: #b91c1c; font-weight: 700; }
</style>
<script>
  const form = document.querySelector("#signup");
  const email = document.querySelector("#email");
  const error = document.querySelector("#email-error");
  form.addEventListener("submit", event => {
    event.preventDefault();
    const empty = email.value.trim() === "";
    email.setAttribute("aria-invalid", String(empty));
    error.hidden = !empty;
  });
</script>
  1. Mark the field required.

    The email input has a clear requirement before any interaction.
    The email input has a clear requirement before any interaction.
  2. Connect hint and error text.

    The input can point to both persistent help and a later error.
    The input can point to both persistent help and a later error.
  3. Keep the error quiet at first.

    The page starts with guidance, not a failure message.
    The page starts with guidance, not a failure message.
  4. Style the invalid state.

    The input gets a visible border only when marked invalid.
    The input gets a visible border only when marked invalid.
  5. Listen for submit.

    The Continue button sends the form through one validation path.
    The Continue button sends the form through one validation path.
  6. Check for an empty value.

    The failure check trims whitespace before deciding.
    The failure check trims whitespace before deciding.
  7. Render the failed field state.

    The input state and visible error now match the failed check.
    The input state and visible error now match the failed check.
required required marks a form control that must have a value before submission.
aria-describedby aria-describedby connects an input to hint and error text.
field error A field error should appear next to the field that needs correction.