I’ve created HTML and CSS code to illustrate an idea for setting the width on form fields where data entered has a known maxlength. My case is forms that ask for a postcode. In addition to guiding sighted users, I’ve added attributes to make completing on smartphones as easy as possible.

… you might be tempted to give every address field the same width.
But giving the postcode field the same width as every other field increases the cognitive effort needed to fill it out. This is because the width gives users a clue as to the length of the content it requires.

Silver, A. (2018). A Checkout Form. In Form Design Patterns. Smashing Media AG.

For example, Australian postcodes are 4 characters long. Setting the width of the input just a little wider than this helps sighted users understand what is expected.

See the Pen Input width to guide sighted users by Vernon Fowler (@vfowler) on CodePen.


My main reason for switching the input type away from type="number" to type="text" is I discovered the presence of spinner buttons causes painful experiences. In September 2018, manual accessibility testing a form postcode field with type="number" caused confusion with increment and decrement spinbox announcements, and frustration with operating the keyboard to enter the 4 digits. If in doubt, check Silver’s list of criteria for When to use the number input.

Adding autocomplete="postal-code" benefits everyone completing a form that requests personal data. Autocomplete can save time, eliminate typing or spelling errors, and make it easier to complete for anyone with cognitive or mobility impairments. In Exploring WCAG 2.1 — 1.3.5 Identify Input Purpose, Gibson’s video clearly demonstrates how form fields with autocomplete contrast those without. Lastly, using appropriate autocomplete attributes is a requirement for Level AA compliance with WCAG2.1.

Using pattern="[0-9]*" will validate that the input only contains digits 0 through 9. As Australian postcodes do not contain letters or any other characters, this seems warranted. It can also trigger the large numeric keypad on iOS, for an iPhone but not on iPad. To achieve a similar keypad on Android, add inputmode="numeric", however:

Update May 10th, 2019: With iOS 12.2 Apple appears to have introduced a bug where the numeric keyboards … no longer invoke the true “numeric” keyboard with the enlarged number keys (beyond the “tel” keyboard).

Touch Keyboard Types ‘Cheat Sheet’ by Baymard Institute

In the meantime, with inputmode="numeric" iOS 12.2 iPhone users will see the keyboard with keys 1 through 0 across the top row, with special characters below.

According to Grainer, autocorrect is on by default. I’ve set autocorrect="off" to avoid any dictionary lookup.

Postcodes in Australia are all 4 digits, but we’re allowing at least 3 digits for anyone forgetting a leading zero from postcodes such as 0800—0899. Thus the minlength="3" maxlength="4" attributes. (By the way, a leading zero is another reason input type="number" is unsuitable.)


I’ve created style rules for any input that has a maxlength attribute. I set padding vertically and horizontally via padding: 0.3rem 1ch; because, as McDowell concludes, “rems are good for vertical cadence, and ch is good for horizontal cadence” (Using Ch, An Underappreciated CSS Length by Justin McDowell). I also use the ch unit to calculate the input box width. Before going further, note that:

… a ch unit is equal to the width of the 0 (zero) glyph found in the font used to render it. This definition works for monospaced fonts (where every glyph shares an identical width), but it’s completely unreliable for proportional fonts.

Making Sense of Ch Units by John D. Jameson

Rather than do extra calculations to use proportional fonts, I’ve chosen monospace fonts to help users distinguish a 1 from an l, or a 0 from an O, and any other similar looking characters. Try entering 1lO0 in the input box above to see how the characters render visually with these fonts.

Finally, with Australian postcodes at 4 characters, I set the width of the input box: input[maxlength="4"] {
width: calc(4ch + 2ch + 1ch + 2px);

/* maxlength + padding + breathing space + border */

I add 1ch of breathing space on McDowell’s formula. I found his fudge factor of 0.1ch put the blinking cursor hard up against the right edge of the input box. Sometimes the leftmost of my 4 characters had their left edge cropped. There was also the question: Had I typed more characters and these are the most recent 4? Don’t make me think. Adding 1ch of breathing space makes it clear that the input box has enough characters, and not more than the maximum.


Leave a comment

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