Wyłącz automatyczne powiększanie wejściowego znacznika „Tekst” - Safari na iPhonie

539

Zrobiłem stronę HTML z <input>tagiem type="text". Po kliknięciu go w przeglądarce Safari na telefonie iPhone strona staje się większa (automatyczne powiększanie). Czy ktoś wie, jak to wyłączyć?

Eduardo Czarnogóra
źródło
8
Dla wszystkich użytkowników Twittera Bootstrap lądujących tutaj: zobacz także ten problem Github .
Jeroen
7
Myślę, że @daxmacrog odpowiedź dokładnie odpowiada na to, czego chcesz, czy jesteś gotów to zaakceptować, aby wspiąć się na szczyt i zaoszczędzić wielu przeróbek od osób czytających to wszystko? Odpowiedź 2018: stackoverflow.com/a/46254706/172651
Evolve
@ Rozwiąż odpowiedź, o której mówiłeś, zrywa funkcje szczypania i powiększania Androida. Odpowiedź daxmacrog jest błędna.
MH
4
Przysięgam, Apple tworzy te antyfunkcje tylko po to, by zadzierać w naszych głowach.
Andrew Koster,
@AndrewKoster, zgadzam się z tobą nawet teraz w 2020 roku.
Ashok

Odpowiedzi:

491

Przeglądarka wykona zbliżenie, jeśli rozmiar czcionki jest mniejszy niż, 16pxa domyślny rozmiar czcionki dla elementów formularza to 11px(przynajmniej w Chrome i Safari).

Ponadto selectelement musi mieć focusdołączoną pseudoklasę.

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

To nie jest niezbędne do korzystania z wszystkich wyżej wymienionych, można po prostu styl elementy trzeba np: po prostu text, numberi textarea:

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

Alternatywne rozwiązanie, aby elementy wejściowe dziedziczyły po stylu nadrzędnym:

body {
  font-size: 16px;
}
input[type="text"] {
  font-size: inherit;
}
śrikanth
źródło
81
Tylko po to, żeby wszystko załatwić: 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,
8
@Nic Musisz użyć select:focus. Miałem ten sam problem.
DGibbs
141
Nie rozumiem, jak to jest poprawka? Co jeśli chcę mniejszy / większy rozmiar czcionki?
bryan
47
właściwym sposobem jest zmiana metatagu na: <nazwa meta = "rzutnia" treść = "szerokość = szerokość urządzenia, początkowa skala = 1, maksymalna skala = 1, skalowalne przez użytkownika = 0" />
Milos Matic
37
@ MilosMatic W większości przypadków prawdopodobnie nie jest to dobre rozwiązanie, ponieważ całkowicie uniemożliwia użytkownikowi skalowanie strony. Potencjalnie jeszcze bardziej irytujący dla odwiedzających.
BadHorsie
359

Możesz uniemożliwić Safari automatyczne powiększanie pól tekstowych podczas wprowadzania danych przez użytkownika bez wyłączania możliwości powiększania powiększenia przez użytkownika. Po prostu dodaj, maximum-scale=1ale pomiń atrybut skali użytkownika sugerowany w innych odpowiedziach.

Jest to opłacalna opcja, jeśli masz formę w warstwie, która „unosi się”, jeśli jest powiększona, co może spowodować, że ważne elementy interfejsu użytkownika znikną z ekranu.

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

daxmacrog
źródło
65
To jest rozwiązanie 2018+. Głosuj za tym tak, jakby od tego zależało twoje życie.
Henrik Petterson
17
Spowoduje to złamanie możliwości powiększania urządzeń z systemem Android
fen1ksss
4
@daxmacrog, masz rację, ale OP nie wspomniał, czy chce złamać androidy, pozwalając na potrzebne zachowanie. To tutaj osobiście wybrałem niewłaściwą opcję. Oczywiście lepiej jest określić.
fen1ksss
13
@HenrikPetterson To nie tylko wyłącza automatyczne powiększanie określone przez OP, ale także wyłącza powiększanie szczypane. Więc nie sądzę, że jest to rozwiązanie 2018+.
André Werlang,
4
@ AndréWerlang To nie jest dokładne. Jak stwierdzono wyraźnie w odpowiedzi, to rozwiązanie nie wyłącza powiększania szczypcami w Safari (lub Firefox), o co pytał OP. Ale jak wskazano w poprzednich komentarzach, wyłącza powiększanie użytkownika na urządzeniach z Androidem i w Chrome na iOS.
daxmacrog
223
@media screen and (-webkit-min-device-pixel-ratio:0) { 
  select:focus,
  textarea:focus,
  input:focus {
    font-size: 16px;
    background: #eee;
  }
}

Nowość: IOS będzie nadal powiększać, chyba że użyjesz 16px na wejściu bez fokusa.

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

Dodałem tło, ponieważ IOS nie dodaje tła do zaznaczenia.

Christina
źródło
9
Działa to nie tylko w przypadku safari na iOS (iPhone / ipad / ipod), ale także Safari / OSX i Chrome (Windows i Mac). Więc jeśli próbujesz celować w iPhone'a, to nie zadziała.
Redtopia
31
Dlaczego wszyscy mówią 16 pikseli, ale nikt nie chce wspomnieć, dlaczego dokładnie ma 16 pikseli? Dlaczego taka dowolna liczba? Dlaczego musimy ustawić rozmiar pola formularza na 16 pikseli, a nie… powiedzmy 1.8rem lub 2.5em czy coś takiego? Czy to tylko głupi błąd z zastrzeżonego systemu operacyjnego?
Beebee
14
@Beebee 100% rozmiar czcionki to 16 pikseli, co jest wartością domyślną dla większości, jeśli nie dla wszystkich przeglądarek (również na komputerze). IOS używa go jako domyślnego prawdopodobnie dlatego, że jest to wygodny rozmiar do czytania. Dlaczego to jest ustawione w ten sposób, że nie zadałem sobie trudu, by spojrzeć w górę, nie obchodzi mnie to.
Christina
5
Użyj, @media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)aby ograniczyć efekt do iPhone'a, ale nie modyfikuj stron internetowych podczas przeglądania w Chrome.
BurninLeo,
9
Zamiast używać zapytania o media, powinieneś użyć @supports (-webkit-overflow-scrolling: touch), ponieważ ta funkcja css istnieje tylko w systemie iOS
James Moran
189

Jeśli Twoja witryna jest odpowiednio zaprojektowana dla urządzenia mobilnego, możesz zdecydować, że nie zezwalasz na skalowanie.

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

To rozwiązuje problem, że Twoja strona mobilna lub formularz będą się „unosić”.

Marcellino Bommezijn
źródło
123
Technicznie poprawne, ale nie zgadzam się z uzasadnieniem. Wyłączenie powiększenia użytkownika w prawidłowo zaprojektowanej witrynie jest ogólnie złym pomysłem.
Fer
20
„Właściwie zaprojektowane” jest bardzo subiektywne. Rozważ stały nagłówek 50 pikseli na górze strony, który jest w pełni responsywny i powinien działać we wszystkich przeglądarkach. Powiększanie w iOS Safari psuje pozycję nagłówka i prawie całą witrynę.
Redtopia,
62
Wyłączanie funkcji powiększania przez użytkownika jest okropną praktyką z punktu widzenia UX i naprawdę należy jej unikać za wszelką cenę. Możliwość swobodnego powiększania jest podstawową funkcją ułatwień dostępu oraz kontrolą, której nigdy nie powinieneś odbierać użytkownikowi.
Gabriel Luethje
72
W natywnych aplikacjach mobilnych nigdy nie masz szansy na powiększenie i działają one dobrze, dlaczego aplikacja internetowa miałaby być inna? Jeśli ustawisz odpowiedni rozmiar czcionki i wysokość linii z wyraźnymi kontrastami, powinieneś być w porządku.
jotav
39
Ci, którzy używają argumentu „w aplikacjach natywnych jest w porządku”, przeoczają fakt, że dobrze wykonane aplikacje natywne stosują się do ustawień dostępności na poziomie systemu operacyjnego, takich jak rozmiar tekstu. Starsi i słabo widzący użytkownicy mogą używać bardzo dużych czcionek w całym systemie operacyjnym, ponieważ muszą . Aplikacje internetowe często nie dostosowują się do tego ustawienia lub nie mogą go stosować, dlatego kluczowe znaczenie ma umożliwienie wbudowanej funkcji ułatwień dostępu w przeglądarce internetowej, takiej jak powiększanie. Cokolwiek myślisz, że jest doskonale czytelne, uwierz mi, są ludzie, którzy nie uznają tego za wystarczająco jasne. Czy nie ma tej opcji, z dala od użytkowników, jeśli cenisz użyteczność.
Ryan Williams
72

Podsumowując, odpowiedź brzmi: ustaw rozmiar czcionki elementów formularza na co najmniej 16 pikseli

Nik
źródło
Tak, jest to zdecydowanie najlepsza praktyka, aby uniknąć powiększania na urządzeniach mobilnych. Żadnych js, żadnych hacków, żadnych obejść. Ale nawet przy 16px zauważyłem bardzo mały zoom na moich stronach, więc spróbowałem 17px, 18px ... aby zobaczyć, co się stanie.
ed1nh0
8
Najlepszą praktyką jest deklarowanie 100% treści, przycisku, wprowadzania, obszaru tekstowego i wybranych elementów. Dzięki temu użytkownik może ustawić wartość domyślną inną niż 16 pikseli dostarczana z przeglądarkami. Ktoś, kto ma problemy z czytaniem na ekranie, może ustawić domyślną wartość 18px lub 20px. Nie chcesz przesłonić ich wyboru, wymuszając na nich 16 pikseli. Jeśli chodzi o iOS, podjęli decyzję o zwiększeniu wartości, które według ich HIG są zbyt małe. Niestety wygląda na to, że nie interpretuje wartości 100%, więc utknęliśmy dodając domyślną wartość, aby ją uspokoić.
J. Hogue,
RE iOS Safari, od tego komentarza Safari poprawnie interpretuje font-size: 100%wartość i pobiera niezbędne 16px.
Nathan Lafferty
36
input[type='text'],textarea {font-size:1em;}
szturmowiec
źródło
3
Zauważ, że ustawienie skalowalne przez użytkownika na no spowoduje wyłączenie całego powiększania, co jest prawdopodobnie złym pomysłem.
Stormsweeper
18
Działa to tylko wtedy, gdy rozmiar czcionki jest domyślny (nieokreślony, lub 1em, lub 100%). Jeśli ustawisz niestandardowy rozmiar czcionki, możesz ustawić font-sizewe fragmencie, 16pxaby uniknąć automatycznego powiększania.
Alan H.
Wiem, że to pytanie było skierowane do iPhone'a, ale jest ono bardziej kompatybilne na różnych platformach i w przyszłości więcej platform / urządzeń wypróbowałem podejście 16px, ale na tablecie z Androidem tylko zmniejszyłem efekt automatycznego powiększania. Ustawienie „1em” zgodnie z opisem w poście rozwiązało problem.
toddles_fp
3
Ani 1emteż nie 1remjest właściwym rozwiązaniem, ponieważ oba mogą być mniejsze niż, 16pxa Safari wymaga przynajmniej 16pxnie powiększania.
Finezja
2
użyłem rozwiązania rzutni, ale nie zadziałało, rozwiązanie 16px działa dobrze, ale 16px jest za duże dla inputboxa mojej witryny, czy jest jakieś trzecie rozwiązanie
Suneth Kalhara
21

Właściwym sposobem rozwiązania tego problemu jest zmiana rzutni meta na:

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

Milos Matic
źródło
32
Niekoniecznie jest to „właściwy” sposób zapobiegania temu zachowaniu. Mobilne Safari powiększa się, jeśli tekst zostanie uznany za zbyt mały, aby go przeczytać. Całkowite wyłączenie powiększania jest trudne i uniemożliwia użytkownikom interakcję ze stroną w sposób, którego mogą się spodziewać.
AlecRust
3
Najwyraźniej w iOS10 Apple zmieniło właściwość maksymalnej skali, aby nie była już przestrzegana, pozwalając wszystkim stronom na powiększanie niezależnie od jej ustawienia.
Wolfr
3
Działa to dla wersji iOS 10 20 / września 2016 ... przynajmniej działa na mojej aplikacji ... Dzięki !!! Zanim użyłem <meta name = "viewport" content = "width = szerokość-urządzenia, początkowa-skala = 1, minimalna-skala = 1 , maksymalna-skala = 1"> Ale przełączyłem ją na linię w odpowiedzi i zadziałało ...
eljamz
1
„Upewnij się, że powiększenie ściśnięcia przeglądarki nie jest blokowane przez element meta rzutni strony, aby można go było użyć do powiększenia strony do 200%. Należy unikać ograniczających wartości skalowalnych przez użytkownika i atrybutów tego elementu w maksymalnej skali”. w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon
Widziałem komentarze, jak niektóre z tych metatagów nie działają na iOS 10 i wiem, że powyższe działa przynajmniej w Chrome na iOS. :) Dzięki!
cbloss793
16

Nie ma czystego sposobu na znalezienie, ale oto hack ...

1) Zauważyłem, że zdarzenie najechania kursorem następuje przed powiększeniem, ale powiększenie następuje przed zdarzeniem przerwania lub skupienia.

2) Możesz dynamicznie zmieniać znacznik okienka META za pomocą javascript (patrz Włączanie / wyłączanie powiększania na iPhonie Safari za pomocą Javascript? )

Wypróbuj to (pokazane w jquery dla zwięzłości):

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

To zdecydowanie hack ... mogą zdarzyć się sytuacje, w których najechanie myszą / opuszczenie nie zawsze łapie wejścia / wyjścia, ale działało dobrze w moich testach i jest dobrym początkiem.

dlo
źródło
5
Nie jestem pewien, kiedy zachowanie Safari mogło się zmienić, ale teraz (iOS6.0.1) mousedown dzieje się przed autozoomem. Tak więc w moim poprzednim rozwiązaniu powiększanie jest zbyt wcześnie włączane. Nie znalazłem odpowiedniego rozwiązania, ponieważ wszystkie zdarzenia, które próbowałem, mają miejsce przed powiększeniem. Możesz ponownie włączyć powiększenie po naciśnięciu klawisza lub rozmyciu, ale istnieją pewne scenariusze, których może to przegapić (na przykład, jeśli użytkownik chce ręcznie powiększyć, zanim zacznie coś pisać).
dlo
14

Ostatnio (dzisiaj: D) musiałem zintegrować to zachowanie. Aby nie wpływać na oryginalne pola projektowe, w tym kombinację, zdecydowałem się zastosować transformację w centrum pola:

input[type="text"]:focus, input[type="password"]:focus,
textarea:focus, select:focus {
  font-size: 16px;
}
piouPiouM
źródło
Do Twojej wiadomości, działało to dobrze na moim iPhonie 5 z iOS 6, ale na iPhonie 4 z iOS 5 w trybie pionowym stylizacja ostrości została zastosowana po wystąpieniu powiększenia. Może dzieje się coś subtelnego, nie badałem dalej.
Vish
Chcę tylko powiedzieć, że mam wiele różnych zapytań używających zoomu, aby przyspieszyć programowanie, a zależnie od tego, ile powiększenia określi, ile potrzebuję rozmiaru czcionki
mike
: focus nie działało dla mnie iOS 10.2 iPhone 6, ale wejście [type = "text"]: hover działało dobrze.
Amirhossein Rzd
14

Dodaj skalowalne przez użytkownika = 0 do meta okienka ekranu w następujący sposób

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

Pracował dla mnie :)

Tuyen Cao
źródło
11
„Upewnij się, że powiększenie ściśnięcia przeglądarki nie jest blokowane przez element meta rzutni strony, aby można go było użyć do powiększenia strony do 200%. Należy unikać ograniczających wartości skalowalnych przez użytkownika i atrybutów tego elementu w maksymalnej skali”. w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon
9
To łamie zasady dostępności zdefiniowane przez W3.
Joshua Russell,
pracował dla mnie, jest to również najlepsze rozwiązanie dla mnie, ponieważ chcę swobodnie zmieniać rozmiary czcionek wejściowych poniżej 16 pikseli i nie chcę hacka JS
Blue Bot
13

Jak już wskazano wiele innych odpowiedzi, można to osiągnąć przez dodanie maximum-scaledo metatagu viewport. Jednak nie ma to negatywnego konsekwencji wyłączenie zoomu obsługi na urządzeniach z systemem Android . ( Nie wyłącza powiększania użytkownika na urządzeniach iOS od wersji 10 ).

Możemy użyć JavaScript, aby dynamicznie dodawać maximum-scaledo meta, viewportgdy urządzenie jest iOS. Osiąga to to, co najlepsze z obu światów: pozwalamy użytkownikowi powiększać i zapobiegać powiększaniu pól tekstowych przez iOS.

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

Kod:

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();
}
Oliver Joseph Ash
źródło
dlaczego tworzysz kopię addMaximumScaleToMetaViewport? Czy to tylko z powodów semantycznych?
Pherrymason
Tak, wystarczy odwzorować funkcję na inną nazwę, aby było jasne, w jaki sposób jest używana.
Oliver Joseph Ash,
8

Włamanie Javascript, które działa na iOS 7. Jest to oparte na odpowiedzi @dlo, ale zdarzenia najechania myszką i mouseout są zastąpione przez touchstart i touchend. Zasadniczo ten skrypt dodaje pół sekundy, zanim powiększenie włączy się ponownie, aby zapobiec powiększaniu.

$("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" />');
} 
Ilkka R.
źródło
To działało dla mnie najlepiej. Ale zmieniłem zdarzenia touchstart / touchend na jedno zdarzenie „focus” zarówno z zoomDisable, jak i zoomEnable.
Justin Cloud,
Dodanie opóźnienia wydaje się działać całkiem dobrze w nowszych wersjach iOS, ale interesujące jest to, że nie działa zbyt dobrze, gdy jest ustawiony na 250ms. To sugeruje, że w niektórych okolicznościach 500 ms może również nie działać, ale jeśli działa przez większość czasu, myślę, że to lepiej niż w ogóle nie działać. Dobre myślenie.
dlo
7

To działało dla mnie:

input, textarea {
    font-size: initial;
}

źródło
Całkiem proste, ale czy jest jakiś sposób, aby kontrolować, jaki jest ten „początkowy” rozmiar?
2540625
Nie testowałem tego, ale powinien to być sposób na kontrolowanie rozmiaru czcionki. (daj mi znać, czy to działa, a ja zaktualizuję odpowiedź) body {font-size: 20px; } input {font-size: inherit; }
7

Użyłem powyższego rozwiązania Christiny, ale z małą modyfikacją bootstrap i inną zasadą, która ma zastosowanie do komputerów stacjonarnych. Domyślny rozmiar czcionki Bootstrap to 14px, co powoduje powiększenie. Poniżej zmieniono na 16px dla „form form” w Bootstrap, zapobiegając powiększeniu.

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

I z powrotem do 14px dla przeglądarek nieprzeznaczonych na urządzenia mobilne.

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

Próbowałem użyć .form-control: focus, który pozostawił go na 14px, z wyjątkiem fokusa, który zmienił go na 16px i nie naprawił problemu z powiększeniem w iOS8. Przynajmniej na moim iPhonie korzystającym z iOS8 rozmiar czcionki musi wynosić 16 pikseli, aby iPhone nie mógł powiększyć strony.

Tanny O'Haley
źródło
6

Zrobiłem to również z 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'));
});

Oczywiście niektóre inne elementy interfejsu mogą wymagać dostosowania, jeśli ten 16pxrozmiar czcionki psuje projekt.

Nicolas Hoizey
źródło
4
To jest eleganckie. To jest stylizacja. Nie mam słów. Sprytne podejście.
crowjonah
@Wolfr próbowałeś na prawdziwym urządzeniu?
Nicolas Hoizey,
1
To działało dla nas na iOS 12. Najbardziej podoba mi się to podejście zamiast robienia transformacji css i ujemnych marginesów.
anonimowy-jeden
6

Po pewnym czasie próbowałem wymyślić to rozwiązanie

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

W „mousedown” ustawia rozmiar czcionki wejściowej na 16px. Zapobiegnie to powiększeniu. Podczas fokusu zmienia rozmiar czcionki z powrotem do wartości początkowej.

W przeciwieństwie do rozwiązań opublikowanych wcześniej, pozwoli ci to ustawić rozmiar czcionki tekstu na cokolwiek chcesz.

jirikuchta
źródło
Ten naprawdę działa dla mnie, zwłaszcza, że ​​w nowszych wersjach iOS nie można używać metatagu widoku do wyłączenia powiększania.
mparizeau
Potwierdzono pracę na iOS 12.1, dzięki
Ziki
6

Po przeczytaniu prawie każdej linii tutaj i przetestowaniu różnych rozwiązań, dzięki wszystkim, którzy udostępnili swoje rozwiązania, wymyśliłem, przetestowałem i pracowałem dla mnie na 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;}
}

Ma jednak pewne wady, zauważalnie „przeskakuje” w wyniku szybkiej zmiany rozmiaru czcionki występującej między stanami „najechania” i „najechania” - oraz wpływu przerysowania na wydajność

l3bel
źródło
Dziękujemy za opinię, @MikeBoutin. Czy możesz podzielić się swoją env (wersja urządzenia / iOS)?
l3bel
6

Zainspirowany odpowiedzią @jirikuchta rozwiązałem ten problem, dodając trochę CSS:

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

Bez JS i nie zauważam żadnego flasha ani nic takiego.

Warto zauważyć, że viewportz maximum-scale=1również działa, ale nie wtedy, gdy strona jest ładowana jako iframe, lub jeśli masz jakiś inny skrypt modyfikowania viewportitp

Meligy
źródło
4

Pseudoelementy, takie jak :focus, nie działają tak jak kiedyś. W systemie iOS 11 można dodać prostą deklarację resetowania przed głównymi stylami (pod warunkiem, że nie zastąpisz ich mniejszym rozmiarem czcionki).

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

Warto wspomnieć, że w przypadku bibliotek CSS, takich jak Tachyons.css, łatwo jest przypadkowo zastąpić rozmiar czcionki.

Na przykład klasa: f5jest równoważna z:, fontSize: 1remco jest w porządku, jeśli domyślną skalą czcionki jest.

Jednak: jeśli wybierzesz klasę rozmiaru czcionki: f6będzie to równoważne z fontSize: .875remmałym wyświetlaczem w górę. W takim przypadku musisz dokładniej określić swoje deklaracje resetowania:


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

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

/* not small */

}
Scott Phillips
źródło
3

Nawiasem mówiąc, jeśli używasz Bootstrap , możesz po prostu użyć tego wariantu:

.form-control {
  font-size: 16px;
}
Bohdan Vorona
źródło
3

Musiałem „naprawić” problem automatycznego powiększania do kontroli formularzy dla witryny holenderskiego uniwersytetu (która używała 15px w kontrolkach formularzy). Wymyśliłem następujący zestaw wymagań:

  • użytkownik musi nadal mieć możliwość powiększania
  • rozmiar czcionki musi pozostać taki sam
  • brak błysków tymczasowo odmiennych stylizacji
  • brak wymagań jQuery
  • musi działać na najnowszym iOS i nie może utrudniać żadnej innej kombinacji OS / urządzenia
  • jeśli to możliwe, nie ma limitów czasu magicznych, a jeśli to konieczne, poprawnie wyczyść liczniki

Oto, co do tej pory wymyśliłem:

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

Niektóre uwagi:

  • Pamiętaj, że do tej pory testowałem go tylko na iOS 11.3.1, ale wkrótce przetestuję go na kilku innych wersjach
  • Wykorzystanie zdarzeń focusIn oznacza, że ​​wymaga co najmniej iOS 5.1 (ale widzę, że strony, które tworzymy działające w wersjach iOS starszych niż 9, to i tak fajny bonus)
  • Korzystanie z delegowania zdarzeń, ponieważ wiele witryn, na których pracuję, ma strony, które mogą dynamicznie tworzyć formanty formularzy
  • Ustawienie eventListeners na element html (documentElement) tak, aby nie trzeba było czekać na udostępnienie treści (nie chcę zawracać sobie głowy sprawdzaniem, czy dokument jest w stanie gotowym / załadowanym, lub trzeba czekać na zdarzenie DOMContentLoaded)
Spellcoder
źródło
3

Zamiast po prostu ustawić rozmiar czcionki na 16px, możesz:

  1. Nadaj styl polu wejściowemu, aby było większe niż jego zamierzony rozmiar, umożliwiając ustawienie logicznej wielkości czcionki na 16px.
  2. Użyj scale()transformacji CSS i marginesów ujemnych, aby zmniejszyć pole wejściowe do odpowiedniego rozmiaru.

Załóżmy na przykład, że twoje pole wejściowe jest oryginalnie stylowane za pomocą:

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

Jeśli powiększysz pole, zwiększając wszystkie wymiary o 16/12 = 133,33%, zmniejsz użycie scale() o = 75%, pole wejściowe będzie miało poprawny rozmiar wizualny (i rozmiar czcionki) i nie będzie powiększenia skupiać.

Tak jak scale() wpływa to tylko na rozmiar wizualny, konieczne będzie również dodanie ujemnych marginesów, aby zmniejszyć logiczny rozmiar pola.

Dzięki temu 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%;
}

pole wejściowe będzie miało logiczny rozmiar czcionki 16px, podczas gdy wydaje się, że zawiera tekst 12px.

Mam wpis na blogu, w którym zagłębiam się nieco bardziej szczegółowo, i mam ten przykład jako widoczny HTML:
Brak powiększenia wejściowego w Safari na iPhonie, idealny sposób na piksel

Jeffery To
źródło
3

Nawet z tymi odpowiedziami zajęło mi trzy dni, aby dowiedzieć się, co się dzieje, i być może będę potrzebować rozwiązania w przyszłości.

Moja sytuacja była nieco inna niż opisana.

W moim miałem na stronie tekst, który można zadowalać. Gdy użytkownik kliknął RÓŻNĄ sekcję div, przycisk sortowania, automatycznie zaznaczyłem jakiś tekst w edytowalnej div (zakres zaznaczenia, który wcześniej został zapisany i wyczyszczony), uruchomiłem polecenie tekstowe execCommand dla tego wyboru i wyczyściłem go ponownie.

Umożliwiło mi to niewidoczną zmianę kolorów tekstu w oparciu o interakcje użytkownika z divami kolorów w innym miejscu na stronie, przy jednoczesnym zachowaniu zaznaczenia zaznaczenia, aby mógł widzieć kolory we właściwym kontekście.

Cóż, w Safari na iPadzie kliknięcie div koloru spowodowało pojawienie się klawiatury ekranowej i nic, co zrobiłem, nie zapobiegłoby.

W końcu zorientowałem się, jak robi to iPad.

Nasłuchuje sekwencji dotknięcia i dotknięcia, która wyzwala zaznaczenie edytowalnego tekstu.

Gdy taka kombinacja się pojawi, pokazuje klawiaturę ekranową.

W rzeczywistości wykonuje powiększenie dolly, w którym powiększa leżącą pod nim stronę, jednocześnie powiększając edytowalny tekst. Zajęło mi dzień, aby zrozumieć, co widzę.

Tak więc rozwiązaniem, które zastosowałem, było przechwycenie zarówno dotknięcia palcem, jak i dotknięcia tych konkretnych kolorów. W obu programach obsługi zatrzymuję propagację i propagację i zwracam wartość false. Ale w zdarzeniu dotkniętym wyzwalam to samo zachowanie, które wywołało kliknięcie.

Tak więc wcześniej Safari uruchamiało coś, co moim zdaniem było „touchstart”, „mousedown”, „touchend”, „mouseup”, „click”, a ze względu na mój kod zaznaczenie tekstu w tej kolejności.

Nowa sekwencja z powodu przechwytywania to po prostu zaznaczenie tekstu. Wszystko inne zostaje przechwycone, zanim Safari może je przetworzyć i wykonać czynności związane z klawiaturą. Przechwyty touchstart i touchchend zapobiegają również wyzwalaniu zdarzeń myszy, a w kontekście jest to całkowicie w porządku.

Nie znam prostszego sposobu na opisanie tego, ale myślę, że warto go mieć tutaj, ponieważ znalazłem ten wątek w ciągu godziny od pierwszego napotkania problemu.

Jestem 98% pewien, że ta sama poprawka będzie działać z polami wprowadzania i wszystkim innym. Przechwytuj zdarzenia dotykowe i przetwarzaj je osobno, nie pozwalając na ich propagację lub bąbelkowanie, i rozważ dokonanie wyboru po krótkim czasie, aby upewnić się, że Safari nie rozpozna sekwencji jako wyzwalacza klawiatury.

JBlitzen
źródło
To świetne wytłumaczenie tego, co robi safari. Dzięki!
Jeremy
2

Widzę, że ludzie tutaj robią dziwne rzeczy za pomocą JavaScript lub funkcji rzutni i wyłączają wszystkie ręczne powiększanie na urządzeniach. Moim zdaniem nie powinno to być rozwiązaniem. Dodanie tego fragmentu kodu CSS spowoduje wyłączenie automatycznego powiększania w systemie iOS bez zmiany rozmiaru czcionki na stałą liczbę, np. 16 pikseli.

Domyślnie używam 93,8% (15 pikseli) czcionek w polach wejściowych, a po dodaniu fragmentu kodu CSS pozostaje on na poziomie 93,8%. Nie musisz zmieniać na 16px ani ustawiać go na stały numer.

input[type="text"]:focus,
textarea:focus {
    -webkit-text-size-adjust: 100%;
}
Jack Ottermans
źródło
5
To nie działa dla mnie, przetestowane zarówno z najnowszym iOS 6, jak i iOS 9.2.1. Oto minimalna odtwarzalna strona: pastebin.com/bh5Zhe9h Nadal powiększa ostrość. Dziwne, że został opublikowany w 2015 roku i został jeszcze oceniony, ale nie działa w iOS 6.
Alexandre Dieulot
2

Ustawienie rozmiaru czcionki (dla pól wprowadzania) równego rozmiarowi czcionki wydaje się być tym, co uniemożliwia przeglądarce pomniejszenie lub powiększenie. Sugeruję użycie jej font-size: 1remjako bardziej eleganckiego rozwiązania.

Sindiploma
źródło
1

Ponieważ automatyczne powiększanie (bez pomniejszania) jest wciąż denerwujące na iPhonie, oto JavaScript oparty na sugestii dlo, działającej z ostrością / rozmyciem.

Powiększanie jest wyłączone, gdy tylko wprowadzanie tekstu zostanie zmodyfikowane i ponownie włączone, gdy wejście zostanie pozostawione.

Uwaga: Niektórzy użytkownicy mogą nie docenić edycji tekstu przy małym wprowadzeniu tekstu! Dlatego osobiście wolę zmienić rozmiar tekstu wejściowego podczas edycji (patrz kod poniżej).

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

Poniższy kod zmieni rozmiar tekstu wejściowego na 16 pikseli (obliczony, tj. W bieżącym rozmiarze powiększenia), gdy element jest aktywny. iPhone nie będzie zatem automatycznie powiększał.

Uwaga: Współczynnik powiększenia jest obliczany na podstawie window.innerWidth i wyświetlacza iPhone'a z 320 pikselami. Dotyczy to tylko iPhone'a w trybie pionowym.

<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>
BurninLeo
źródło
1

Znalezienie go zajęło mi trochę czasu, ale oto najlepszy kod, jaki znalazłem ...... 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));
});
Stephen Walsh
źródło
1

Na podstawie odpowiedzi Stephena Walsha ... Ten kod działa bez zmiany rozmiaru czcionki na fokus (który wygląda kiepsko), a ponadto nadal działa z FastClick , który sugeruję dodanie do wszystkich witryn mobilnych, aby pomóc w „zgryźliwym”. Dostosuj „szerokość rzutni” do swoich potrzeb.

// 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)
    });
skalisty
źródło
Jeśli użytkownik powiększył już trochę widok przed kliknięciem kontrolki wprowadzania danych, czy to rozwiązanie spowodowałoby nagle „cofnięcie powiększenia” ekranu?
Bruno Torquato,
Tak, ale nie wygląda bardziej wstrząsająco niż poprzedni efekt „powiększenia”, który pojawiał się za każdym razem, gdy użytkownik kliknął dane wejściowe.
Pete,
1

W komentarzu do górnej odpowiedzi na temat ustawienia rozmiaru czcionki na 16px zapytano, jak to jest rozwiązanie, co jeśli chcesz większą / mniejszą czcionkę.

Nie wiem o was wszystkich, ale używanie px do rozmiarów czcionek nie jest najlepszym rozwiązaniem, powinieneś ich używać.

Ten problem wystąpił w mojej responsywnej witrynie, w której moje pole tekstowe jest większe niż 16 pikseli. Miałem kontener formularza ustawiony na 2rem i moje pole wejściowe ustawione na 1.4em. W moich zapytaniach mobilnych zmieniam rozmiar czcionki HTML w zależności od okienka ekranu. Ponieważ domyślnym kodem HTML jest 10, moje pole wejściowe oblicza na pulpicie 28 pikseli

Aby usunąć automatyczne powiększanie, musiałem zmienić dane wejściowe na 1.6em. To zwiększyło mój rozmiar czcionki do 32px. Tylko nieco wyżej i prawie niezauważalnie. Na iPhonie 4 i 5 zmieniam rozmiar czcionki HTML na 15px dla portretu i z powrotem na 10px dla krajobrazu. Wygląda na to, że najsłabszym punktem dla tego rozmiaru piksela było 48 pikseli, dlatego zmieniłem z 1,4 em (42 piksele) na 1,6 em (48 pikseli).

Musisz znaleźć najodpowiedniejszy rozmiar czcionki, a następnie przekonwertować go do tyłu w rozmiarach rem / em.

Jon Tinsman
źródło
1

Oto hack, którego użyłem w jednym z moich projektów:

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

Skończyłem z początkowymi stylami i skalą, której chciałem, ale nie miałem ostrości na powiększeniu.

magom001
źródło