Eu criei uma página HTML com uma <input>
tag type="text"
. Quando clico nele usando o Safari no iPhone, a página fica maior (zoom automático). Alguém sabe como desativar isso?
Eu criei uma página HTML com uma <input>
tag type="text"
. Quando clico nele usando o Safari no iPhone, a página fica maior (zoom automático). Alguém sabe como desativar isso?
Respostas:
O navegador aumentará o zoom se o tamanho da fonte for menor que 16px
e o tamanho da fonte padrão para os elementos do formulário for 11px
(pelo menos no Chrome e Safari).
Além disso, o select
elemento precisa ter a focus
pseudo classe anexada.
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;
}
Não é necessário o uso de todos os acima, você pode simplesmente estilo os elementos que você precisa, por exemplo: apenas text
, number
e textarea
:
input[type='text'],
input[type='number'],
textarea {
font-size: 16px;
}
Solução alternativa para herdar os elementos de entrada de um estilo pai:
body {
font-size: 16px;
}
input[type="text"] {
font-size: inherit;
}
select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"] { font-size: 16px; }
select:focus
. Estava tendo o mesmo problema também.
Você pode impedir que o Safari faça zoom automaticamente nos campos de texto durante a entrada do usuário sem desativar a capacidade do usuário de beliscar o zoom. Basta adicionarmaximum-scale=1
mas deixar de fora o atributo de escala do usuário sugerido em outras respostas.
É uma opção interessante se você tiver um formulário em uma camada que "flutue" ao redor se for ampliada, o que pode fazer com que elementos importantes da interface do usuário se movam para fora da tela.
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
@media screen and (-webkit-min-device-pixel-ratio:0) {
select:focus,
textarea:focus,
input:focus {
font-size: 16px;
background: #eee;
}
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
select,
textarea,
input {
font-size: 16px;
}
}
Eu adicionei um plano de fundo, já que o IOS não adiciona plano de fundo ao selecionar.
@media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)
para limitar o efeito ao iPhone, mas não modifique sites quando visualizados no Chrome.
@supports (-webkit-overflow-scrolling: touch)
, como este recurso css só existe no iOS
Se o seu site for projetado corretamente para um dispositivo móvel, você poderá decidir não permitir o dimensionamento.
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
Isso resolve o problema que a sua página ou formulário para celular vai 'flutuar'.
Em resumo, a resposta é: defina o tamanho da fonte dos elementos do formulário para pelo menos 16 px
font-size: 100%
valor e obtém os 16px necessários.
input[type='text'],textarea {font-size:1em;}
1em
, ou 100%
). Se você definir um tamanho de fonte personalizado, poderá defini-lo font-size
no snippet 16px
para evitar o zoom automático.
1em
nem 1rem
é uma solução adequada, porque tanto pode ser inferior 16px
e Safari requer pelo menos 16px
para não ampliar.
A maneira correta de corrigir esse problema é alterar a meta viewport para:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
Não há uma maneira limpa de encontrar, mas aqui está um truque ...
1) Notei que o evento do mouseover ocorre antes do zoom, mas o zoom ocorre antes dos eventos de redução ou foco.
2) Você pode alterar dinamicamente a tag da porta de visualização META usando javascript (consulte Ativar / desativar o zoom no safari do iPhone com Javascript? )
Então, tente isso (mostrado no jquery para compactação):
$("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" />');
}
Definitivamente, isso é um hack ... pode haver situações em que o mouse / down nem sempre captura entradas / saídas, mas funcionou bem nos meus testes e é um começo sólido.
Adicione user-scalable = 0 para a viewport meta da seguinte maneira
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
Trabalhou para mim :)
Recentemente (hoje: D) tive que integrar esse comportamento. Para não impactar os campos de design originais, incluindo o combo, optei por aplicar a transformação no foco do campo:
input[type="text"]:focus, input[type="password"]:focus,
textarea:focus, select:focus {
font-size: 16px;
}
Como muitas outras respostas já apontaram, isso pode ser alcançado adicionando maximum-scale
à metatag viewport
. No entanto, isso tem a consequência negativa de desativar o zoom do usuário em dispositivos Android . ( Não desativa o zoom do usuário em dispositivos iOS desde a v10 .)
Podemos usar JavaScript para adicionar dinamicamente maximum-scale
à meta viewport
quando o dispositivo é iOS. Isso alcança o melhor dos dois mundos: permitimos que o usuário amplie e evite que o iOS amplie os campos de texto em foco.
| maximum-scale | iOS: can zoom | iOS: no text field zoom | Android: can zoom |
| ------------------------- | ------------- | ----------------------- | ----------------- |
| yes | yes | yes | no |
| no | yes | no | yes |
| yes on iOS, no on Android | yes | yes | yes |
Código:
const addMaximumScaleToMetaViewport = () => {
const el = document.querySelector('meta[name=viewport]');
if (el !== null) {
let content = el.getAttribute('content');
let re = /maximum\-scale=[0-9\.]+/g;
if (re.test(content)) {
content = content.replace(re, 'maximum-scale=1.0');
} else {
content = [content, 'maximum-scale=1.0'].join(', ')
}
el.setAttribute('content', content);
}
};
const disableIosTextFieldZoom = addMaximumScaleToMetaViewport;
// /programming/9038625/detect-if-device-is-ios/9039885#9039885
const checkIsIOS = () =>
/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
if (checkIsIOS()) {
disableIosTextFieldZoom();
}
addMaximumScaleToMetaViewport
? É apenas por razões semânticas?
Hack de Javascript, que funciona no iOS 7. Isso é baseado na resposta do @dlo, mas os eventos de mouseover e mouseout são substituídos pelos eventos touchstart e touchend. Basicamente, esse script adiciona um intervalo de meio segundo antes que o zoom seja ativado novamente para impedir o 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" />');
}
Isso funcionou para mim:
input, textarea {
font-size: initial;
}
Usei a solução de Christina acima, mas com uma pequena modificação para o bootstrap e outra regra para aplicar aos computadores de mesa. O tamanho da fonte padrão do Bootstrap é 14px, o que causa o zoom. O seguinte altera para 16px para "controles de formulário" no Bootstrap, impedindo o zoom.
@media screen and (-webkit-min-device-pixel-ratio:0) {
.form-control {
font-size: 16px;
}
}
E voltando ao 14px para navegadores não móveis.
@media (min-width: 768px) {
.form-control {
font-size: 14px;
}
}
Tentei usar o .form-control: focus, que o deixou em 14px, exceto no foco, que foi alterado para 16px e não corrigiu o problema de zoom no iOS8. Pelo menos no meu iPhone usando iOS8, o tamanho da fonte deve ser 16 px antes do foco para o iPhone não ampliar a página.
Eu fiz isso, também com 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'));
});
Obviamente, alguns outros elementos na interface podem precisar ser adaptados se esse 16px
tamanho da fonte interromper o design.
Depois de um tempo tentando, eu vim com esta solução
// 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 = "";
});
Em "mousedown", define o tamanho da fonte da entrada como 16px. Isso impedirá o zoom. No evento de foco, ele altera o tamanho da fonte de volta ao valor inicial.
Diferentemente das soluções publicadas anteriormente, isso permitirá que você defina o tamanho da fonte da entrada para o que quiser.
Depois de ler quase todas as linhas aqui e testar as várias soluções, é isso, graças a todos que compartilharam suas soluções, o que eu criei, testei e trabalhei para mim no 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;}
}
Porém, ele tem alguns contras, notadamente um "salto" como resultado da rápida mudança no tamanho da fonte que ocorre entre os estados ed "focalizado" e "focalizado" - e o impacto do redesenho no desempenho
Inspirado na resposta de @jirikuchta, resolvi esse problema adicionando este pouco de CSS:
#myTextArea:active {
font-size: 16px; /* `16px` is safer I assume, although `1rem` works too */
}
Sem JS, e não percebo nenhum flash ou qualquer coisa.
Vale ressaltar que a viewport
com maximum-scale=1
também funciona, mas não quando a página é carregada como um iframe ou se você tiver algum outro script modificando o viewport
, etc.
Pseudo-elementos como :focus
não funcionam como costumavam. No iOS 11, é possível adicionar uma declaração de redefinição simples antes dos estilos principais (desde que você não os substitua por um tamanho de fonte menor).
/* Prevent zoom */
select, input, textarea {
font-size: 16px;
}
Vale ressaltar que para bibliotecas CSS como o Tachyons.css, é fácil substituir acidentalmente o tamanho da fonte.
Por exemplo, class: f5
é equivalente a:fontSize: 1rem
que é bom se você mantiver a escala da fonte do corpo no padrão.
No entanto: se você escolher a classe de tamanho da fonte: f6
isso será equivalente a fontSize: .875rem
uma pequena exibição para cima. Nesse caso, você precisará ser mais específico sobre suas declarações de redefinição:
/* Prevent zoom */
select, input, textarea {
font-size: 16px!important;
}
@media screen and (min-width: 30em) {
/* not small */
}
A propósito, se você usa o Bootstrap , pode apenas usar esta variante:
.form-control {
font-size: 16px;
}
Eu tive que "corrigir" o problema de zoom automático nos controles de formulário de um site da Universidade Holandesa (que usava 15px nos controles de formulário). Eu vim com o seguinte conjunto de requisitos:
Isto é o que eu vim até agora:
/*
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);
}
}
Algumas notas:
Em vez de simplesmente definir o tamanho da fonte como 16px, você pode:
scale()
transformação CSS e as margens negativas para reduzir o campo de entrada até o tamanho correto.Por exemplo, suponha que seu campo de entrada seja originalmente estilizado com:
input[type="text"] {
border-radius: 5px;
font-size: 12px;
line-height: 20px;
padding: 5px;
width: 100%;
}
Se você aumentar o campo aumentando todas as dimensões em 16/12 = 133,33% e reduza usando scale()
em 12/16 = 75%, o campo de entrada terá o tamanho visual correto (e tamanho da fonte) e não haverá zoom foco.
Como scale()
afeta apenas o tamanho visual, você também precisará adicionar margens negativas para reduzir o tamanho lógico do campo.
Com 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%;
}
o campo de entrada terá um tamanho de fonte lógica de 16px enquanto parece ter texto de 12px.
Tenho uma postagem no blog em que vou detalhar um pouco mais e tenho este exemplo como HTML visível:
Não há zoom de entrada no Safari no iPhone, a maneira perfeita de pixel
Mesmo com essas respostas, levei três dias para descobrir o que estava acontecendo e talvez eu precise da solução novamente no futuro.
Minha situação era um pouco diferente da descrita.
No meu, eu tinha um texto editável em uma div na página. Quando o usuário clicou em uma div DIFERENTE, um botão das sortes, selecionei automaticamente algum texto na div editável por conteúdo (um intervalo de seleção que havia sido salvo e limpo anteriormente), executou um execCommand em rich text nessa seleção e o limpei novamente.
Isso me permitiu alterar invisivelmente as cores do texto com base nas interações do usuário com as divs de cores em outras partes da página, mantendo a seleção normalmente oculta para permitir que eles vejam as cores no contexto apropriado.
Bem, no Safari do iPad, clicar na div de cores resultou na ativação do teclado na tela, e nada que eu fiz impediu.
Finalmente descobri como o iPad está fazendo isso.
Ele escuta uma sequência de toque e toque que aciona uma seleção de texto editável.
Quando essa combinação acontece, ele mostra o teclado na tela.
Na verdade, ele faz um zoom de zorra onde expande a página subjacente enquanto amplia o texto editável. Levei um dia apenas para entender o que estava vendo.
Portanto, a solução que usei foi interceptar o touchstart e o touchend nesses divs de cores específicos. Nos dois manipuladores, paro a propagação e o borbulhamento e retorno falso. Mas, no evento touchend, desencadeio o mesmo comportamento que o clique disparou.
Antes, o Safari estava acionando o que eu acho que era "touchstart", "mousedown", "touchend", "mouseup", "mouseup", "click" e, por causa do meu código, uma seleção de texto, nessa ordem.
A nova sequência por causa das interceptações é simplesmente a seleção de texto. Todo o resto é interceptado antes que o Safari possa processá-lo e fazer suas coisas de teclado. As interceptações touchstart e touchend também impedem que os eventos do mouse sejam acionados e, no contexto, isso é totalmente correto.
Não conheço uma maneira mais fácil de descrever isso, mas acho que é importante tê-lo aqui, porque encontrei esse tópico dentro de uma hora depois de encontrar o problema.
Tenho 98% de certeza de que a mesma correção funcionará com caixas de entrada e qualquer outra coisa. Intercepte os eventos de toque e processe-os separadamente, sem permitir que eles se propaguem ou borbulhem e considere fazer qualquer seleção após um pequeno tempo limite, apenas para garantir que o Safari não reconheça a sequência como o acionador do teclado.
Vejo pessoas aqui fazendo coisas estranhas com JavaScript ou a função de janela de exibição e desativando o zoom manual nos dispositivos. Isso não deve ser uma solução na minha opinião. A adição desse trecho de CSS desativará o zoom automático no iOS sem alterar o tamanho da fonte para um número fixo como 16px.
Por padrão, eu uso o tamanho da fonte de 93,8% (15px) nos campos de entrada e, adicionando meu snippet CSS, ele permanece em 93,8%. Não há necessidade de alterar para 16px ou torná-lo um número fixo.
input[type="text"]:focus,
textarea:focus {
-webkit-text-size-adjust: 100%;
}
Definir um tamanho de fonte (para campos de entrada) igual ao tamanho da fonte do corpo parece ser o que impede que o navegador diminua ou diminua o zoom. Sugiro que seja usada font-size: 1rem
como uma solução mais elegante.
Como o zoom automático (sem zoom) ainda é irritante no iPhone, aqui está um JavaScript baseado na sugestão da dlo de trabalhar com foco / desfoque.
O zoom é desativado assim que uma entrada de texto é ativada e reativada quando a entrada é deixada.
Nota: Alguns usuários podem não gostar de editar textos em uma pequena entrada de texto! Portanto, eu pessoalmente prefiro alterar o tamanho do texto da entrada durante a edição (consulte o código abaixo).
<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>
O código a seguir alterará o tamanho do texto de uma entrada para 16 pixels (calculado, ou seja, no tamanho atual do zoom) durante o foco do elemento. O iPhone não aumentará automaticamente o zoom.
Nota: O fator de zoom é calculado com base na janela window.innerWidth e na tela do iPhone com 320 pixels. Isso será válido apenas para o iPhone no 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>
Levei um tempo para encontrá-lo, mas aqui está o melhor código que eu encontrei ...... 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));
});
Com base na resposta de Stephen Walsh ... Esse código funciona sem alterar o tamanho da fonte das entradas em foco (o que parece ruim), e ainda funciona com o FastClick , que eu sugiro que seja adicionado a todos os sites móveis para ajudar a trazer o "snappy". Ajuste sua "largura da janela de exibição" para atender às suas necessidades.
// 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)
});
Um comentário para a resposta principal sobre como definir o tamanho da fonte para 16px perguntou como essa é uma solução, e se você quiser uma fonte maior / menor.
Eu não sei sobre todos vocês, mas usar px para tamanhos de fonte não é o melhor caminho a seguir, você deve usá-los.
Encontrei esse problema no meu site responsivo, onde meu campo de texto é maior que 16 pixels. Eu tinha meu contêiner de formulário definido como 2rem e meu campo de entrada definido como 1.4em. Nas minhas consultas para dispositivos móveis, altero o tamanho da fonte html, dependendo da janela de visualização. Como o html padrão é 10, meu campo de entrada calcula para 28 px na área de trabalho
Para remover o zoom automático, tive que alterar minha entrada para 1.6em. Isso aumentou o tamanho da minha fonte para 32px. Apenas um pouco mais alto e quase imperceptível. No iPhone 4 e 5, altero o tamanho da fonte html para 15px para retrato e de volta para 10px para paisagem. Parecia que o ponto ideal para esse tamanho de pixel era 48px, motivo pelo qual mudei de 1,4em (42px) para 1,6em (48px).
O que você precisa fazer é encontrar o ponto ideal no tamanho da fonte e depois convertê-lo para trás nos tamanhos rem / em.