When defining form fields in HTML, one of the most common cases is a numeric field where we want to control exactly how many decimal places the user can enter. The classic example is a price field: we need two decimal places, no more, no less.
In this article, we are going to see how we can limit the number of decimal places in an <input type="number"> in HTML, using both native element attributes and a small JavaScript enhancement to guarantee the correct format.
The <input type="number"> element in HTML allows users to enter numeric values; however, by default, it does not allow limiting the number of decimal places using an attribute that specifies a minimum amount or a base way to define the decimal count.
The step attribute: the key to accepting decimals
By default, an <input type="number"> only accepts integers. If you try to type 1.5 without configuring anything else, the field may reject it or flag it as invalid depending on the browser. To enable decimals, we need the step attribute.
The step attribute defines the interval between valid values in the field. When set to 0.01, we are telling the browser that any value with up to two decimal places is acceptable.
<input type="number" step="0.01" id="price">With this, the field accepts decimal values such as 9.99, 0.50, or 100.00. It also works with the browser's increment arrows: each click increases or decreases the value by 0.01.
Important: the
stepattribute defines the interval of valid values, but it does not prevent the user from typing more decimals than expected. A user could type9.9999and the browser would display it, although it would mark the field as invalid upon submitting the form. To force rounding in real time, it is necessary to combinestepwith JavaScript.
Variations of the step attribute based on the number of decimal places
The value of step directly determines the number of allowed decimal places. Here are the most common cases:
step="0.01"→ allows up to 2 decimal places (ideal for prices and amounts)step="0.001"→ allows up to 3 decimal places (useful for fine percentages or dosages)step="0.1"→ allows up to 1 decimal placestep="any"→ accepts any decimal value without interval restrictions
For example, for a percentage field with two decimal places:
<input type="number" step="0.01" min="0" max="100" id="percentage">Forcing exactly 2 decimal places with JavaScript
If you need the field to always display exactly two decimal places, even when the user enters an integer like 5, the solution is to combine the step attribute with an event handler in JavaScript that uses the toFixed(2) method.
First, the HTML for the field with step="0.01":
<input type="number" step="0.01" id="price">Next, the JavaScript block that ensures real-time formatting:
const priceInput = document.getElementById("price");
// Handler that ensures the value has exactly two decimal places upon modification
priceInput.addEventListener("input", function (event) {
const value = event.target.valueAsNumber;
// We verify it is a valid number before reformatting
if (!isNaN(value)) {
event.target.value = value.toFixed(2);
}
});The valueAsNumber method returns the field's value as a floating-point number, and toFixed(2) formats it with exactly two decimal places, rounding if necessary. This way, if the user types 9.999, the field will automatically show 10.00.
What about the inputmode attribute?
Although it does not control the number of decimal places, the inputmode="decimal" attribute is very useful on mobile devices. It tells the browser to display the numeric keypad with decimal separator support, significantly improving the user experience on touch screens.
<input type="number" step="0.01" inputmode="decimal" id="price">The key difference: inputmode only affects the onscreen virtual keyboard without changing the field's validation behavior. It is a complement, not a replacement for the step attribute.
Summary
To allow decimal places in an <input type="number"> in HTML, the native solution is to use the step attribute:
- For 2 decimal places:
step="0.01" - For 3 decimal places:
step="0.001" - For any decimal value without interval restrictions:
step="any"
If you also need to ensure that the value is always displayed with exactly two decimal places, add a JavaScript listener using toFixed(2). And if the field is going to be used on mobile devices, combine it with inputmode="decimal" to enhance the touch keyboard experience.