DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Languages
  4. How to Build Great HTML Form Controls

How to Build Great HTML Form Controls

This article highlights all the considerations one should make when creating an HTML form control, from accessibility to functionality to user experience.

Austin Gil user avatar by
Austin Gil
CORE ·
Jan. 10, 23 · Tutorial
Like (2)
Save
Tweet
Share
2.59K Views

Join the DZone community and get the full member experience.

Join For Free

Today I'm going to show you all the things to consider when building the perfect HTML input. Despite its seemingly simple nature, there's actually a lot that goes into it.

How To Make the Control

Well, we need to start somewhere. Might as well start with the control itself.

HTML offers three different form controls to choose from: <input>, <textarea>, and <select>. Today, we'll use <input>, but the same rules will apply to the others.

<input />


How To Make <input> Work

Inputs are generally used to capture user data. To do so, they should be placed within a  <form>  element, but that's not quite enough. When the form is submitted, it won't know how to label the input's data.

For a form to include an input's data when the form is submitted, the input needs a name attribute. You don't need state management or data binding. Just a name.

<input name="data" />


How To Make the Input Accessible

Now that we've made the robots happy, it's time to focus on the humans.

Every input also needs a label, both for clarity and for accessibility. There are a few options:

  •  Add a <label> element with a for attribute and assign it to the input's id (explicit label).
  • Wrap the input with a <label> element (implicit label).
  • Add an aria-label attribute to the input.
  • Add an aria-labeledby attribute to the input and assign it to the id of another element.

Of all these options, the most reliable is an explicit label as it works across the most browsers, assistive technologies, and voice-control interfaces. Implicit labels do not work in Dragon Speech Recognition. ARIA attributes are finicky. 

The placeholder and title attributes are not proper labels.

I recommend not wrapping everything in a <label> tag because:

  1. It's prone to include more content than what would be considered the label. This results in a poor experience for screen-reader users.
  2. It's common to add styles to the input's wrapper element. These styles may conflict with the default behavior of a <label>.

In general, I prefer using a <div> to isolate the control.

<div>
    <label for="input-id">Label</input>
    <input id="input-id" name="data" />
</div>


If you ever want an input that does not show the label, don't remove the label from the HTML. Instead, hide it with CSS or use a less reliable option. Keep the label in the markup and visually hide it with a class with these styles. These styles keep it accessible to assistive technology, while also visually removing it:

.visually-hidden {
  position: absolute;
  overflow: hidden;
  clip: rect(0 0 0 0);
  width: 1px;
  height: 1px;
  margin: -1px;
  border: 0;
  padding: 0;
}


Note that it's still generally advised to include a visible label to avoid any confusion. A placeholder should not serve as a label.

How To Choose a Type (Or Not)

In addition to the different tags listed above, you can change the control's behavior by setting an input's type attribute. For example, if you wanted to accept a user's email, you can set the type attribute to "email". 

Input types can change the behavior or appearance of the UI. Here are just a few examples:

  • The "number" type changes behavior by preventing non-number value entries.
  • The "color" type changes the UI by adding a button that opens a color picker.
  • The "date" type improves the data entry experience by offering a date-picker.
  • The "email" type enforces built-in constraint validation on form submission. 

However, some input types may be false friends.

Consider an input that asks for a US zip code. Only numerical entries are valid, so it might make sense to use a "number" type. However, one issue with the "number" input is that it adds a scroll event feature such that a user can scroll up on the input to increment the value or down to decrement it.

For a zip code input, it's possible that a user clicks on the input, enters their zip code, then tries to scroll down the page. This would decrement the value they entered, and it's very easy for the user to miss that change. As a result, the number they entered could be wrong.

In this case, it may be better to avoid the type attribute completely and use a pattern such as [0-9]* if you want to limit the input to only numeric values. In fact, the "number" type is often more problematic than it's worth.

Be Descriptive

Since we've briefly touched on constraint validation, it's a good time to mention descriptions. 

Although HTML has built-in validation attributes and there are several more robust JavaScript validation libraries, there is another effective approach to getting users to fill in proper data that can be less annoying.

Tell them exactly what it is you want.

Some form controls like "name" or "email" may be obvious, but for those that are not, provide a clear description for what you need. 

For example, if you are asking users to create a new password, tell them what the requirements are before they try to submit the form. And don't forget about assistive technology users.

We can associate an input with a description through visual proximity as well as using the aria-describedby attribute.

<div>
    <label for="password">Password</input>
    <input id="password" name="password" type="password" aria-describedby="password-requirements" />
    <p id="password-requirements">Please create a new password. Must contain at least 8 characters, one uppercase letter, one lowercase letter, and one special character.</p>
</div>


Descriptions are also an effective place to put any validation feedback messages.

Be Flexible

When creating inputs, it's often tempting to add constraints for the acceptable values to ensure the user only sends good data. But being too strict can lead to a poor user experience.

For example, if you ask the user to enter a phone number, consider that there are several different acceptable formats:

  • 8008675309
  • 800 867 5309
  • 800-867-5309
  • 800.867.5309
  • (800) 867-5309
  • +1 (800) 867-5309
  • 001 800 867 5309

All of the above represent the same phone number. Ideally, a user would be able to enter any of these formats and still be able to submit the form without issue.

If you want your input to only send number characters, it's possible to allow the user to type in whatever format they want. Then you can use JavaScript to add an event handler to the blur event, and remove any unwanted characters (space, dash, period, and so on) from the input's value. This would leave only the numbers.

Make It Easy

If you've ever filled out a form using a mobile device, you may have noticed that your phone's keyboard looks different on different inputs. 

For a basic text input you see the standard keyboard, for email inputs you may see the @ symbol more conveniently placed, and for number inputs you may see the keyboard replaced with a number pad.

In many cases, the browser will choose a more appropriate keyboard to show users if the input type is set. But as we saw above, it's often better to use just a basic text input.

We can still offer a nicer user experience to mobile users by asking the browser to show specific keyboards despite the input missing a type attribute. We can accomplish this with the inputmode attribute which accepts eight different options.

  • text (default value)
  • none
  • decimal
  • numeric
  • tel
  • search
  • email
  • url

Want to give it a try? Head over to inputmodes.com on your mobile device. It's pretty cool.

Continue Learning

That's over a thousand words I had to say about creating form controls. I hope you found it useful. 

HTML Attribute (computing) Form (document) Web development

Published at DZone with permission of Austin Gil. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • The Future of Cloud Engineering Evolves
  • Type Variance in Java and Kotlin
  • Top Five Tools for AI-based Test Automation
  • What Java Version Are You Running? Let’s Take a Look Under the Hood of the JDK!

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: