{"id":198412,"date":"2015-03-25T06:28:19","date_gmt":"2015-03-25T13:28:19","guid":{"rendered":"http:\/\/css-tricks.com\/?p=198412"},"modified":"2015-03-26T08:51:56","modified_gmt":"2015-03-26T15:51:56","slug":"numeric-inputs-a-comparison-of-browser-defaults","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/numeric-inputs-a-comparison-of-browser-defaults\/","title":{"rendered":"Numeric Inputs – A Comparison of Browser Defaults"},"content":{"rendered":"

The spec, purposefully, stops short of telling implementations (browsers) how to handle UI. In this article we’re looking specifically at <input type=\"number\"><\/code>, and you might be surprised to learn that the spec specifically says<\/a>: <\/p>\n

This specification does not define what user interface user agents are to use.<\/p><\/blockquote>\n

It goes on to explain that different languages, cultures, and regions might have good reason to handle numeric inputs differently. So browsers are on their own here, and perhaps this time unsurprisingly, there are quite a few different approaches to the UI. Let’s take a look.<\/p>\n

<\/p>\n

The Markup<\/h3>\n
<form>\r\n  <label for=\"age\">Enter your age<\/label>\r\n  <input type=\"number\" id=\"age\" name=\"age\">\r\n<\/form><\/code><\/pre>\n

This produces a simple form with one single input that accepts numeric values. I added some CSS for presentational purposes in the demos that follow, but this is the basic HTML markup we’re looking at.<\/p>\n

How Internet Explorer Handles It<\/h3>\n
Default behavior in Internet Explorer 11<\/figcaption><\/figure>\n

Internet Explorer offers the simplest default presentation among desktop browsers. The input looks like any other form input that accepts text. In fact, IE is making no user interface decisions for us at all, except the ability to clear the input once something has been entered. That’s a handy little feature, and one that other browsers do not include (although it’s sometimes seen on type=\"search\"<\/code> inputs).<\/p>\n

How Firefox Handles It<\/h3>\n
Default behavior in Firefox<\/figcaption><\/figure>\n

Firefox introduces UI that IE does not: spinner controls. These controls include up and down arrows that increase and decrease the numeric value of the field when clicked, respectively.<\/p>\n

Removing the controls can be accomplished with a little CSS using the appearance<\/code><\/a> property:<\/p>\n

\/* Remove controls from Firefox *\/\r\ninput[type=number] {\r\n  -moz-appearance: textfield;\r\n}<\/code><\/pre>\n

While that does a nice job of removing the controls, it appears we have no control over the design of them.<\/p>\n

How Safari Handles It<\/h3>\n
Default behavior in Safari<\/figcaption><\/figure>\n

Firefox and Safari are similar in how they treat numeric inputs. Both include spinner controls and both leave out the clearing UI seen in IE.<\/p>\n

We can also remove the controls from Safari, but differently than Firefox using a method that tackles the Shadow DOM<\/a>:<\/p>\n

\/* Remove controls from Safari and Chrome *\/\r\ninput[type=number]::-webkit-inner-spin-button, \r\ninput[type=number]::-webkit-outer-spin-button { \r\n  -webkit-appearance: none;\r\n  margin: 0; \/* Removes leftover margin *\/\r\n}<\/code><\/pre>\n

Another element that we can style in the Shadow DOM is the invisible box around the number:<\/p>\n

\/* Adds a box around the numeric value in Safari and Chrome *\/\r\ninput[type=number]::-webkit-textfield-decoration-container {\r\n  border: 1px #ccc solid;\r\n  background: #efefef;\r\n}<\/code><\/pre>\n

Might be useful, or it might not. Either way, it’s nice to have a little more design flexibility in Safari (and Chrome) compared to what we’ve seen so far.<\/p>\n

How Chrome Handles It<\/h3>\n
Default behavior in Chrome<\/figcaption><\/figure>\n

Chrome sort of falls in the middle of the crowd. At first glance, we’re presented with a simple form input. Then, just as the cursor moves over the field, the same controls in Firefox and Safari are displayed.<\/p>\n

Again, it’s interesting and worth noting that Firefox, Safari, Chrome and Opera have decided that quantity controls are enough of a benefit to user experience that they include them where IE has left them out. Then again, Chrome takes the middle ground by revealing the controls on hover as opposed to displaying them by default.<\/p>\n

What if we want Firefox to behave like Chrome and display the controls on hover? We can remove the controls from Firefox like we did earlier, then re-apply them on :hover<\/code><\/a> and :focus<\/code>:<\/p>\n

\/* Remove controls from Firefox *\/\r\ninput[type=number] {\r\n  -moz-appearance: textfield;\r\n}\r\n\r\n\/* Re-applies the controls on :hover and :focus *\/\r\ninput[type=\"number\"]:hover,\r\ninput[type=\"number\"]:focus {\r\n  -moz-appearance: number-input;\r\n}<\/code><\/pre>\n

While Chrome and Safari might not be as similar as we might expect, they do share an ability to style and manipulate the input using the Shadow DOM elements. In fact, the same techniques covered in the Safari section apply to Chrome as well.<\/p>\n

How Opera Handles It<\/h3>\n

Opera handles numeric inputs exactly like Chrome. That should come as no surprise since Opera adopts the same Blink rendering engine as Chrome. That means that the same CSS tricks to hide and style the input in Safari and Chrome also apply here with Opera.<\/p>\n

Since Opera only recently updated to Blink, it’s interesting to see how its last pre-update version, Opera 12, handles numeric inputs.<\/p>\n

Default behavior in Opera 12<\/figcaption><\/figure>\n

The difference here is how the the controls float outside the input. Where Firefox, Safari, Chrome and the latest Opera place the controls squarely inside the input, Opera 12 has them completely outside of the field. Even more notable is how Opera has decided to place borders around the controls. This creates what appears to be a full-fledged user interface complete with buttons that extend the width of the input by default.<\/p>\n

Removing the controls from Opera is no easy task and can only be removed by changing the input type to text<\/code> in the HTML and restricting the pattern of accepted characters strictly to numbers:<\/p>\n

<form>\r\n  <label for=\"age\">Enter your age<\/label>\r\n  <input type=\"text\" pattern=\"[0-9]*\" id=\"age\" name=\"age\">\r\n<\/form><\/code><\/pre>\n

Another difference is how the number is right-aligned. This is sort of reminiscent of how Excel automatically aligns numeric spreadsheet cells to the right. All other browsers keep the text aligned to the left, so we can force Opera to do the same using CSS:<\/p>\n

html:not([dir=\"rtl\"]) input {\r\n  text-align: left;\r\n}<\/code><\/pre>\n

This snippet searches the DOM for any input that is not set right-to-left and forces the text to the left. This would be applied globally as written, but could be modified with more specificity, if needed.<\/p>\n

One final detail worth noting is all the highlighting that’s happening on :focus<\/code><\/a>. Opera applies what appears to be the heaviest amount of styling when the field is targeted, all the way down to the quantity controls, which have their own active states when clicked.<\/p>\n

How Mobile Safari and Android Handle It<\/h3>\n
Default behavior in Mobile Safari<\/figcaption><\/figure>\n
Default behavior in Android 4.4<\/figcaption><\/figure>\n

Mobile Safari and the Android Browser are very similar when stacked head-to-head. Both behave much like IE in that they offer no controls directly on the input, but they also diverge from IE in that they provide no added user interface for clearing the input once something has been entered. In this sense, the mobile browsers offer the simplest default implementation of the entire set.<\/p>\n

These browsers recognize type=\"number\"<\/code> and instantly serve a numeric keyboard when the input is in focus. That’s pretty cool and serves as an excellent reminder that adding the proper type<\/code> to any form field is a good practice for good user experience.<\/p>\n

The Results<\/h3>\n

Here’s a summary of the findings covered in this post.<\/p>\n\n\n\n\n\n\n\n\n\n\n
Does it Have?<\/span><\/th>\nIE<\/span><\/th>\nSafari<\/span><\/th>\nFirefox<\/span><\/th>\nChrome<\/span><\/th>\nOpera<\/span><\/th>\niOS<\/span><\/th>\nAndroid<\/span><\/th>\n<\/tr>\n<\/thead>\n
Spinner Controls<\/td>\nNo<\/td>\nYes<\/td>\nYes<\/td>\nOn Hover<\/td>\nOn Hover<\/td>\nNo<\/td>\nNo<\/td>\n<\/tr>\n
Clearing Control<\/td>\nYes<\/td>\nNo<\/td>\nNo<\/td>\nNo<\/td>\nNo<\/td>\nNo<\/td>\nNo<\/td>\n<\/tr>\n
Left Alignment<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\n<\/tr>\n
Focus Styling<\/td>\nOn Hover<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nNo<\/td>\nNo<\/td>\n<\/tr>\n
Keyboard Commands<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nYes<\/td>\nNo<\/td>\nNo<\/td>\n<\/tr>\n
Shadow DOM Control<\/td>\nNo<\/td>\nYes<\/td>\nNo<\/td>\nYes<\/td>\nYes<\/td>\nNo<\/td>\nNo<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n

In Conclusion<\/h3>\n

It can be frustrating when browsers behave differently. We’ve been dealing with that in various ways for a long time. That’s how hacks—err, tricks— are discovered.<\/p>\n

The interesting thing a comparison like this reveals is how these differences have an impact on user experience. If we were to create a numeric form input and rely on browser defaults to handle the display, then it’s very possible that two different visitors to the site will have two totally different experiences. Although that experience might also be consistent for them across<\/em> sites, since that user likely sticks to one browser.<\/p>\n

How do you feel about these UI differences? Do you have a favorite? Have you tried overriding them? What can we do with JavaScript here? Please share in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"

The spec, purposefully, stops short of telling implementations (browsers) how to handle UI. In this article we’re looking specifically at <input type=”number”\/>, and you might be surprised to learn that the spec specifically says: This specification does not define what user interface user agents are to use. It goes on to explain that different languages, […]<\/p>\n","protected":false},"author":2508,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":306387,"url":"https:\/\/css-tricks.com\/better-form-inputs-for-better-mobile-user-experiences\/","url_meta":{"origin":198412,"position":0},"title":"Better Form Inputs for Better Mobile User Experiences","date":"April 17, 2020","format":false,"excerpt":"Here\u2019s one simple, practical way to make apps perform better on mobile devices: always configure HTML input fields with the correct type, inputmode, and autocomplete attributes. While these three attributes are often discussed in isolation, they make the most sense in the context of mobile user experience when you think\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/04\/input-date-featured.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":304551,"url":"https:\/\/css-tricks.com\/what-to-use-instead-of-number-inputs\/","url_meta":{"origin":198412,"position":1},"title":"What to Use Instead of Number Inputs","date":"March 6, 2020","format":false,"excerpt":"You might reach for when you're, you know, trying to collect a number in a form. But it's got all sorts of issues. For one, sometimes what you want kinda looks like a number, but isn't one (like how a credit card number has spaces), because it's really\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/04\/inputmode.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":270286,"url":"https:\/\/css-tricks.com\/finger-friendly-numerical-inputs-with-inputmode\/","url_meta":{"origin":198412,"position":2},"title":"Finger-friendly numerical inputs with `inputmode`","date":"April 30, 2018","format":false,"excerpt":"Forms are often a nightmare on mobile. We can make the process as pain-free as possible by reacting to context. Input fields that expect numerical values should have a numerical UI. Bringing up a number keyboard on small screens is easy on most platforms \u2014 just use a . This\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/04\/inputmode.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":187037,"url":"https:\/\/css-tricks.com\/datalists-different-input-types\/","url_meta":{"origin":198412,"position":3},"title":"Datalists for Different Input Types","date":"October 26, 2014","format":false,"excerpt":"I saw an HTML5 date input the other day, which had the dropdown arrow on the right, which I've grown accustom to clicking to reveal a calendar datepicker in which to choose a date. Typically, that looks like this: I've seen variations on this before, like when you\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":287475,"url":"https:\/\/css-tricks.com\/everything-you-ever-wanted-to-know-about-inputmode\/","url_meta":{"origin":198412,"position":4},"title":"Everything You Ever Wanted to Know About inputmode","date":"May 17, 2019","format":false,"excerpt":"The inputmode global attribute provides a hint to browsers for devices with onscreen keyboards to help them decide which keyboard to display when a user has selected any input or textarea element.