
📱 Masque de saisie de téléphone en JavaScript : 4 méthodes avec code
Les utilisateurs saisissent leur numéro de téléphone de toutes les manières possibles: certains commencent par un 8, d’autres par +7, certains tapent les chiffres sans espaces, d’autres ajoutent un espace après chaque paire de chiffres. La base de données se transforme en capharnaüm. Les équipes perdent du temps à passer des appels et la moitié des numéros s’avèrent inutilisables. Un scénario familier pour quiconque a déjà ajouté un formulaire de contact à un site web.
Un masque de saisie résout ce problème de manière radicale: l’utilisateur ne peut physiquement pas entrer un numéro dans un format incorrect. Il tape des chiffres, et ceux-ci apparaissent automatiquement aux bons emplacements, tandis que les parenthèses et les tirets s’affichent d’eux-mêmes. Aucune erreur, aucune frustration.
Voici quatre façons d’ajouter un masque de téléphone à un champ de saisie: de la solution native en HTML5 sans une ligne de JavaScript à une bibliothèque complète avec les drapeaux de chaque pays. Avec du code que vous pouvez copier et coller dans votre projet.
💡 Aperçu rapide:
- Le masque le plus simple utilise l’attribut
patternettype="tel", aucun JavaScript, fonctionne dans tous les navigateurs - Besoin de drapeaux et d’un formatage international, utilisez
intl-tel-input, la solution la plus populaire sur GitHub - Besoin d’une seule bibliothèque pour les téléphones, les dates, les cartes bancaires et tout autre masque, optez pour
IMask.js - Vous voulez écrire un masque à la main sans dépendance externe, le JavaScript vanilla peut le faire en 30 lignes
Qu’est-ce qu’un masque de saisie et pourquoi il est plus important que la validation
Un masque de saisie est une chaîne de caractères qui sert de gabarit et contrôle ce que l’utilisateur voit et peut taper dans un champ de formulaire. Contrairement à la validation, qui vérifie les données après l’envoi et affiche une erreur, un masque agit en temps réel pendant la saisie: il empêche de taper une lettre là où un chiffre est attendu et insère automatiquement les parenthèses, les tirets et les espaces.
La différence est fondamentale. La validation dit «vous avez fait une erreur», et l’utilisateur, déjà frustré, risque de quitter la page. Un masque le guide pas à pas: les erreurs sont tout simplement impossibles. Pour les numéros de téléphone, c’est critique car il existe des dizaines d’options de formatage. Rien qu’un numéro russe peut s’écrire +7 999 123-45-67, 8(999)1234567 ou +7(999)123-45-67, et ce ne sont que trois variantes parmi beaucoup d’autres. Sans masque, chaque utilisateur invente son propre format et la base de données devient un dépotoir.
Méthode 1: HTML5, type="tel" et pattern
La voie la plus simple: se passer totalement de JavaScript. Les navigateurs modernes prennent en charge type="tel" et l’attribut pattern, qui valide la saisie par rapport à une expression régulière lors de l’envoi du formulaire.
Ajoutez le champ à votre balisage. Le code peut être inséré dans n’importe quel template HTML: Contact Form 7, un formulaire natif WordPress ou un balisage personnalisé.
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="Enter the number in the format +7 (999) 123-45-67" 8 required 9 >
Voyons ce qui se passe ici. type="tel" affiche un clavier numérique sur les appareils mobiles au lieu du clavier standard, ce qui rend la saisie du numéro plus pratique. pattern définit une expression régulière qui autorise plusieurs variantes: avec ou sans espaces, avec ou sans parenthèses autour de l’indicatif régional. title affiche une infobulle au survol, et required empêche l’envoi du formulaire avec un champ vide.
L’avantage: zéro dépendance, fonctionne dans tous les navigateurs. Pour une simple page d’atterrissage, cela suffit.
Mais ce n’est pas un véritable masque. Les parenthèses et les tirets n’apparaissent pas automatiquement; l’utilisateur doit les taper manuellement. pattern ne se déclenche qu’à l’envoi du formulaire. Si vous avez besoin d’un formatage en temps réel pendant la saisie, passez aux méthodes suivantes.
Méthode 2: intl-tel-input, format international avec drapeaux
intl-tel-input est la bibliothèque JavaScript la plus populaire pour la saisie de numéros de téléphone. Elle fournit un champ avec une liste déroulante de drapeaux, un formatage automatique conforme au gabarit national et une validation du numéro. En juin 2026, la bibliothèque compte plus de 7 800 étoiles sur GitHub et la version actuelle est la 29.
Installez la bibliothèque via npm (npm i intl-tel-input) ou par CDN. Le code ci-dessous est pour du JavaScript vanilla; il existe également des composants prêts à l’emploi pour React, Vue, Angular et Svelte.
1 <!-- In the <head> of the page --> 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>
L’élément de saisie et l’initialisation se placent dans le template à l’endroit où vous avez besoin du champ. Pour un thème WordPress, ajoutez le script via wp_enqueue_script dans functions.php et placez le balisage dans le template approprié.
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" définit le drapeau russe par défaut. separateDialCode: true place l’indicatif pays à l’extérieur du champ de saisie: lorsque l’utilisateur change de drapeau, l’indicatif est inséré automatiquement. utilsScript charge les utilitaires de formatage; sans eux, la bibliothèque fonctionne toujours, mais les numéros ne sont pas formatés selon le modèle du pays sélectionné.
L’objet retourné par intlTelInput() fournit plusieurs méthodes utiles. iti.getNumber() renvoie le numéro au format international E.164, iti.isValidNumber() vérifie la validité et iti.setNumber("9991234567") définit la valeur par programmation. Pour Contact Form 7, vous aurez besoin d’un script personnalisé: trouvez le champ .wpcf7-tel et attachez-y intlTelInput.
Avantage: une solution internationale complète avec formatage automatique, drapeaux, validation et intégrations pour frameworks. Inconvénient: la bibliothèque pèse environ 40 Ko (gzip), ce qui est surdimensionné pour une simple page d’atterrissage avec un seul champ.
Méthode 3: IMask.js, un masque universel sans jQuery
IMask.js est une bibliothèque de masquage éprouvée, écrite en JavaScript vanilla: pas de jQuery, pas d’autre dépendance. Elle prend en charge les masques pour les téléphones, les dates, les nombres, les devises et les gabarits dynamiques. Elle s’avère utile lorsque vous avez besoin de différents types de masques sur un même site: un téléphone dans un formulaire de contact, une date dans un calendrier et un montant dans un calculateur. La version actuelle est la 7.1.
Installez via npm (npm i imask) ou incluez le CDN:
1 <script src="https://unpkg.com/imask"></script>
Un masque de téléphone en trois lignes. Le code peut être placé dans une balise <script> dans le pied de page ou dans un fichier JS séparé dans votre thème.
1 const phoneInput = document.getElementById('phone'); 2 const maskOptions = { 3 mask: '+{7} (000) 000-00-00' 4 }; 5 IMask(phoneInput, maskOptions);
Syntaxe du masque: +{7} est un préfixe fixe que l’utilisateur ne peut pas modifier. 0 représente n’importe quel chiffre de 0 à 9. Vous pouvez ajouter de la complexité: rendre l’indicatif régional optionnel ou changer dynamiquement le masque lorsque le pays change en utilisant le paramètre dispatch.
IMask retourne un objet donnant accès à la valeur brute: maskRef.unmaskedValue vous donnera les chiffres bruts 79991234567, exactement ce que vous voulez enregistrer en base de données. La méthode maskRef.value retourne la chaîne formatée pour l’affichage. Le problème classique est résolu: les chiffres partent vers le backend, tandis que l’utilisateur voit un numéro joliment formaté.
Avantage: une seule bibliothèque pour tous les cas, valeurs brutes disponibles immédiatement, aucune dépendance. Inconvénient: pour un seul champ téléphone, il est plus simple d’utiliser intl-tel-input avec les drapeaux; IMask brille vraiment sur les formulaires comportant trois à cinq types de champs différents.
Méthode 4: JavaScript vanilla, un masque fait main
Si vous ne voulez pas embarquer une bibliothèque pour un seul champ, écrivez le masque en JavaScript vanilla. Le code ci-dessous gère chaque frappe et insère automatiquement les parenthèses et les tirets au fur et à mesure de la saisie des chiffres.
Placez le script dans le même template que le champ de saisie, ou incluez-le comme fichier séparé. Pour WordPress, utilisez wp_enqueue_script avec le paramètre true (dans le pied de page).
1 document.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 });
L’événement input se déclenche à chaque modification du champ: collage depuis le presse-papiers, correction automatique, suppression. La première ligne replace(/\D/g, '') supprime tout ce qui n’est pas un chiffre: les lettres et les caractères spéciaux disparaissent instantanément. Ensuite, le script tronque les chiffres en trop (un numéro russe compte 11 chiffres, indicatif pays inclus) et construit la chaîne formatée: indicatif pays +7, indicatif régional à trois chiffres entre parenthèses, trois chiffres, deux, deux, séparés par des tirets.
Avant d’utiliser ceci sur un site en production, ajoutez deux améliorations. Premièrement: lors de la suppression de chiffres au milieu du numéro, le curseur peut sauter à la fin du champ; sauvegardez la position du curseur via selectionStart et restaurez-la après le formatage. Deuxièmement: pour les numéros d’autres pays (la Biélorussie a 12 chiffres, le Kazakhstan 11 chiffres avec un indicatif différent), la logique devient plus complexe, et à ce stade, intl-tel-input est pleinement justifié.
Avantage: 30 lignes, contrôle total, zéro kilo-octet de dépendance. Inconvénient: le masque est taillé pour un seul format; pour des projets multi-pays, le code va grossir.
⁉️🤔 Foire aux questions
Pourquoi un masque est-il meilleur qu’une simple validation?
La validation se déclenche après l’envoi du formulaire: l’utilisateur voit une erreur et doit revenir en arrière pour la corriger. Un masque agit pendant la saisie, rendant un format invalide physiquement impossible. Moins de frustration, moins d’abandons de formulaire. Pour les numéros de téléphone, c’est critique: les erreurs dans le numéro sont l’une des raisons les plus courantes pour lesquelles les utilisateurs abandonnent un formulaire.
Comment enregistrer les chiffres bruts en base de données, sans parenthèses ni tirets?
Toutes les bibliothèques de cet article fournissent des valeurs brutes:
intl-tel-inputa une méthodegetNumber()qui retourne+79991234567,IMask.jsa une propriétéunmaskedValuequi retourne79991234567. Avant d’envoyer les données au serveur, récupérez la valeur brute et enregistrez-la. N’affichez la chaîne formatée que dans l’interface. Dans les formulaires WordPress, ajoutez un champ caché<input type="hidden" name="phone_raw">et remplissez-le via JavaScript avant l’envoi.
Le masque fonctionne-t-il sur les appareils mobiles?
Oui, les quatre méthodes fonctionnent correctement sur iOS et Android.
type="tel"fait apparaître le clavier numérique, ce qui est pratique. Sur les anciens Android (versions inférieures à 6), l’événementinputpeut se comporter différemment avec la correction automatique; testez sur des appareils réels.intl-tel-inputetIMask.jssont testés par leurs développeurs sur les navigateurs mobiles et ne posent pas de problème.
Puis-je utiliser un masque avec Contact Form 7?
CF7 génère des champs avec les classes
.wpcf7-tel. Écrivez un script qui trouve ce champ par son sélecteur et y attacheintl-tel-inputouIMask. Lors de l’envoi du formulaire, CF7 récupère la valeur directement depuis le champ, la bibliothèque doit donc avoir le temps de la formater au préalable. Si vous utilisez des valeurs brutes, interceptez l’événementwpcf7submitet remplacez les données dans un champ caché.
Que faire avec des numéros de différents pays sur le même site?
Utilisez
intl-tel-input: l’utilisateur sélectionne un drapeau et le masque s’adapte automatiquement au format du pays choisi. Pour le géociblage, vous pouvez définirinitialCountry: "auto", et la bibliothèque détectera le pays par IP via un service externe. S’il n’y a que deux ou trois pays et que votre budget de dépendances est minimal, écrivez deux masques en JavaScript vanilla et basculez entre eux avec un bouton radio «Russie / Kazakhstan» au-dessus du champ.
Quelle méthode choisir pour votre projet
Le choix se résume à trois questions: combien de champs comporte le site, avez-vous besoin des drapeaux des pays et quel est le poids critique du bundle.
Un formulaire simple et unique sur une page d’atterrissage: commencez par le pattern HTML5. Rapide, sans JavaScript, et sur mobile, le clavier passe en mode numérique. Si le site accepte des numéros internationaux, intl-tel-input couvrira tout: drapeaux, formatage automatique, validation. Pour une boutique en ligne ou un SaaS, c’est la solution standard.
Plusieurs masques différents sur le site (téléphone, date, montant, carte bancaire): IMask.js vous offrira une API unique pour tous les champs et ne nécessite pas jQuery. Vous construisez un projet personnel et voulez un contrôle total: 30 lignes de JavaScript vanilla géreront les numéros russes sans aucune dépendance.
Testez le comportement du masque sur un site en production: saisissez un numéro avec des lettres, collez depuis le presse-papiers, essayez de supprimer quelques chiffres au milieu. Le champ doit se comporter de manière prévisible dans tous les scénarios. Quelle méthode avez-vous choisie pour votre projet? Partagez en commentaires.



