Try entering a credit card number in both fields. Left uses type="number". Right uses type="text" inputmode="numeric". Notice what breaks on the left.
| Data type | Best type | inputmode | Why |
|---|---|---|---|
| Quantity / count | number | — | Spinner makes sense, no leading zeros |
| Credit card | text | numeric | Preserves spaces, no spinners |
| ZIP / postal code | text | numeric | Keeps leading zeros (e.g. 02134) |
| OTP / PIN | text | numeric | Short code, no leading-zero loss |
| Price / decimal | text | decimal | Gets decimal key on mobile |
| Phone number | tel | — | Phone keypad with *, # keys |
email | — | Gets @ and .com keys on mobile | |
| Search | search | — | Submit key labeled "Search" on mobile |
| Website URL | url | — | Gets / and .com keys on mobile |
Interact with each field. The log shows the current value, type, and what keyboard would appear on mobile.
Use type="number" only when the value is a true mathematical quantity where incrementing makes sense.
Most tutorials use a <span> to show the range value. The correct semantic element is <output> — it has implicit role="status" for screen readers and connects to the input via for.
Select a check-in date. The checkout input enables with its minimum set to the next day. Change check-in and checkout updates accordingly.
Select an image. Preview appears instantly via URL.createObjectURL() — no FileReader, no base64, one line of code.
Color input always returns a 6-char hex value. Convert it to RGB or CSS custom properties on the fly.