Skip to content
easeweb
Search topics

Input masks that change a typed or pasted number

A phone field's mask has ten fixed places, so a number pasted with +1 in front becomes another number, and the mask's blanks are read out as the field's value.

Best practice
No WCAG criterion requires it
Related WCAG 2.2
SC 3.3.2A
Required by
Not required by Section 508 or EN 301 549
Broken Inputmask('(999) 999-9999').mask(tel);
The accessibility problem illustrated: Motor:Why did my number change?
01

The problem

People who paste a number, let the browser fill it in or type it their own way get a different number from the one they gave, and screen reader users hear a pattern of blanks as the field's value.

02

Try it

Copy the number from the contact card, paste it into Phone number, and press Continue.

  • Broken 1: Tab into the field first and read what the panel under the form says. Then paste the number: which digits went in?

  • Broken 2: paste the number, then clear the field, type 2125550147 yourself, click just after the first 5 and change it with Backspace and another digit. Where does the caret go?

  • Apply a fix. Paste the number, or type it any way you like, with spaces, dots or brackets, and press Continue.

Broken Can you fix this?

Your contact card

Mobile +1 212 555 0147

Delivery texts

Screen reader says:

(Tab to the field)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Take the number as it is typed, and check its digits.

Before

A mask library with the pattern in the field

<form>  <label for="tel">Phone number</label>  <input id="tel" name="tel" type="tel" autocomplete="tel">  <button type="submit">Continue</button></form>
What is wrong3 points
  • When the field takes focus, its value becomes the pattern (__) -, and a screen reader reads that as what it holds.
  • The mask has ten places. Pasted as +1 212 555 0147, the number fills them with its first ten digits and shows (121) 255-5014; the last 7 is dropped.
  • The + is thrown away, and nothing says the number changed.
After

No mask, and the digits checked when the form is sent

<form>  <label for="tel">Phone number</label>  <p id="tel-hint">Include the area code, such as (212) 555-0147.</p>  <input id="tel" name="tel" type="tel" autocomplete="tel"    aria-describedby="tel-hint tel-error">  <p id="tel-error"></p>  <button type="submit">Continue</button></form>
How it is fixed5 steps
  1. Remove the mask, so the field keeps the number as it is typed or pasted, with any spaces, brackets, dashes or dots.
  2. Put an example under the label, tied to the field with aria-describedby. It is read with the field, and stays on screen while people type.
  3. When the form is sent, keep only the digits, and drop a leading 1 when there are eleven, so +1 212 555 0147, (212) 555-0147 and 212.555.0147 are the same ten digits.
  4. Give a value with the wrong number of digits a message that says what to enter, tied to the field.
  5. Send the ten digits, and keep them the same way on the server, since a request can reach it without this script.

This fixes both Befores. Nothing changes the field while people type, so the caret stays where they put it and a pasted number goes in whole; it passes 3.3.2, as the Befores did, with the format now in words.

04

Verify the fix

6 checks, no mouse.

Test with: Keyboard, Touch, Autofill, Screen reader

0 of 6 checked

Record the OS, browser, assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared phone field or its formatting changes.

Limits

This is a starting pattern, not a guarantee for every application. The example is a US number with ten digits and an optional country code 1; other countries need other lengths, and an international form keeps the +. A number asked for in three boxes, one for each group, is a different failure, covered in split date and phone fields with no name for each box. How a message reaches people after a failed submission is covered in form errors that don't say how to fix them.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service