Что такое маска ввода — и почему она чаще мешает, чем помогает

Маска ввода выглядит как забота. Человек печатает цифры — а скобки, пробелы и дефисы появляются сами, будто поле знает, чего хочет.
А теперь неожиданное: маска не проверяет ничего. Она только печатает символы за тебя. И ломает ровно то, чем люди пользуются чаще всего — вставку из буфера обмена.
Что такое маска ввода
Маска (input mask) — это шаблон, по которому поле само форматирует то, что в него вводят. Обычно её задают строкой вроде +7 (999) 999-99-99: девятки — места под цифры, остальное поле подставляет само, пока человек печатает.
Маски вешают на телефоны, карты, даты, ИНН, индексы. Логика понятная: раз формат известен заранее — пусть поле его и держит.
В HTML маски нет. Это всегда чужой JavaScript: библиотека или кусок кода, который слушает каждое нажатие и переписывает содержимое поля. Отсюда и все проблемы — поле перестаёт быть обычным полем.
Маска — это не проверка
Тут главная путаница. Маска формирует вид строки, а не её смысл. +7 (000) 000-00-00 идеально ложится в маску и не является телефоном. Маска промолчит.
Проверка — это отдельная работа, и делать её всё равно придётся на сервере: клиентский код можно обойти, а JavaScript — просто не загрузиться.
Рядом живут два штатных атрибута, которых обычно и не хватает:
inputmode— подсказывает телефону, какую клавиатуру показать:numeric,decimal,tel,email,url. MDN подчёркивает отдельно: этот атрибут «не накладывает никаких требований к валидности ввода». Только клавиатура.pattern— а вот он уже проверяет: регулярка, которой должно соответствовать значение, иначе браузер не отправит форму.
То есть «удобную цифровую клавиатуру» даёт inputmode, а не маска, и стоит это одну строчку.
Где маска ломается
Три сценария, которые ловит любой, кто пробовал маски в бою:
- Вставка из буфера. Человек копирует номер из переписки — с плюсом, скобками, неразрывным пробелом. Маска видит «лишние» символы и либо режет номер, либо отказывается принимать вставку целиком.
- Чужие форматы. Маска под один формат — это неявное «мы не обслуживаем остальных». Дизайн-система GOV.UK по телефонам говорит прямо: разрешай вводить номер в любом привычном человеку виде — с пробелами, дефисами, скобками, с кодом страны. То же самое у них и про номер банковской карты.
- Курсор и Backspace. Маска постоянно переписывает значение поля, и каретка прыгает: стираешь цифру — уезжаешь за скобку, вставляешь в середину — попадаешь не туда. На телефоне это особенно больно.
Есть и четвёртый, менее очевидный: маска мешает автозаполнению. Браузер подставляет сохранённый номер целиком, а скрипт маски тут же начинает его «исправлять».
Что делать вместо маски
Рабочий подход — принимать что угодно и чистить у себя:
- Поставь правильный
typeиinputmode.type="tel"плюсinputmode="tel"— и на телефоне открывается цифровая клавиатура. Никакого JavaScript. - Разреши лишние символы. GOV.UK советует не ругаться на пробелы, дефисы, скобки и точки, а молча их игнорировать — особенно в номерах и кодах. Отдельно они отмечают, что мусорные символы часто прилетают из копипасты и из диктовки, то есть человек в них не виноват.
- Нормализуй перед проверкой. Одна строчка убирает всё лишнее:
const digits = value.replace(/\D/g, "");
- Проверяй уже очищенное. Длина, код страны, контрольная сумма — по цифрам, а не по красивой строке.
- Форматируй при показе, а не при вводе. В подтверждении и в письме выводи
+7 999 123-45-67— там это никому не мешает.
Проверить свою форму можно за минуту, без всяких инструментов. Возьми номер из мессенджера — вместе со скобками и плюсом — и вставь в поле. Потом поставь курсор в середину и сотри одну цифру. Если после этого в поле каша или часть номера исчезла, маску пора снимать. Тот же тест прогоняй на телефоне: на десктопе многие маски ведут себя прилично, а на экранной клавиатуре разваливаются.
Что получится: человек вставляет номер как есть, из любого мессенджера, и форма его принимает. Ты хранишь чистые цифры — их удобно сравнивать и искать. А сообщение об ошибке появляется только там, где данные действительно нельзя использовать.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.
Значит, маски нельзя использовать вообще никогда?
Можно — там, где формат жёсткий, короткий и общий для всех: время 12:30, срок действия карты 09/29. Но даже тогда оставь возможность вставить значение из буфера и проверяй результат отдельно.
Чем inputmode отличается от type?
type меняет поведение поля (type="email" умеет проверять адрес, type="number" — крутилки со стрелками). inputmode не меняет ничего, кроме экранной клавиатуры. Их спокойно ставят вместе, а поле при этом остаётся текстовым — значит, вставка из буфера работает.





