Disabilita Zoom automatico nel tag di immissione "Testo" - Safari su iPhone


541

Ho creato una pagina HTML con un <input>tag type="text". Quando faccio clic su di esso usando Safari su iPhone, la pagina diventa più grande (zoom automatico). Qualcuno sa come disabilitarlo?


8
Per tutti gli utenti Twitter Bootstrap che atterrano qui: vedi anche questo problema di Github .
Jeroen,

7
Penso che la risposta di @daxmacrog risponda esattamente a ciò che vuoi, sei disposto ad accettarlo in modo che possa salire in cima e salvare un sacco di rilavorazioni dalle persone che leggono tutto questo? Risposta 2018: stackoverflow.com/a/46254706/172651
Evoluzione del

@Evolve la risposta di cui hai parlato interrompe la funzionalità Android pizzico e zoom. la risposta di daxmacrog è difettosa.
MH,

5
Lo giuro, Apple crea queste anti-funzionalità solo per scherzare con le nostre teste.
Andrew Koster,

@AndrewKoster, sono d'accordo con te anche ora nel 2020.
Ashok,

Risposte:


492

Il browser eseguirà lo zoom se la dimensione del carattere è inferiore 16pxe la dimensione del carattere predefinita per gli elementi del modulo è 11px(almeno in Chrome e Safari).

Inoltre, l' selectelemento deve avere la focuspseudo-classe collegata.

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

Non è necessario utilizzare tutto quanto sopra, si può solo lo stile gli elementi necessari, ad esempio: solo text, numbere textarea:

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

Soluzione alternativa per far ereditare gli elementi di input da uno stile principale:

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

81
Solo per avere tutto coperto: 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; }
Nic Barbier il

8
@Nic Devi usare select:focus. Stava avendo lo stesso problema anche.
DGibbs,

141
Non capisco, come è possibile risolvere questo problema? Cosa succede se desidero una dimensione del carattere più piccola / più grande?
bryan,

47
il modo corretto è cambiare il meta tag in: <meta name = "viewport" content = "width = device-width, iniziale-scale = 1, maximum-scale = 1, user-scalable = 0" />
Milos Matic

37
@MilosMatic Nella maggior parte dei casi probabilmente non è una buona soluzione, in quanto impedisce completamente all'utente di ridimensionare la pagina. Potenzialmente ancora più fastidioso per i tuoi visitatori.
BadHorsie,

363

Puoi impedire a Safari di ingrandire automaticamente i campi di testo durante l'immissione dell'utente senza disabilitare la possibilità dell'utente di pizzicare lo zoom. Basta aggiungere maximum-scale=1ma tralasciare l'attributo di scala utente suggerito in altre risposte.

È un'opzione utile se hai un modulo in un livello che "galleggia" intorno se ingrandito, il che può far sì che importanti elementi dell'interfaccia utente si spostino dallo schermo.

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


66
Questa è la soluzione 2018+. Valuta questo come se la tua vita dipendesse da questo.
Henrik Petterson,

17
Questo romperà l'abilità di zoom dei dispositivi Android
fen1ksss

4
@daxmacrog, hai ragione, ma l'OP non ha menzionato se vuole rompere gli androidi consentendo il comportamento necessario. Qui è dove personalmente ho preso un'opzione errata. Certo, è meglio specificare.
fen1ksss,

13
@HenrikPetterson Oltre a disabilitare lo zoom automatico come specificato da OP, disabilita anche lo zoom con pizzico. Quindi non penso che sia la soluzione 2018+.
André Werlang,

4
@ AndréWerlang Non è accurato. Come indicato chiaramente nella risposta, questa soluzione non disabilita lo zoom con pizzico in Safari (o Firefox), che è ciò di cui l'OP ha chiesto. Ma come sottolineato nei commenti precedenti, disabilita lo zoom dell'utente sui dispositivi Android e in Chrome su iOS.
daxmacrog,

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

Novità: IOS eseguirà comunque lo zoom, a meno che non si utilizzi 16 px sull'input senza lo stato attivo.

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

Ho aggiunto uno sfondo poiché IOS non aggiunge sfondo alla selezione.


9
Questo funziona non solo per Safari su iOS (iphone / ipad / ipod), ma anche Safari / OSX e Chrome (Windows e Mac). Quindi, se stai cercando di indirizzare specificamente l'iPhone, questo non funzionerà.
Redtopia,

31
Perché tutti dicono 16px ma nessuno si preoccupa di menzionare perché esattamente è 16px? Perché un numero così arbitrario? Perché dobbiamo impostare la dimensione del testo del nostro campo modulo su 16px e non .. diciamo 1.8rem o 2.5em o simili? È solo uno stupido bug di un sistema operativo proprietario?
Beebee,

14
@Beebee La dimensione del carattere al 100% è 16px, valore predefinito per la maggior parte dei browser, se non per tutti (anche desktop). IOS lo utilizza come predefinito probabilmente perché è una dimensione comoda per la lettura. Perché è impostato in questo modo non mi sono preoccupato di guardare in alto, non mi interessa.
Christina,

5
Utilizzare @media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)per limitare l'effetto a iPhone, ma non modificare i siti Web quando vengono visualizzati in Chrome.
BurninLeo,

9
Invece di utilizzare una query multimediale, dovresti usare @supports (-webkit-overflow-scrolling: touch), poiché questa funzione css esiste solo su iOS
James Moran,

189

Se il tuo sito Web è progettato correttamente per un dispositivo mobile, potresti decidere di non consentire il ridimensionamento.

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

Questo risolve il problema che la tua pagina mobile o modulo sta per "fluttuare" intorno.


123
Tecnicamente corretto, ma non sono d'accordo con il ragionamento. Disabilitare gli zoom utente su un sito correttamente progettato è generalmente ancora una cattiva idea.
Fer

20
"Progettato correttamente" è molto soggettivo. Prendi in considerazione un'intestazione fissa da 50 px nella parte superiore di un sito che sia completamente reattiva e dovrebbe funzionare in tutti i browser. Lo zoom in iOS Safari interrompe il posizionamento dell'intestazione e praticamente interrompe l'intero sito.
Redtopia,

62
Disabilitare la funzionalità di zoom dell'utente è una pratica terribile dal punto di vista UX e dovrebbe essere davvero evitato a tutti i costi. Essere in grado di ingrandire liberamente è una funzione di accessibilità di base e un controllo che non dovresti mai togliere all'utente.
Gabriel Luethje,

72
Nelle app mobili native non hai mai la possibilità di zoomare e funzionano bene, perché una webapp dovrebbe essere diversa? Se imposti la dimensione del carattere e l'altezza della linea appropriate con chiari contrasti, dovresti essere a posto.
jotav,

39
Coloro che usano l'argomento 'va bene nelle app native' stanno trascurando il fatto che le app native ben fatte aderiscono alle impostazioni di accessibilità a livello di sistema operativo come la dimensione del testo. Gli utenti più anziani e ipovedenti possono e devono utilizzare caratteri di dimensioni estremamente grandi a livello di sistema operativo perché ne hanno bisogno . Le app Web spesso non aderiscono o non possono aderire a questa impostazione, pertanto consentire la funzionalità di accessibilità integrata del browser Web come lo zoom è di vitale importanza. Qualunque cosa tu pensi sia perfettamente leggibile, credimi, ci sono persone che non lo troveranno abbastanza chiaro. Non Non prendere questa opzione lontano da utenti se apprezzi l'usabilità.
Ryan Williams,

72

In breve, la risposta è: impostare la dimensione del carattere degli elementi del modulo su almeno 16px


Sì, questa è sicuramente la migliore pratica per evitare lo zoom sui dispositivi mobili. Niente js, niente hack, niente soluzioni. Ma anche con 16px ho notato uno zoom molto piccolo nelle mie pagine, quindi ho provato 17px, 18px ... per vedere cosa succede.
ed1nh0

8
È consigliabile dichiarare il 100% su body, button, input, textarea e selezionare gli elementi. Ciò consente all'utente di impostare un valore predefinito non 16px fornito con i browser. Qualcuno che ha difficoltà a leggere sullo schermo potrebbe impostare il valore predefinito su 18px o 20px. Non vuoi annullare la loro scelta forzando 16px su di loro. Quando si tratta di iOS, tuttavia, hanno deciso di aumentare qualsiasi valore che il loro HIG dice sia troppo piccolo. Sfortunatamente sembra che non interpreti il ​​valore del 100%, quindi siamo bloccati ad aggiungere il valore predefinito per placarlo.
J. Hogue,

RE iOS Safari, a partire da questo commento sembra che Safari interpreta correttamente il font-size: 100%valore e afferra il 16px necessario.
Nathan Lafferty,

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

3
Nota che l'impostazione scalabile dall'utente su no disabiliterà tutto lo zoom, il che è probabilmente una cattiva idea.
Stormsweeper,

18
Funziona solo se la dimensione del carattere del tuo corpo è quella predefinita (non specificato, o 1em, o 100%). Se imposti una dimensione del carattere personalizzata, puoi impostare lo font-sizesnippet 16pxper evitare lo zoom automatico.
Alan H.

So che questa domanda era rivolta a iPhone, ma questo è più compatibile su più piattaforme e nel futuro di più piattaforme / dispositivi, ho provato l'approccio 16px ma su un tablet Android ha solo ridotto l'effetto di zoom automatico. L'impostazione su "1em" come specificato nel post ha risolto il problema.
toddles_fp,

3
1em, né 1remè una soluzione adeguata perché entrambi possono essere inferiore 16pxe Safari richiede almeno 16pxdi non ingrandire.
Finesse

2
ho usato la soluzione viewport ma non ha funzionato, la soluzione 16px funziona bene, ma 16px è troppo grande per inputbox del mio sito, c'è una terza soluzione
Suneth Kalhara

21

Il modo corretto per risolvere questo problema è cambiare meta viewport in:

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


32
Questo non è necessariamente il modo "corretto" per prevenire questo comportamento. Safari mobile aumenta lo zoom se il testo è considerato troppo piccolo per essere letto. Disattivare lo zoom tutto insieme è pesante e impedisce agli utenti di interagire con la tua pagina in un modo che potrebbero aspettarsi.
AlecRust,

3
Apparentemente in iOS10 Apple ha modificato la proprietà della scala massima per non essere più rispettata, consentendo a tutti i siti di ingrandire indipendentemente dalle sue impostazioni.
Wolfr,

3
Funziona con iOS10 versione 20 / settembre / 2016 ... almeno funziona sulla mia app ... Grazie !!! Prima stavo usando <meta name = "viewport" content = "width = device-width, iniziale-scale = 1, minima scala = 1 , massima scala = 1"> Ma l'ho passato alla riga sulla risposta e ha funzionato ...
eljamz,

1
"Assicurati che lo zoom pizzico del browser non sia bloccato dal meta elemento viewport della pagina in modo che possa essere usato per ingrandire la pagina al 200%. I valori restrittivi per gli attributi scalabili dall'utente e della scala massima di questo meta element dovrebbero essere evitati." w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon

Ho visto commenti su come alcuni di questi meta tag non funzionino su iOS 10 e so che quanto sopra funziona su Chrome almeno per iOS. :) Grazie!
cbloss793,

16

Non riesco a trovare un modo pulito, ma ecco un trucco ...

1) Ho notato che l'evento del mouseover si verifica prima dello zoom, ma lo zoom avviene prima degli eventi di mouse o focus.

2) Puoi cambiare dinamicamente il tag viewport META usando javascript (vedi Abilitare / disabilitare lo zoom su iPhone Safari con Javascript? )

Quindi, prova questo (mostrato in jquery per compattezza):

$("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" />');
}

Questo è sicuramente un trucco ... potrebbero esserci situazioni in cui il passaggio del mouse / giù non sempre rileva voci / uscite, ma ha funzionato bene nei miei test ed è un buon inizio.


5
Non sono sicuro di quando il comportamento di Safari potrebbe essere cambiato, ma ora (iOS6.0.1) il mousedown si sta verificando prima dell'autozoom. Pertanto, nella mia precedente soluzione, lo zoom viene riattivato troppo presto. Non ho trovato una soluzione adeguata, dal momento che tutti gli eventi che ho provato ora accadono prima dello zoom. Puoi riattivare lo zoom su un keydown o sfocatura, ma ci sono alcuni scenari che potrebbero non essere presenti (ad esempio se l'utente desidera eseguire lo zoom manualmente prima di iniziare a digitare qualcosa).
dal

15

Aggiungi user-scalable = 0 al viewport meta come segue

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

Ha funzionato per me :)


11
"Assicurati che lo zoom pizzico del browser non sia bloccato dal meta elemento viewport della pagina in modo che possa essere usato per ingrandire la pagina al 200%. I valori restrittivi per gli attributi scalabili dall'utente e della scala massima di questo meta element dovrebbero essere evitati." w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon

9
Ciò infrange le regole di accessibilità definite da W3.
Joshua Russell,

ha funzionato per me, anche questa è la soluzione migliore per me poiché voglio la libertà di cambiare le dimensioni dei caratteri di input al di sotto di 16px e non voglio un hack JS
Blue Bot

14

Di recente (oggi: D) ho dovuto integrare questo comportamento. Al fine di non influire sui campi di progettazione originali, inclusa la combo, ho optato per applicare la trasformazione al centro del campo:

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

Cordiali saluti, Questo ha funzionato bene sul mio iPhone 5 con iOS 6, ma su un iPhone 4 con iOS 5 in modalità verticale, lo stile di messa a fuoco è stato applicato dopo lo zoom. Forse sta succedendo qualcosa di sottile, non ho indagato ulteriormente.
Vish,

Voglio solo dire che ho molte domande diverse usando lo zoom per velocizzare lo sviluppo e in base a quanto ingrandisci determinerò la dimensione del carattere di cui hai bisogno credo
mike

: focus non ha funzionato per me iOS 10.2 iPhone 6, ma input [type = "text"]: hover ha funzionato bene.
Amirhossein Rzd,

13

Come molte altre risposte hanno già sottolineato, questo può essere ottenuto aggiungendo maximum-scaleal meta viewporttag. Tuttavia, ciò ha la conseguenza negativa di disabilitare lo zoom utente sui dispositivi Android . ( Non disabilita lo zoom utente sui dispositivi iOS dalla v10 .)

Possiamo usare JavaScript per aggiungere dinamicamente maximum-scaleal meta viewportquando il dispositivo è iOS. Ciò consente di ottenere il meglio da entrambi i mondi: consentiamo all'utente di eseguire lo zoom e di impedire a iOS di ingrandire i campi di testo in primo piano.

| 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               |

Codice:

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

perché crei una copia di addMaximumScaleToMetaViewport? È solo per ragioni semantiche?
Pherrymason,

Sì, basta mappare la funzione su un nome diverso, quindi è chiaro come viene utilizzata.
Oliver Joseph Ash,

8

Hack di Javascript che funziona su iOS 7. Questo si basa sulla risposta di @dlo ma gli eventi di passaggio del mouse e del mouseout sono sostituiti da eventi touchstart e touchend. Fondamentalmente questo script aggiunge un timeout di mezzo secondo prima che lo zoom venga nuovamente abilitato per impedire lo 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" />');
} 

Questo ha funzionato meglio per me. Ma, ho cambiato gli eventi touchstart / touchend in un evento 'focus' sia con zoomDisable che zoomEnable.
Justin Cloud,

L'aggiunta del ritardo sembra funzionare abbastanza bene con le versioni più recenti di iOS, ma è interessante che non funzioni molto bene quando impostato su 250ms. Ciò suggerisce che in alcune circostanze, 500ms potrebbero non funzionare neanche, ma se funziona la maggior parte delle volte immagino sia meglio che non funzionare affatto. Pensare bene.
dlo

7

Questo ha funzionato per me:

input, textarea {
    font-size: initial;
}

Ben semplice, ma c'è un modo per controllare che cos'è quella dimensione "iniziale"?
2540625,

Non l'ho provato, ma questo dovrebbe essere un modo per controllare la dimensione del carattere. (per favore fatemi sapere se funziona e aggiornerò la mia risposta) body {font-size: 20px; } input {font-size: inherit; }

7

Ho usato la soluzione di Christina sopra, ma con una piccola modifica per bootstrap e un'altra regola da applicare ai computer desktop. La dimensione del carattere predefinita di Bootstrap è 14px che causa lo zoom. Di seguito viene modificato in 16px per "controlli modulo" in Bootstrap, impedendo lo zoom.

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

E torna a 14px per browser non mobili.

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

Ho provato a usare .form-control: focus, che lo ha lasciato a 14px tranne che su focus che lo ha cambiato a 16px e non ha risolto il problema di zoom con iOS8. Almeno sul mio iPhone usando iOS8, la dimensione del carattere deve essere 16px prima di mettere a fuoco l'iPhone per non ingrandire la pagina.


6

L'ho fatto, anche 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'));
});

Naturalmente, alcuni altri elementi nell'interfaccia potrebbero dover essere adattati se questa 16pxdimensione del carattere rompe il design.


4
Questo è di classe. Questo è stile. Ho finito i giochi di parole. Approccio intelligente.
crowjonah,

@ Wolfr hai provato su un dispositivo reale?
Nicolas Hoizey,

1
Questo ha funzionato per noi su iOS 12. Mi piace questo approccio il migliore invece di perdere tempo con trasformazioni CSS e margini negativi.
anonimo-uno

6

Dopo un po 'di tempo ho provato questa soluzione

// 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 = "";
});

Su "mousedown" imposta la dimensione del carattere dell'input su 16px. Ciò impedirà lo zoom. Nell'evento focus, la dimensione del carattere torna al valore iniziale.

A differenza delle soluzioni precedentemente pubblicate, questo ti permetterà di impostare la dimensione del carattere dell'input su quello che vuoi.


Questo in realtà funziona per me, soprattutto perché nelle nuove versioni di iOS non è possibile utilizzare il meta tag viewport per disabilitare lo zoom.
mparizeau,

Confermato il lavoro su iOS 12.1, grazie
Ziki

6

Dopo aver letto quasi ogni singola riga qui e testato le varie soluzioni, questo è, grazie a tutti coloro che hanno condiviso le loro soluzioni, quello che ho ideato, testato e lavorato per me su 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;}
}

Ha alcuni svantaggi, tuttavia, evidentemente un "salto" a causa della rapida modifica della dimensione del carattere che si verifica tra gli stati "hover" ed "focus" ed e l'impatto del ridisegno sulle prestazioni


Grazie per il tuo feedback, @MikeBoutin. Puoi condividere la tua env (versione dispositivo / iOS)?
lbelbel

6

Ispirato dalla risposta di @jirikuchta, ho risolto questo problema aggiungendo questo bit di CSS:

#myTextArea:active {
  font-size: 16px; /* `16px` is safer I assume, although `1rem` works too */
}

No JS, e non noto alcun flash o altro.

Vale la pena notare che a viewportwith maximum-scale=1funziona anche, ma non quando la pagina viene caricata come iframe, o se hai qualche altro script che modifica il viewport, ecc.


4

Pseudo elementi come :focusnon funzionano come una volta. Da iOS 11, è possibile aggiungere una semplice dichiarazione di ripristino prima dei propri stili principali (a condizione che non vengano sovrascritti con una dimensione del carattere inferiore).

/* Prevent zoom */
select, input, textarea {
  font-size: 16px;
}

Vale la pena ricordare che per le librerie CSS come Tachyons.css è facile sostituire accidentalmente la dimensione del carattere.

Ad esempio class: f5equivale a:, fontSize: 1remche va bene se la scala del carattere del corpo è stata mantenuta sul valore predefinito.

Tuttavia: se si sceglie la classe di dimensione del carattere: f6questo sarà equivalente a fontSize: .875remsu un piccolo display verso l'alto. In tal caso dovrai essere più specifico sulle dichiarazioni di ripristino:


  /* Prevent zoom */
  select, input, textarea {
    font-size: 16px!important;
  }

@media screen and (min-width: 30em) {

/* not small */

}

3

A proposito, se usi Bootstrap , puoi semplicemente usare questa variante:

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

3

Ho dovuto "risolvere" il problema dello zoom automatico nel controllo dei moduli per un sito Web dell'Università olandese (che utilizzava 15px nei controlli del modulo). Mi è venuta in mente la seguente serie di requisiti:

  • l'utente deve essere ancora in grado di ingrandire
  • la dimensione del carattere deve rimanere la stessa
  • nessun lampo di stile diverso temporaneo
  • nessun requisito jQuery
  • deve funzionare sul iOS più recente e non ostacolare qualsiasi altra combinazione sistema operativo / dispositivo
  • se possibile, nessun timeout magico e, se necessario, azzerare correttamente i timer

Questo è quello che mi è venuto in mente finora:

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

Alcune note:

  • Nota che finora l'ho provato solo su iOS 11.3.1, ma lo proverò presto su alcune altre versioni
  • Uso di focusIn eventi significa che richiede almeno iOS 5.1 (ma vedo comunque i siti che costruiamo funzionare nelle versioni iOS precedenti a 9 come un bel bonus)
  • Uso della delega degli eventi perché molti siti su cui lavoro hanno pagine che potrebbero creare dinamicamente controlli di modulo
  • Impostare eventListeners sull'elemento html (documentElement) in modo da non dover aspettare che il corpo diventi disponibile (non voglio preoccuparti di controllare se il documento ha lo stato pronto / caricato o di dover attendere l'evento DOMContentLoaded)

3

Invece di impostare semplicemente la dimensione del carattere su 16px, puoi:

  1. Modellare il campo di input in modo che sia più grande della dimensione prevista, consentendo di impostare la dimensione del carattere logico su 16px.
  2. Utilizzare la scale()trasformazione CSS e i margini negativi per ridurre il campo di input fino alla dimensione corretta.

Ad esempio, supponiamo che il tuo campo di input sia originariamente disegnato con:

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

Se ingrandisci il campo aumentando tutte le dimensioni del 16/12 = 133,33%, quindi riduci utilizzando scale()del 12/16 = 75%, il campo di input avrà la dimensione visiva corretta (e la dimensione del carattere) e non ci sarà alcun ingrandimento messa a fuoco.

Poiché scale()influisce solo sulla dimensione visiva, dovrai anche aggiungere margini negativi per ridurre la dimensione logica del campo.

Con questo 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%;
}

il campo di input avrà una dimensione del carattere logico di 16px mentre sembra avere un testo di 12px.

Ho un post sul blog in cui vado un po 'più in dettaglio, e ho questo esempio come HTML visualizzabile:
nessun input zoom in Safari su iPhone, il modo pixel perfetto


3

Anche con queste risposte mi ci sono voluti tre giorni per capire cosa stesse succedendo e potrei aver bisogno di nuovo la soluzione in futuro.

La mia situazione era leggermente diversa da quella descritta.

Nel mio, avevo un testo appagante in un div sulla pagina. Quando l'utente ha fatto clic su un DIVERSO div, un tipo di pulsante, ho selezionato automaticamente del testo nel div contenteditable (un intervallo di selezione che era stato precedentemente salvato e cancellato), ho eseguito un richCommand rich text su quella selezione e l'ho cancellato di nuovo.

Ciò mi ha permesso di cambiare in modo invisibile i colori del testo in base alle interazioni dell'utente con i div di colore in altre parti della pagina, mantenendo la selezione normalmente nascosta per consentire loro di vedere i colori nel giusto contesto.

Bene, su Safari di iPad, facendo clic sul div di colore si è verificata la comparsa della tastiera su schermo, e nulla che ho fatto lo avrebbe impedito.

Alla fine ho capito come sta andando l'iPad.

Ascolta una sequenza di touchstart e touchend che attiva una selezione di testo modificabile.

Quando si verifica quella combinazione, mostra la tastiera su schermo.

In realtà, esegue uno zoom dolly in cui espande la pagina sottostante mentre ingrandisce il testo modificabile. Mi ci è voluto un giorno solo per capire cosa stavo vedendo.

Quindi la soluzione che ho usato è stata quella di intercettare sia il touchstart che il touchend su quei particolari div di colore. In entrambi i gestori interrompo la propagazione e il gorgoglio e ritorno falso. Ma nel caso del touchend innesco lo stesso comportamento attivato dal clic.

Quindi, prima, Safari stava innescando quello che penso fosse "touchstart", "mousedown", "touchend", "mouseup", "click", e grazie al mio codice, una selezione di testo, in quell'ordine.

La nuova sequenza a causa delle intercettazioni è semplicemente la selezione del testo. Tutto il resto viene intercettato prima che Safari possa elaborarlo e fare le sue cose da tastiera. Le intercettazioni touchstart e touchend impediscono anche l'attivazione degli eventi del mouse, e nel contesto questo è totalmente corretto.

Non conosco un modo più semplice per descriverlo, ma penso che sia importante averlo qui perché ho trovato questo thread entro un'ora dal primo incontro con il problema.

Sono sicuro al 98% che la stessa correzione funzionerà con le caselle di input e qualsiasi altra cosa. Intercetta gli eventi tattili ed elaborali separatamente senza lasciarli propagare o creare bolle, e considera di fare qualsiasi selezione dopo un piccolo timeout solo per assicurarti che Safari non riconosca la sequenza come il trigger della tastiera.


Questa è una grande spiegazione di ciò che Safari sta facendo. Grazie!
Jeremy,

2

Vedo che qui le persone fanno cose strane con JavaScript o la funzione viewport e disattivano tutto lo zoom manuale sui dispositivi. Non dovrebbe essere una soluzione secondo me. L'aggiunta di questo frammento CSS disattiva lo zoom automatico in iOS senza modificare la dimensione del carattere in un numero fisso come 16px.

Per impostazione predefinita, utilizzo la dimensione del carattere 93,8% (15px) nei campi di input e aggiungendo il mio frammento CSS questo rimane al 93,8%. Non è necessario cambiare a 16px o renderlo un numero fisso.

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

5
Questo non funziona per me, testato con iOS 6 e iOS 9.2.1 più recenti. Ecco una pagina riproducibile minima: pastebin.com/bh5Zhe9h Ingrandisce ancora la messa a fuoco. Strano che sia stato pubblicato nel 2015 e aggiornato ma non funziona in iOS 6.
Alexandre Dieulot,

2

Impostare una dimensione del carattere (per i campi di input) uguale alla dimensione del carattere del corpo, sembra essere ciò che impedisce al browser di ingrandire o ridurre. Suggerirei di utilizzare font-size: 1remcome soluzione più elegante.


1

Dato che lo zoom automatico (senza zoom out) sta ancora annonando su iPhone, ecco un JavaScript basato sul suggerimento di dlo che lavora con focus / blur.

Lo zoom viene disabilitato non appena viene inserito un input di testo e riattivato quando viene lasciato l'input.

Nota: alcuni utenti potrebbero non apprendere a modificare i testi con un piccolo input di testo! Pertanto, personalmente preferisco cambiare la dimensione del testo dell'input durante la modifica (vedi il codice sotto).

<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>

Il seguente codice cambierà la dimensione del testo di un input a 16 pixel (calcolata, cioè, nella dimensione dello zoom corrente) durante il focus dell'elemento. L'iPhone pertanto non eseguirà automaticamente lo zoom in avanti.

Nota: il fattore di zoom viene calcolato in base a window.innerWidth e al display dell'iPhone con 320 pixel. Questo sarà valido solo per iPhone in modalità verticale.

<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>

1

Mi ci è voluto un po 'per trovarlo, ma ecco il codice migliore che ho trovato ...... 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));
});

1

Basato sulla risposta di Stephen Walsh ... Questo codice funziona senza cambiare la dimensione del carattere degli input a fuoco (che sembra zoppo), inoltre funziona ancora con FastClick , che suggerisco di aggiungere a tutti i siti mobili per contribuire a rendere "scattante". Regola la "larghezza della finestra" in base alle tue esigenze.

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

Se l'utente avesse già ingrandito un po 'lo zoom prima di fare clic sul controllo di input, questa soluzione causerebbe improvvisamente la "decompressione" della finestra?
Bruno Torquato,

Sì, ma non sembra più stonante del precedente effetto "zoom" che si è verificato ogni volta che l'utente ha fatto clic su un input.
Pete,

1

Un commento per la risposta principale sull'impostazione della dimensione del carattere su 16px ha chiesto come sia una soluzione, e se si desidera un carattere più grande / più piccolo.

Non so tutti voi, ma usare px per le dimensioni dei caratteri non è il modo migliore per andare, dovreste usarli.

Ho riscontrato questo problema sul mio sito reattivo in cui il mio campo di testo è più grande di 16 pixel. Avevo il mio contenitore di moduli impostato su 2rem e il mio campo di input impostato su 1.4em. Nelle mie query mobili cambio la dimensione del carattere html a seconda della finestra. Poiché il codice HTML predefinito è 10, il mio campo di input viene calcolato su 28 px sul desktop

Per rimuovere lo zoom automatico ho dovuto modificare il mio input in 1.6em. Ciò ha aumentato la dimensione del mio carattere a 32 px. Solo leggermente più alto e appena percettibile. Sul mio iPhone 4 e 5 cambio la dimensione del carattere html a 15px per il ritratto e di nuovo a 10px per il paesaggio. Sembrava che il punto debole per quella dimensione di pixel fosse 48px, motivo per cui sono passato da 1,4em (42px) a 1,6em (48px).

La cosa che devi fare è trovare il punto debole sulla dimensione del carattere e quindi convertirlo all'indietro nelle dimensioni rem / em.


1

Ecco un trucco che ho usato su uno dei miei progetti:

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

Ho finito con gli stili e la scala iniziali che desideravo, ma senza zoom sulla messa a fuoco.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.