Skip to content

Todo para WordPress, el desarrollo web — y mucho más

📱 Máscara de entrada de teléfono en JavaScript: 4 métodos con código

📱 Máscara de entrada de teléfono en JavaScript: 4 métodos con código

Los usuarios ingresan números de teléfono de muchas maneras: algunos empiezan con 8, otros con +7, algunos escriben los dígitos sin espacios, otros añaden espacios después de cada par de dígitos. La base de datos termina hecha un desastre. Los gestores pierden tiempo haciendo llamadas y la mitad de los números resultan estar mal. Un escenario familiar para cualquiera que haya añadido un formulario de contacto a un sitio web.

Una máscara de entrada resuelve este problema por completo: el usuario físicamente no puede ingresar un número en un formato incorrecto. Teclea los dígitos y estos aparecen automáticamente en los lugares correctos, mientras que los paréntesis y guiones se muestran solos. Sin errores, sin frustración.

A continuación, cuatro maneras de añadir una máscara de teléfono a un campo de entrada: desde HTML5 nativo sin nada de JavaScript hasta una biblioteca completa con banderas para cada país. Con código que puede copiar y pegar en su proyecto.

💡 Resumen rápido:

  • La máscara más simple usa el atributo pattern y type="tel", sin nada de JavaScript, funciona en cualquier navegador
  • Si necesita banderas de países y formato internacional, use intl-tel-input, la solución más popular en GitHub
  • Si necesita una biblioteca para teléfonos, fechas, tarjetas y cualquier otra máscara, opte por IMask.js
  • Si quiere escribir una máscara a mano sin añadir dependencias, JavaScript puro puede hacerlo en 30 líneas

Qué es una máscara de entrada y por qué importa más que la validación

Una máscara de entrada es una cadena de plantilla que controla lo que el usuario ve y puede teclear en un campo de formulario. A diferencia de la validación, que verifica los datos después del envío y muestra un error, una máscara funciona en tiempo real durante la entrada: impide teclear una letra donde debería ir un dígito e inserta automáticamente paréntesis, guiones y espacios.

La diferencia es fundamental. La validación dice «cometió un error» y el usuario ya está frustrado y podría irse. Una máscara lo guía paso a paso: los errores son simplemente imposibles. Para los números de teléfono esto es crítico porque hay docenas de opciones de formato. Solo un número ruso puede escribirse como +7 999 123-45-67, como 8(999)1234567 o como +7(999)123-45-67, y estas son solo tres variantes entre muchas. Sin una máscara, cada usuario inventa su propio formato y la base de datos se convierte en un montón de basura.

Método 1: HTML5, type="tel" y pattern

El camino más fácil: omita JavaScript por completo. Los navegadores modernos admiten type="tel" y el atributo pattern, que valida la entrada contra una expresión regular al enviar el formulario.

Añada el campo a su marcado. El código puede insertarse en cualquier plantilla HTML: Contact Form 7, un formulario nativo de WordPress o marcado personalizado.

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>

Analicemos qué está sucediendo aquí. type="tel" muestra un teclado numérico en dispositivos móviles en lugar del teclado normal, lo que hace más cómodo ingresar el teléfono. pattern establece una expresión regular que permite varias variantes: con o sin espacios, con o sin paréntesis alrededor del código de área. title muestra una sugerencia al pasar el cursor y required impide enviar el formulario con el campo vacío.

La ventaja: cero dependencias, funciona en cualquier navegador. Para una página de aterrizaje simple, esto es suficiente.

Pero esto no es una máscara verdadera. Los paréntesis y guiones no aparecen automáticamente; el usuario debe teclearlos manualmente. pattern solo se activa al enviar el formulario. Si necesita formato en tiempo real durante la entrada, pase a los siguientes métodos.

Método 2: intl-tel-input, formato internacional con banderas de países

intl-tel-input es la biblioteca JavaScript más popular para la entrada de teléfonos. Proporciona un campo con una lista desplegable de banderas de países, autoformato para ajustarse a la plantilla nacional y validación del número. A junio de 2026, la biblioteca tiene más de 7800 estrellas en GitHub y la versión actual es la 29.

Instale la biblioteca mediante npm (npm i intl-tel-input) o CDN. El código a continuación es para JavaScript vainilla; también hay componentes listos para usar para React, Vue, Angular y 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>

El elemento de entrada y la inicialización van en la plantilla donde necesite el campo. Para un tema de WordPress, añada el script mediante wp_enqueue_script en functions.php y coloque el marcado en la plantilla correspondiente.

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" establece la bandera rusa por defecto. separateDialCode: true mueve el código de país fuera del campo de entrada: cuando el usuario cambia la bandera, el código se inserta automáticamente. utilsScript carga utilidades de formato; sin ellas la biblioteca aún funciona, pero los números no se formatean para coincidir con el patrón del país seleccionado.

El objeto devuelto por intlTelInput() proporciona varios métodos útiles. iti.getNumber() devuelve el número en formato internacional E.164, iti.isValidNumber() verifica la validez y iti.setNumber("9991234567") establece el valor mediante programación. Para Contact Form 7 necesitará un script personalizado: busque el campo .wpcf7-tel y adjúntele intlTelInput.

Ventaja: una solución internacional completa con autoformato, banderas, validación e integraciones con frameworks. Desventaja: la biblioteca pesa alrededor de 40 KB (gzip), lo cual es excesivo para una página de aterrizaje simple con un solo campo.

Método 3: IMask.js, una máscara universal sin jQuery

IMask.js es una biblioteca de máscaras madura escrita en JavaScript puro: sin jQuery, sin otras dependencias. Admite máscaras para teléfonos, fechas, números, divisas y plantillas dinámicas. Resulta útil cuando necesita diferentes tipos de máscaras en un mismo sitio: un teléfono en un formulario de contacto, una fecha en un calendario y un importe en una calculadora. La versión actual es la 7.1.

Instale mediante npm (npm i imask) o incluya el CDN:

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

Una máscara de teléfono en tres líneas. El código puede ir en una etiqueta <script> en el pie de página o en un archivo JS separado en su tema.

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

Sintaxis de la máscara: +{7} es un prefijo fijo que el usuario no puede editar. 0 representa cualquier dígito del 0 al 9. Puede añadir complejidad: hacer que el código de área sea opcional o cambiar dinámicamente la máscara cuando el país cambie usando el parámetro dispatch.

IMask devuelve un objeto con acceso al valor bruto: maskRef.unmaskedValue le dará los dígitos simples 79991234567, exactamente lo que quiere guardar en la base de datos. El método maskRef.value devuelve la cadena formateada para mostrar. El problema clásico está resuelto: los dígitos van al backend, mientras que el usuario ve un número con un formato agradable.

Ventaja: una biblioteca para todos los casos, valores brutos listos para usar, sin dependencias. Desventaja: para un solo campo de teléfono es más fácil usar intl-tel-input con banderas; IMask realmente brilla en formularios con tres a cinco tipos de campo diferentes.

Método 4: JavaScript puro, una máscara hecha a mano

Si no quiere incluir una biblioteca para un solo campo, escriba la máscara en JavaScript puro. El código a continuación maneja cada pulsación de tecla e inserta automáticamente paréntesis y guiones a medida que se ingresan los dígitos.

Coloque el script en la misma plantilla donde se encuentra el campo de entrada o inclúyalo como un archivo separado. Para WordPress, use wp_enqueue_script con el indicador true (en el pie de página).

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});

El evento input se dispara ante cada cambio en el campo: pegado desde el portapapeles, autocorrección, eliminación. La primera línea replace(/\D/g, '') elimina todo excepto dígitos: las letras y caracteres especiales desaparecen instantáneamente. Luego, el script recorta los dígitos sobrantes (un número ruso tiene 11 dígitos incluyendo el código de país) y construye la cadena formateada: código de país +7, código de área de tres dígitos entre paréntesis, tres dígitos, dos, dos, separados por guiones.

Antes de usar esto en un sitio en vivo, añada dos mejoras. Primera: al eliminar dígitos en medio del número, el cursor puede saltar al final del campo; guarde la posición del cursor mediante selectionStart y restáurela después de formatear. Segunda: para números de otros países (Bielorrusia tiene 12 dígitos, Kazajistán tiene 11 dígitos con un código diferente) la lógica se vuelve más compleja y, en ese punto, intl-tel-input está plenamente justificado.

Ventaja: 30 líneas, control total, cero kilobytes de dependencias. Desventaja: la máscara está adaptada a un solo formato; para proyectos multipaís el código se hinchará.

⁉️🤔 Preguntas frecuentes

¿Por qué una máscara es mejor que una simple validación?

La validación se activa después del envío del formulario: el usuario ve un error y tiene que volver atrás y corregirlo. Una máscara funciona durante la entrada, haciendo que un formato inválido sea físicamente imposible. Menos frustración, menos formularios abandonados. Para los números de teléfono esto es crítico: los errores en el número son una de las razones más comunes por las que los usuarios abandonan un formulario.

¿Cómo guardo dígitos simples en la base de datos sin paréntesis ni guiones?

Todas las bibliotecas de este artículo proporcionan valores brutos: intl-tel-input tiene un método getNumber() que devuelve +79991234567, IMask.js tiene una propiedad unmaskedValue que devuelve 79991234567. Antes de enviar los datos al servidor, obtenga el valor bruto y guárdelo. Muestre la cadena formateada solo en la interfaz. En los formularios de WordPress, añada un campo oculto <input type="hidden" name="phone_raw"> y rellénelo mediante JavaScript antes del envío.

¿Funciona la máscara en dispositivos móviles?

Sí, los cuatro métodos funcionan correctamente en iOS y Android. type="tel" hace aparecer el teclado numérico, lo cual es conveniente. En Android antiguo (versiones inferiores a la 6) el evento input puede comportarse de manera diferente con la autocorrección; pruebe en dispositivos reales. intl-tel-input e IMask.js están probados por sus desarrolladores en navegadores móviles y no causan problemas.

¿Puedo usar una máscara con Contact Form 7?

CF7 genera campos con clases .wpcf7-tel. Escriba un script que encuentre este campo por selector y le adjunte intl-tel-input o IMask. Al enviar el formulario, CF7 toma el valor directamente del campo, por lo que la biblioteca debe tener tiempo de formatearlo previamente. Si usa valores brutos, intercepte el evento wpcf7submit y reemplace los datos en un campo oculto.

¿Qué debo hacer con números de diferentes países en el mismo sitio?

Use intl-tel-input: el usuario selecciona una bandera y la máscara cambia automáticamente para coincidir con el formato del país elegido. Para la geosegmentación puede establecer initialCountry: "auto" y la biblioteca detectará el país por IP mediante un servicio externo. Si solo hay dos o tres países y su presupuesto de dependencias es mínimo, escriba dos máscaras en JavaScript puro y alterne entre ellas con un botón de opción «Rusia / Kazajistán» encima del campo.

Qué método elegir para su tarea

La elección se reduce a tres preguntas: cuántos campos hay en el sitio, si necesita banderas de países y qué tan crítico es el tamaño del paquete.

Un único formulario simple en una página de aterrizaje: empiece con pattern de HTML5. Rápido, sin JavaScript y en el móvil el teclado cambia a numérico. Si el sitio acepta números internacionales, intl-tel-input lo cubrirá todo: banderas, autoformato, validación. Para una tienda en línea o un SaaS este es el estándar.

Varias máscaras diferentes en el sitio (teléfono, fecha, importe, tarjeta): IMask.js le dará una API única para todos los campos y no requiere jQuery. Si está construyendo un proyecto personal y quiere control total: 30 líneas de JavaScript puro manejarán números rusos sin una sola dependencia.

Pruebe cómo funciona la máscara en un sitio en vivo: ingrese un número con letras, pegue desde el portapapeles, intente eliminar un par de dígitos en el medio. El campo debe comportarse de manera predecible en cualquier escenario. ¿Qué método eligió para su proyecto? Compártalo en los comentarios.