March 14

Маска для номера телефона

Проблема стандартизации форматирования и валидации поля ввода номера телефона абсолютно не новая. Даже в MDN говорят о том, что <input type="tel"> в отличие от <input type="email"> не имеет никакой автоматической валидации, потому что "форматы телефонных номеров сильно раличаются по всему миру".

Решение, которое мы можем без труда соорудить стандартными средствами браузера, не используя дополнительных библиотек выглядит примерно так:

<div>
 <input
  type="tel"
  pattern="(^8|7|\+7)([0-9]{10})"
  required
 > 
</div>
<div>
 <small>Формат: +79999999999</small>
</div>

С таким решением мы будем строго принимать один обозначенный формат (пример сильно упрощён, более комплексный вариант регулярного выражения можно подглядеть тут) с общей подсказкой для пользователя, без маски для ввода. Как давно вы в последний раз видели поле ввода для номера телефона без маски?

Можно долго дискутировать о том, нужна ли маска для ввода в данном случае, но пользователи уже к этому привыкли и вы явно их не отучите, только добавите неудобств.

Вернёмся к основной теме. Без добавления JS-кода маску мы не получим. Можно поискать готовое решение, но с этим тоже есть проблема. Решения, которые сразу будут хорошо работать из коробки найти сложно. Довольно часто, многие из этих решений уже содержат в себе стилизацию, которую не всегда легко переделать под нужный дизайн.

На мой взгляд, всё, что должно быть в хорошем решении подобной задачи:

возможность управления паттерном форматирования, валидации;
отсутствие лишних зависимостей и любой стилизации, она должна поступать извне, либо легко кастомизироваться;
интернационализация.

Почти идеальным решением, на мой взгляд, является imask. Он предоставляет только функциональную часть с очень простыми API. К примеру, для российского номера телефона код будет выглядеть так:

IMask(
  document.getElementById('phone-mask'),
  {
    mask: '+{7}(000)000-00-00'
  }
)

Кроме прочего, решение имеет адаптацию под популярные веб-фреймворки (react, vue, angular, svelte) и даже неплохой задел на интернационализацию за счёт использования динамических масок. Пожалуй, единственным минусом этого решения является необходимость написания большого количества кода для более тонкой настройки. С другой стороны, это даёт возможность широкой кастомизации и позволяет менять паттерны и маски так, как вам требуется, не отнимая возможности стилизовать свои поля ввода так, как вы считаете нужным.