Skip to content

Все для WordPress, веб-розробки — і не тільки

📱 Маска телефону для input на JavaScript: 4 способи з кодом

📱 Маска телефону для input на JavaScript: 4 способи з кодом

Користувач вводить телефон як завгодно: хтось із вісімки, хтось із +7, хтось разом, хтось із пробілами після кожної пари цифр. У базу потрапляє мішанина. Менеджер витрачає час на обдзвін, а половина номерів, бита. Знайома картина для кожного, хто ставив форму зворотного зв'язку на сайт.

Маска введення закриває проблему повністю: користувач фізично не може ввести номер у неправильному форматі. Набирає цифри, вони самі підставляються в потрібні місця, дужки та дефіси з'являються автоматично. Жодних помилок, жодного роздратування.

Нижче, чотири способи додати маску телефону в input: від нативного HTML5 без жодного рядка JavaScript до готової бібліотеки з прапорами всіх країн. З кодом, який можна скопіювати та вставити у свій проєкт.

💡 Швидкий огляд:

  • Найпростіша маска через атрибут pattern і type="tel", жодного рядка JavaScript, працює в будь-якому браузері
  • Потрібні прапори країн і міжнародний формат, ставте intl-tel-input, найпопулярніше рішення на GitHub
  • Потрібна одна бібліотека для телефонів, дат, карток і будь-яких інших масок, беріть IMask.js
  • Хочете написати маску вручну і не тягнути залежностей, чистий JavaScript впорається за 30 рядків

Що таке маска введення і чому вона важливіша за валідацію

Маска введення, або input mask, — це рядок-шаблон, який керує тим, що бачить і може набрати користувач у полі форми. На відміну від валідації, яка перевіряє дані після надсилання та показує помилку, маска працює безпосередньо під час введення: не дає надрукувати літеру там, де має бути цифра, і сама розставляє дужки, дефіси та пробіли.

Різниця принципова. Валідація каже «ви помилилися», користувач уже роздратований і може піти. Маска веде за руку: помилка просто неможлива. Для телефону це критично, бо форматів запису десятки. Тільки російський номер можна написати як +7 999 123-45-67, як 8(999)1234567 або як +7(999)123-45-67, і це лише три варіанти з безлічі. Без маски кожен користувач винаходить свій формат, і база перетворюється на звалище.

Спосіб 1: HTML5, type="tel" і pattern

Найлегший шлях: обійтися без JavaScript взагалі. Сучасні браузери підтримують type="tel" та атрибут pattern, який перевіряє введення за регулярним виразом під час надсилання форми.

Додайте поле в розмітку. Код вставляється в будь-який HTML-шаблон: Contact Form 7, нативну форму WordPress або кастомне верстання.

1<input
2 type="tel"
3 id="phone"
4 name="phone"
5 pattern="\+7\s?[\(]?\d{3}[\)]?\s?\d{3}[\-]?\d{2}[\-]?\d{2}"
6 placeholder="+7 (999) 123-45-67"
7 title="Введите номер в формате +7 (999) 123-45-67"
8 required
9>

Розберімо, що тут відбувається. type="tel" на мобільних пристроях показує цифрову клавіатуру замість звичайної, вводити телефон одразу зручніше. pattern задає регулярний вираз, який дозволяє кілька варіантів: із пробілами та без, із дужками навколо коду оператора та без них. title показує підказку під час наведення, а required не дасть надіслати форму з порожнім полем.

Плюс підходу: нуль залежностей, працює в будь-якому браузері. Для простого лендингу цього достатньо.

Але це не справжня маска. Дужки та дефіси не з'являються автоматично, користувач має набрати їх сам. pattern спрацьовує лише під час надсилання форми. Якщо потрібне форматування безпосередньо під час введення, переходьте до наступних способів.

Спосіб 2: intl-tel-input, міжнародний формат із прапорами країн

intl-tel-input, найпопулярніша JavaScript-бібліотека для введення телефонів. Дає поле з випадним списком прапорів країн, автоформатуванням під національний шаблон і валідацією номера. Станом на червень 2026 бібліотека налічує понад 7 800 зірок на GitHub, актуальна версія, 29.

Підключіть бібліотеку через npm (npm i intl-tel-input) або CDN. Код нижче, для vanilla JavaScript; є також готові компоненти для React, Vue, Angular і Svelte.

1<!-- В <head> страницы -->
2<link
3 rel="stylesheet"
4 href="https://cdn.jsdelivr.net/npm/intl-tel-input@29/build/css/intlTelInput.css"
5>
6<script src="https://cdn.jsdelivr.net/npm/intl-tel-input@29/build/js/intlTelInput.min.js"></script>

Сам input та ініціалізація, у тому місці шаблону, де потрібне поле. Для WordPress-теми додайте скрипт через wp_enqueue_script у functions.php, а розмітку, у потрібний шаблон.

1<input type="tel" id="phone">
2
3<script>
4 const input = document.querySelector("#phone");
5 const iti = intlTelInput(input, {
6 initialCountry: "ru",
7 separateDialCode: true,
8 utilsScript: "https://cdn.jsdelivr.net/npm/intl-tel-input@29/build/js/utils.js"
9 });
10</script>

initialCountry: "ru" ставить російський прапор за замовчуванням. separateDialCode: true виносить код країни за межі поля введення: користувач змінює прапор, код підставляється сам. utilsScript підвантажує утиліти форматування, без них бібліотека працює, але номери не форматуються під маску вибраної країни.

Об'єкт, який повертає intlTelInput(), дає кілька корисних методів. iti.getNumber() віддає номер у міжнародному форматі E.164, iti.isValidNumber() перевіряє коректність, iti.setNumber("9991234567") програмно встановлює значення. Для Contact Form 7 знадобиться кастомний скрипт: знаходите поле .wpcf7-tel і вішаєте на нього intlTelInput.

Плюс: повноцінне міжнародне рішення, автоформат, прапори, валідація, інтеграції з фреймворками. Мінус: бібліотека важить близько 40 КБ (gzip), і для простого лендингу з одним полем це забагато.

Спосіб 3: IMask.js, універсальна маска без jQuery

IMask.js, зріла бібліотека масок на чистому JavaScript: ні jQuery, ні інших залежностей. Підтримує маски для телефонів, дат, чисел, валют і динамічні шаблони. Зручна, коли на одному сайті потрібні різні типи масок: телефон у формі зворотного зв'язку, дата в календарі та сума в калькуляторі. Актуальна версія, 7.1.

Встановіть через npm (npm i imask) або підключіть CDN:

1<script src="https://unpkg.com/imask"></script>

Маска телефону в три рядки. Код можна розмістити в <script> у футері або в окремому JS-файлі теми.

1const phoneInput = document.getElementById('phone');
2const maskOptions = {
3 mask: '+{7} (000) 000-00-00'
4};
5IMask(phoneInput, maskOptions);

Синтаксис маски: +{7}, фіксований префікс, не редагується користувачем. 0, будь-яка цифра від 0 до 9. Можна ускладнити: зробити код оператора опціональним або динамічно змінювати маску під час зміни країни через параметр dispatch.

IMask повертає об'єкт із доступом до сирого значення: maskRef.unmaskedValue віддасть чисті цифри 79991234567, саме те, що потрібно зберігати в базу. Метод maskRef.value поверне форматований рядок для відображення. Класичну проблему вирішено: на бекенд летять цифри, а користувач бачить гарний номер.

Плюс: одна бібліотека на всі випадки, чисті значення з коробки, немає залежностей. Мінус: для одного телефонного поля простіше взяти intl-tel-input із прапорами, IMask розкривається на формах із трьома-п'ятьма різними типами полів.

Спосіб 4: чистий JavaScript, маска своїми руками

Якщо не хочете тягнути бібліотеку заради одного поля, напишіть маску на чистому JavaScript. Код нижче обробляє кожне натискання й автоматично вставляє дужки та дефіси в міру введення цифр.

Скрипт розміщується в тому ж шаблоні, де знаходиться поле введення, або підключається окремим файлом. Для WordPress, через wp_enqueue_script із прапором true (у футері).

1document.getElementById('phone').addEventListener('input', function (e) {
2 let value = e.target.value.replace(/\D/g, '');
3
4 if (value.length > 11) {
5 value = value.slice(0, 11);
6 }
7
8 let formatted = '+7 (';
9 if (value.length > 1) formatted += value.slice(1, 4);
10 if (value.length > 4) formatted += ') ' + value.slice(4, 7);
11 if (value.length > 7) formatted += '-' + value.slice(7, 9);
12 if (value.length > 9) formatted += '-' + value.slice(9, 11);
13
14 e.target.value = formatted;
15});

Подія input спрацьовує за кожної зміни поля: вставка з буфера, автовиправлення, видалення. Перший рядок replace(/\D/g, '') вирізає все, крім цифр: літери та спецсимволи зникають миттєво. Потім скрипт відсікає зайві цифри (російський номер, 11 знаків із кодом країни) і збирає форматований рядок: код країни +7, три цифри коду оператора в дужках, три цифри номера, дві, дві, через дефіси.

Перед використанням на реальному сайті додайте два доопрацювання. Перше: під час видалення цифр усередині номера курсор може стрибати в кінець поля, зберігайте позицію каретки через selectionStart і відновлюйте після форматування. Друге: для номерів інших країн (Білорусь, 12 цифр, Казахстан, 11 цифр з іншим кодом) логіка ускладнюється, і тоді intl-tel-input повністю виправданий.

Плюс: 30 рядків, повний контроль, жодного кілобайта залежностей. Мінус: маска заточена під один формат, для мультикраїнних проєктів код розпухне.

⁉️🤔 Часті запитання

Чим маска краща за просту валідацію?

Валідація спрацьовує після надсилання форми: користувач бачить помилку та повертається виправляти. Маска працює під час введення, неправильний формат фізично неможливий. Менше роздратування, менше відмов від надсилання. Для телефону це критично: помилки в номері, одна з найчастіших причин, через які користувачі кидають форму.

Як зберігати в базу чисті цифри без дужок і дефісів?

Усі бібліотеки зі статті віддають сире значення: у intl-tel-input метод getNumber() повертає +79991234567, у IMask.js властивість unmaskedValue, 79991234567. Перед надсиланням на сервер беріть чисте значення та зберігайте його. Форматований рядок показуйте лише в інтерфейсі. У WordPress-формах додайте приховане поле <input type="hidden" name="phone_raw"> і заповнюйте його через JavaScript перед надсиланням.

Чи працює маска на мобільних пристроях?

Так, усі чотири способи коректно працюють на iOS і Android. type="tel" викликає цифрову клавіатуру — це зручно. На старих Android (версії нижче 6) подія input може поводитися інакше під час автозаміни, протестуйте на реальних пристроях. intl-tel-input та IMask.js тестуються розробниками на мобільних браузерах і проблем не створюють.

Чи можна використовувати маску в Contact Form 7?

CF7 генерує поля з класами .wpcf7-tel. Напишіть скрипт, який знаходить це поле за селектором і вішає на нього intl-tel-input або IMask. Під час надсилання форми CF7 бере значення безпосередньо з поля, бібліотека має встигнути відформатувати його до цього. Якщо використовуєте чисті значення, перехопіть подію wpcf7submit і підмініть дані в прихованому полі.

Що робити з номерами різних країн на одному сайті?

Беріть intl-tel-input: користувач вибирає прапор, маска автоматично перемикається під формат вибраної країни. Для геотаргетингу можна задати initialCountry: "auto", бібліотека визначить країну за IP через зовнішній сервіс. Якщо країн дві-три і бюджет на залежності мінімальний, напишіть дві маски на чистому JavaScript і перемикайте їх радіокнопкою «Росія / Казахстан» над полем.

Який спосіб обрати під вашу задачу

Вибір зводиться до трьох запитань: скільки полів на сайті, чи потрібні прапори країн і наскільки критичний розмір бандла.

Одна проста форма на лендингу, почніть із HTML5 pattern. Швидко, без JavaScript, на мобільних клавіатура перемикається на цифрову. Сайт приймає міжнародні номери, intl-tel-input закриє питання повністю: прапори, автоформат, валідація. Для інтернет-магазину або SaaS це стандарт.

Кілька різних масок на сайті (телефон, дата, сума, картка), IMask.js дасть один API під усі поля і не тягне jQuery. Робите pet-проєкт і хочете повний контроль, 30 рядків на чистому JavaScript вирішать задачу для російських номерів без жодної залежності.

Перевірте роботу маски на живому сайті: вбийте номер із літерами, вставте з буфера, спробуйте стерти пару цифр усередині. Поле має поводитися передбачувано в будь-якому сценарії. Який спосіб обрали для свого проєкту, напишіть у коментарях.