dont avoid html iphone zoom mobile-safari html-input

html - avoid - Deshabilitar el zoom automático en la etiqueta de entrada "Texto"-Safari en iPhone



input zoom mobile (28)

Agregue user-scalable = 0 a viewport meta como sigue

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">

Trabajó para mi :)

Hice una página HTML que tiene una etiqueta <input> con type="text" . Cuando hago clic en él con Safari en iPhone, la página se hace más grande (zoom automático). ¿Alguien sabe como deshabilitar esto?


Aquí hay un hack que utilicé en uno de mis proyectos:

select { font-size: 2.6rem; // 1rem = 10px ... transform-origin: ... ...; transform: scale(0.5) ...; }

Terminé con los estilos iniciales y la escala que quería pero sin enfoque de zoom.


Basado en la respuesta de Stephen Walsh ... Este código funciona sin cambiar el tamaño de fuente de las entradas en el foco (que parece poco convincente), y además funciona con FastClick , que sugiero agregar a todos los sitios móviles para ayudar a llevar el "rápido". Ajuste el "ancho de la ventana gráfica" para que se adapte a sus necesidades.

// disable autozoom when input is focused var $viewportMeta = $(''head > meta[name="viewport"]''); $(''input, select, textarea'').bind(''touchend'', function(event) { $viewportMeta.attr(''content'', ''width=640, user-scalable=0''); setTimeout(function(){ $viewportMeta.attr(''content'', ''width=640, user-scalable=1''); }, 1) });


Como el acercamiento automático (sin alejamiento) sigue siendo una anulación en el iPhone, aquí hay un JavaScript basado en la sugerencia de dlo que funciona con enfoque / desenfoque.

El zoom se desactiva tan pronto como la entrada de texto se enfoca y se vuelve a activar cuando se deja la entrada.

Nota: ¡ Algunos usuarios pueden no aceptar la edición de textos en una entrada de texto pequeña! Por lo tanto, personalmente prefiero cambiar el tamaño del texto de la entrada durante la edición (ver código a continuación).

<script type="text/javascript"> <!-- function attachEvent(element, evtId, handler) { if (element.addEventListener) { element.addEventListener(evtId, handler, false); } else if (element.attachEvent) { var ieEvtId = "on"+evtId; element.attachEvent(ieEvtId, handler); } else { var legEvtId = "on"+evtId; element[legEvtId] = handler; } } function onBeforeZoom(evt) { var viewportmeta = document.querySelector(''meta[name="viewport"]''); if (viewportmeta) { viewportmeta.content = "user-scalable=0"; } } function onAfterZoom(evt) { var viewportmeta = document.querySelector(''meta[name="viewport"]''); if (viewportmeta) { viewportmeta.content = "width=device-width, user-scalable=1"; } } function disableZoom() { // Search all relevant input elements and attach zoom-events var inputs = document.getElementsByTagName("input"); for (var i=0; i<inputs.length; i++) { attachEvent(inputs[i], "focus", onBeforeZoom); attachEvent(inputs[i], "blur", onAfterZoom); } } if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) { attachEvent(window, "load", disableZoom); } // --> </script>

El siguiente código cambiará el tamaño del texto de una entrada a 16 píxeles (calculado, es decir, en el tamaño de zoom actual) durante el elemento que tiene el enfoque. Por lo tanto, el iPhone no hará zoom automáticamente.

Nota: El factor de zoom se calcula en función de la visualización de window.innerWidth y iPhone con 320 píxeles. Esto solo será válido para iPhone en modo retrato.

<script type="text/javascript"> <!-- function attachEvent(element, evtId, handler) { if (element.addEventListener) { element.addEventListener(evtId, handler, false); } else if (element.attachEvent) { var ieEvtId = "on"+evtId; element.attachEvent(ieEvtId, handler); } else { var legEvtId = "on"+evtId; element[legEvtId] = handler; } } function getSender(evt, local) { if (!evt) { evt = window.event; } var sender; if (evt.srcElement) { sender = evt.srcElement; } else { sender = local; } return sender; } function onBeforeZoom(evt) { var zoom = 320 / window.innerWidth; var element = getSender(evt); element.style.fontSize = Math.ceil(16 / zoom) + "px"; } function onAfterZoom(evt) { var element = getSender(evt); element.style.fontSize = ""; } function disableZoom() { // Search all relevant input elements and attach zoom-events var inputs = document.getElementsByTagName("input"); for (var i=0; i<inputs.length; i++) { attachEvent(inputs[i], "focus", onBeforeZoom); attachEvent(inputs[i], "blur", onAfterZoom); } } if (navigator.userAgent.match(/iPhone/i)) { attachEvent(window, "load", disableZoom); } // --> </script>


Después de leer casi todas las líneas aquí y probar las distintas soluciones, esto es, gracias a todos los que compartieron sus soluciones, lo que se me ocurrió, probé y trabajé para mí en iPhone 7 iOS 10.x:

@media screen and (-webkit-min-device-pixel-ratio:0) { input[type="email"]:hover, input[type="number"]:hover, input[type="search"]:hover, input[type="text"]:hover, input[type="tel"]:hover, input[type="url"]:hover, input[type="password"]:hover, textarea:hover, select:hover{font-size: initial;} } @media (min-width: 768px) { input[type="email"]:hover, input[type="number"]:hover, input[type="search"]:hover, input[type="text"]:hover, input[type="tel"]:hover, input[type="url"]:hover, input[type="password"]:hover, textarea:hover, select:hover{font-size: inherit;} }

Sin embargo, tiene algunos inconvenientes, notablemente un "salto" como resultado del cambio rápido en el tamaño de la fuente que se produce entre los estados de "desplazamiento" y "enfoque", y el impacto de redibujado en el rendimiento


Después de un rato de intentarlo, se me ocurrió esta solución.

// set font-size to 16px to prevent zoom input.addEventListener("mousedown", function (e) { e.target.style.fontSize = "16px"; }); // change font-size back to its initial value so the design will not break input.addEventListener("focus", function (e) { e.target.style.fontSize = ""; });

En "mousedown" establece el tamaño de fuente de entrada a 16px. Esto evitará el zoom. En el evento de enfoque, cambia el tamaño de fuente de nuevo al valor inicial.

A diferencia de las soluciones publicadas anteriormente, esto le permitirá establecer el tamaño de fuente de la entrada en lo que desee.


El navegador hará zoom si el tamaño de la fuente es inferior a 16px y el tamaño de fuente predeterminado para los elementos del formulario es de 11px (al menos en Chrome y Safari).

Además, el elemento de select debe tener el focus pseudo-clase adjunto.

input[type="color"], input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"], select:focus, textarea { font-size: 16px; }

No es necesario usar todo lo anterior, solo puede diseñar los elementos que necesita, por ejemplo: solo text , number y área de textarea :

input[type=''text''], input[type=''number''], textarea { font-size: 16px; }

Solución alternativa para que los elementos de entrada se hereden de un estilo principal:

body { font-size: 16px; } input[type="text"] { font-size: inherit; }


En lugar de simplemente establecer el tamaño de fuente a 16px, puede:

  1. Diseñe el campo de entrada para que sea más grande que su tamaño deseado, permitiendo que el tamaño de fuente lógica se establezca en 16px.
  2. Use la transformación CSS scale() y los márgenes negativos para reducir el campo de entrada al tamaño correcto.

Por ejemplo, supongamos que su campo de entrada está originalmente diseñado con:

input[type="text"] { border-radius: 5px; font-size: 12px; line-height: 20px; padding: 5px; width: 100%; }

Si amplía el campo aumentando todas las dimensiones en 16/12 = 133.33%, luego reduzca el uso scale()en 12/16 = 75%, el campo de entrada tendrá el tamaño visual correcto (y el tamaño de fuente), y no habrá zoom en atención.

Como scale()solo afecta el tamaño visual, también deberá agregar márgenes negativos para reducir el tamaño lógico del campo.

Con este CSS:

input[type="text"] { /* enlarge by 16/12 = 133.33% */ border-radius: 6.666666667px; font-size: 16px; line-height: 26.666666667px; padding: 6.666666667px; width: 133.333333333%; /* scale down by 12/16 = 75% */ transform: scale(0.75); transform-origin: left top; /* remove extra white space */ margin-bottom: -10px; margin-right: -33.333333333%; }

el campo de entrada tendrá un tamaño de fuente lógico de 16px mientras que parece tener texto de 12px.

Tengo una publicación en el blog en la que profundizo un poco más, y tengo este ejemplo como HTML visible:
No hay zoom de entrada en Safari en iPhone, la manera perfecta de píxeles


En resumen, la respuesta es: establezca el tamaño de fuente de los elementos del formulario en al menos 16 px


Establecer un tamaño de fuente (para los campos de entrada) igual al tamaño de fuente del cuerpo, parece ser lo que impide que el navegador se acerque o hacia dentro. Yo sugeriría usar font-size: 1rem como una solución más elegante.


Esto funcionó para mí:

input, textarea { font-size: initial; }


Hace poco (hoy: D) tuve que integrar este comportamiento. Para no afectar los campos de diseño original, incluido el combo, opté por aplicar la transformación en el foco del campo:

input[type="text"]:focus, input[type="password"]:focus, textarea:focus, select:focus { font-size: 16px; }


He tenido que "arreglar" el zoom automático en el problema de controles de formulario para un sitio web de la Universidad Holandesa (que usaba 15px en los controles de formulario) Se me ocurrió el siguiente conjunto de requisitos:

  • el usuario todavía debe poder acercarse
  • el tamaño de fuente debe permanecer igual
  • No hay flashes de diferentes estilos temporales.
  • sin requisito de jQuery
  • debe funcionar en el nuevo iOS y no obstaculizar ninguna otra combinación de SO / dispositivo
  • si es posible, no hay tiempos de espera mágicos, y si es necesario borrar los temporizadores correctamente

Esto es lo que se me ocurrió hasta ahora:

/* NOTE: This code overrides the viewport settings, an improvement would be to take the original value and only add or change the user-scalable value */ // optionally only activate for iOS (done because I havn''t tested the effect under other OS/devices combinations such as Android) var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform) if (iOS) preventZoomOnFocus(); function preventZoomOnFocus() { document.documentElement.addEventListener("touchstart", onTouchStart); document.documentElement.addEventListener("focusin", onFocusIn); } let dont_disable_for = ["checkbox", "radio", "file", "button", "image", "submit", "reset", "hidden"]; //let disable_for = ["text", "search", "password", "email", "tel", "url", "number", "date", "datetime-local", "month", "year", "color"]; function onTouchStart(evt) { let tn = evt.target.tagName; // No need to do anything if the initial target isn''t a known element // which will cause a zoom upon receiving focus if ( tn != "SELECT" && tn != "TEXTAREA" && (tn != "INPUT" || dont_disable_for.indexOf(evt.target.getAttribute("type")) > -1) ) return; // disable zoom setViewport("width=device-width, initial-scale=1.0, user-scalable=0"); } // NOTE: for now assuming this focusIn is caused by user interaction function onFocusIn(evt) { // reenable zoom setViewport("width=device-width, initial-scale=1.0, user-scalable=1"); } // add or update the <meta name="viewport"> element function setViewport(newvalue) { let vpnode = document.documentElement.querySelector(''head meta[name="viewport"]''); if (vpnode) vpnode.setAttribute("content",newvalue); else { vpnode = document.createElement("meta"); vpnode.setAttribute("name", "viewport"); vpnode.setAttribute("content", newvalue); } }

Algunas notas:

  • Tenga en cuenta que hasta ahora solo lo he probado en iOS 11.3.1, pero lo probaré en algunas otras versiones pronto
  • El uso de eventos focusIn significa que requiere al menos iOS 5.1 (pero veo que los sitios que construimos funcionan en versiones de iOS anteriores a 9 como un bono genial de todos modos)
  • Uso de la delegación de eventos porque muchos de los sitios en los que trabajo tienen páginas que podrían crear controles de formulario dinámicamente
  • Configuración de los EventListeners en el elemento html (documentElement) para no tener que esperar a que el cuerpo esté disponible (no quiero molestar en comprobar si el documento está listo / cargado o tener que esperar el evento DOMContentLoaded)

Hice esto, también con jQuery:

$(''input[type=search]'').on(''focus'', function(){ // replace CSS font-size with 16px to disable auto zoom on iOS $(this).data(''fontSize'', $(this).css(''font-size'')).css(''font-size'', ''16px''); }).on(''blur'', function(){ // put back the CSS font-size $(this).css(''font-size'', $(this).data(''fontSize'')); });

Por supuesto, algunos otros elementos en la interfaz deben adaptarse si este 16px fuente de 16px rompe el diseño.


JavaScript hack que funciona en iOS 7. Esto se basa en la respuesta de @dlo, pero los eventos de mouseover y mouseout son reemplazados por touchstart y touchend. Básicamente, esta secuencia de comandos agrega un tiempo de espera de medio segundo antes de que el zoom se habilite nuevamente para evitar el zoom.

$("input[type=text], textarea").on({ ''touchstart'' : function() { zoomDisable(); }}); $("input[type=text], textarea").on({ ''touchend'' : function() { setTimeout(zoomEnable, 500); }}); function zoomDisable(){ $(''head meta[name=viewport]'').remove(); $(''head'').prepend(''<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0" />''); } function zoomEnable(){ $(''head meta[name=viewport]'').remove(); $(''head'').prepend(''<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=1" />''); }


La forma correcta de solucionar este problema es cambiar la vista meta a:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>


Me tomó un tiempo encontrarlo, pero aquí está el mejor código que encontré ...... http://nerd.vasilis.nl/prevent-ios-from-zooming-onfocus/

var $viewportMeta = $(''meta[name="viewport"]''); $(''input, select, textarea'').bind(''focus blur'', function(event) { $viewportMeta.attr(''content'', ''width=device-width,initial-scale=1,maximum-scale='' + (event.type == ''blur'' ? 10 : 1)); });


No hay una forma limpia que pueda encontrar, pero aquí hay un truco ...

1) Noté que el evento de mouseover ocurre antes del zoom, pero el zoom ocurre antes de los eventos de ratón o enfoque.

2) Puede cambiar dinámicamente la etiqueta de la vista META usando javascript (consulte ¿ Habilitar / deshabilitar el zoom en el safari del iPhone con Javascript? )

Por lo tanto, intente esto (se muestra en jquery para la compacidad):

$("input[type=text], textarea").mouseover(zoomDisable).mousedown(zoomEnable); function zoomDisable(){ $(''head meta[name=viewport]'').remove(); $(''head'').prepend(''<meta name="viewport" content="user-scalable=0" />''); } function zoomEnable(){ $(''head meta[name=viewport]'').remove(); $(''head'').prepend(''<meta name="viewport" content="user-scalable=1" />''); }

Esto es definitivamente un hackeo ... puede haber situaciones en las que el mouseover / abajo no siempre atrapa entradas / salidas, pero funcionó bien en mis pruebas y es un buen comienzo.


Por cierto, si usa Bootstrap , puede usar esta variante:

.form-control { font-size: 16px; }


Puede evitar que Safari se acerque automáticamente a los campos de texto durante la entrada del usuario sin desactivar la capacidad del usuario para pellizcar el zoom. Solo agregue maximum-scale=1 pero deje de lado el atributo de escala de usuario sugerido en otras respuestas.

Es una opción que vale la pena si tiene un formulario en una capa que "flota" alrededor si se amplía, lo que puede hacer que elementos importantes de la interfaz de usuario se muevan fuera de la pantalla.

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">


Si su sitio web está diseñado adecuadamente para un dispositivo móvil, podría decidir no permitir el escalado.

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

Esto resuelve el problema que su página o formulario móvil va a ''flotar'' alrededor.


Un comentario para la respuesta principal sobre la configuración del tamaño de fuente en 16px preguntó cómo es una solución, y si desea una fuente más grande / más pequeña.

No sé de todos ustedes, pero usar px para tamaños de fuente no es la mejor manera de hacerlo, debería usar em.

Me encontré con este problema en mi sitio sensible donde mi campo de texto tiene más de 16 píxeles. Tenía mi contenedor de formularios configurado en 2rem y mi campo de entrada establecido en 1.4em. En mis consultas móviles, cambio el tamaño de fuente html según la ventana gráfica. Dado que el html predeterminado es 10, mi campo de entrada se calcula a 28px en el escritorio

Para eliminar el zoom automático tuve que cambiar mi entrada a 1.6em. Esto aumentó mi tamaño de fuente a 32px. Solo un poco más alto y apenas perceptible. En mi iPhone 4 y 5 cambio mi tamaño de fuente html a 15px para vertical y de vuelta a 10px para horizontal. Parecía que el punto óptimo para ese tamaño de píxel era 48 px, por lo que cambié de 1.4em (42px) a 1.6em (48px).

Lo que debe hacer es encontrar el punto óptimo en el tamaño de fuente y luego convertirlo hacia atrás en sus tamaños rem / em.


Usé la solución de Christina anterior, pero con una pequeña modificación para la rutina de carga y otra regla para aplicar a las computadoras de escritorio. El tamaño de fuente predeterminado de Bootstrap es 14px, lo que causa el zoom. Lo siguiente lo cambia a 16px para "controles de formulario" en Bootstrap, impidiendo el zoom.

@media screen and (-webkit-min-device-pixel-ratio:0) { .form-control { font-size: 16px; } }

Y volver a 14px para navegadores no móviles.

@media (min-width: 768px) { .form-control { font-size: 14px; } }

Intenté usar .form-control: focus, que lo dejó en 14px, excepto en focus, que lo cambió a 16px y no solucionó el problema del zoom con iOS8. Al menos en mi iPhone con iOS8, el tamaño de fuente debe ser 16px antes de enfocarse para que el iPhone no haga zoom en la página.


Veo que la gente aquí hace cosas extrañas con JavaScript o la función de ventana gráfica y apaga todo el zoom manual en los dispositivos. Eso no debería ser una solución en mi opinión. Al agregar este fragmento de CSS, se desactivará el zoom automático en iOS sin cambiar el tamaño de la fuente a un número fijo como 16px.

De forma predeterminada, uso un tamaño de fuente de 93.8% (15px) en los campos de entrada y al agregar mi fragmento de código CSS se mantiene en 93.8%. No es necesario cambiar a 16px o convertirlo en un número fijo.

input[type="text"]:focus, textarea:focus { -webkit-text-size-adjust: 100%; }


¡¡¡ES TRABAJO!!! ¡TERMINO MI VIAJE DE BÚSQUEDA!

<meta name="viewport" content="width=640px, initial-scale=.5, maximum-scale=.5" />

Probado en iPhone OS6 , Android 2.3.3 Emulator

Tengo un sitio web móvil que tiene un ancho fijo de 640px, y me enfrenté al autozoom en foco.

¡Estaba intentando un montón de slutions pero ninguna funcionaba tanto en iPhone como en Android!

Ahora, para mí, está bien desactivar el zoom porque el sitio web fue el primer diseño móvil.

aquí es donde lo encuentro: ¿Cómo hacer el tamaño y la escala de las vistas para la compatibilidad con varios navegadores?


En Angular, puede usar directivas para evitar que el zoom se enfoque en los dispositivos IOS. No hay etiqueta meta para preservar la accesibilidad.

import { Directive, ElementRef, HostListener } from ''@angular/core''; const MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX = 16; @Directive({ selector: ''[noZoomiOS]'' }) export class NoZoomiOSDirective { constructor(private el: ElementRef) {} @HostListener(''focus'') onFocus() { this.setFontSize(''''); } @HostListener(''mousedown'') onMouseDown() { this.setFontSize(`${MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX}px`); } private setFontSize(size: string) { const { fontSize: currentInputFontSize } = window.getComputedStyle(this.el.nativeElement, null); if (MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX <= +currentInputFontSize.match(//d+/)) { return; } const iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform); iOS && (this.el.nativeElement.style.fontSize = size); } }

Puedes usarlo así <input noZoomiOS >después de declararlo en tu*.module.ts


@media screen and (-webkit-min-device-pixel-ratio:0) { select:focus, textarea:focus, input:focus { font-size: 16px; background: #eee; } }

Nuevo: IOS seguirá haciendo zoom, a menos que use 16px en la entrada sin el enfoque.

@media screen and (-webkit-min-device-pixel-ratio:0) { select, textarea, input { font-size: 16px; } }

Agregué un fondo ya que IOS no agrega ningún fondo en la selección.


input[type=''text''],textarea {font-size:1em;}