Nonaktifkan Zoom Otomatis pada input "Teks" tag - Safari di iPhone

541

Saya membuat halaman HTML <input>dengan tag type="text". Ketika saya mengkliknya menggunakan Safari di iPhone, halaman menjadi lebih besar (zoom otomatis). Adakah yang tahu cara menonaktifkan ini?

Eduardo Montenegro
sumber
8
Untuk semua pengguna Bootstrap Twitter yang mendarat di sini: lihat juga masalah Github ini .
Jeroen
7
Saya pikir @daxmacrog menjawab dengan tepat jawaban yang Anda inginkan, apakah Anda bersedia menerimanya sehingga dapat naik ke atas dan menyimpan banyak pengerjaan ulang dari orang yang membaca semua ini? 2018 Jawaban: stackoverflow.com/a/46254706/172651
Evolve
@Evolve jawaban yang Anda bicarakan tentang fungsi pinch and zoom Android. Jawaban daxmacrog cacat.
MH
4
Saya bersumpah, Apple menciptakan fitur-fitur ini hanya untuk mengacaukan pikiran kita.
Andrew Koster
@AndrewKoster, saya setuju dengan Anda bahkan sekarang di tahun 2020.
Ashok

Jawaban:

492

Browser akan memperbesar jika ukuran font kurang dari 16pxdan ukuran font default untuk elemen formulir adalah 11px(setidaknya di Chrome dan Safari).

Selain itu, selectelemen harus memiliki focuspseudo-class terpasang.

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

Ini tidak perlu menggunakan semua di atas, Anda dapat hanya gaya elemen yang Anda butuhkan, misalnya: hanya text, number, dan textarea:

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

Solusi alternatif untuk mewarisi elemen input dari gaya induk:

body {
  font-size: 16px;
}
input[type="text"] {
  font-size: inherit;
}
srikanth
sumber
81
Hanya untuk mendapatkan semuanya tertutup: 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 Anda perlu menggunakan select:focus. Sedang mengalami masalah yang sama juga.
DGibbs
141
Saya tidak mengerti, bagaimana cara memperbaikinya? Bagaimana jika saya ingin ukuran font yang lebih kecil / lebih besar?
bryan
47
cara yang tepat adalah mengubah tag meta ke: <meta name = "viewport" content = "width = lebar perangkat, skala awal = 1, skala maksimum = 1, skala pengguna = 0" />
Milos Matic
37
@MilosMatic Dalam kebanyakan kasus mungkin bukan solusi yang baik, karena itu sepenuhnya mencegah pengguna dari skala halaman. Berpotensi lebih menyebalkan bagi pengunjung Anda.
BadHorsie
363

Anda dapat mencegah Safari memperbesar secara otomatis pada bidang teks selama input pengguna tanpa menonaktifkan kemampuan pengguna untuk mencubit zoom. Cukup tambahkan maximum-scale=1tetapi tinggalkan atribut skala pengguna yang disarankan dalam jawaban lain.

Ini adalah opsi yang bermanfaat jika Anda memiliki formulir di lapisan yang "mengapung" di sekitar jika diperbesar, yang dapat menyebabkan elemen UI penting bergerak dari layar.

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

daxmacrog
sumber
65
Ini adalah solusi 2018+. Suara positif seperti ini tergantung pada hidup Anda.
Henrik Petterson
17
Ini akan mematahkan kemampuan zoom perangkat Android
fen1ksss
4
@daxmacrog, Anda benar, tetapi OP tidak menyebutkan apakah dia ingin memecah android dengan mengizinkan perilaku yang diperlukan. Di sinilah secara pribadi saya mengambil opsi yang salah. Tentu saja, lebih baik untuk ditentukan.
fen1ksss
13
@HenrikPetterson Ini melakukan lebih dari sekedar menonaktifkan zoom otomatis seperti yang ditentukan oleh OP, ini juga menonaktifkan pinch zoom. Jadi saya tidak berpikir itu solusi 2018+.
André Werlang
4
@ AndréWerlang Itu tidak akurat. Sebagaimana dinyatakan dengan jelas dalam jawaban, solusi ini tidak menonaktifkan zoom cubit di Safari (atau Firefox), yang merupakan pertanyaan OP. Tetapi seperti yang ditunjukkan dalam komentar sebelumnya, ini menonaktifkan zoom pengguna pada perangkat Android dan Chrome di iOS.
daxmacrog
223
@media screen and (-webkit-min-device-pixel-ratio:0) { 
  select:focus,
  textarea:focus,
  input:focus {
    font-size: 16px;
    background: #eee;
  }
}

Baru: iOS masih akan memperbesar, kecuali jika Anda menggunakan 16px pada input tanpa fokus.

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

Saya menambahkan latar belakang karena iOS tidak menambahkan latar belakang pada pilih.

Christina
sumber
9
Ini berfungsi tidak hanya untuk safari di iOS (iphone / ipad / ipod), tetapi juga Safari / OSX dan Chrome (windows dan Mac). Jadi, jika Anda mencoba menargetkan iphone secara spesifik, ini tidak akan berhasil.
Redtopia
31
Mengapa semua orang mengatakan 16px tetapi tidak ada yang mau menyebutkan mengapa sebenarnya 16px? Mengapa angka sewenang-wenang seperti itu? Mengapa kita harus mengatur ukuran teks bidang formulir kami menjadi 16px dan tidak .. katakanlah 1.8rem atau 2.5em atau semacamnya? Apakah ini hanya bug bodoh dari OS berpemilik?
Beebee
14
@Beebee 100% ukuran font adalah 16px, default untuk sebagian besar jika tidak semua browser (desktop juga). IOS menggunakannya sebagai pengaturan standar mungkin karena ukurannya yang nyaman untuk membaca. Mengapa diatur dengan cara ini saya tidak repot-repot mencari, tidak peduli.
Christina
5
Gunakan @media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)untuk membatasi efek ke iPhone, tetapi jangan memodifikasi situs web saat dilihat di Chrome.
BurninLeo
9
Alih-alih menggunakan kueri media, Anda harus menggunakan @supports (-webkit-overflow-scrolling: touch), karena fitur css ini hanya ada di iOS
James Moran
189

Jika situs web Anda dirancang dengan tepat untuk perangkat seluler, Anda dapat memutuskan untuk tidak mengizinkan penskalaan.

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

Ini menyelesaikan masalah yang akan 'mengambang' di laman atau formulir seluler Anda.

Marcellino Bommezijn
sumber
123
Secara teknis benar, tetapi saya tidak setuju dengan alasannya. Menonaktifkan pembesaran pengguna pada situs yang dirancang dengan baik umumnya masih merupakan ide yang buruk.
Fer
20
"Dirancang dengan benar" sangat subyektif. Pertimbangkan tajuk tetap 50px di bagian atas situs yang sepenuhnya responsif dan akan berfungsi di semua browser. Memperbesar iOS Safari mematahkan posisi tajuk dan merusak hampir seluruh situs.
Redtopia
62
Menonaktifkan kemampuan zoom pengguna adalah praktik yang mengerikan dari perspektif UX dan harus benar-benar dihindari dengan cara apa pun. Mampu memperbesar dengan bebas adalah fitur aksesibilitas dasar, dan kontrol yang tidak boleh Anda ambil dari pengguna.
Gabriel Luethje
72
Di aplikasi seluler asli Anda tidak pernah mendapatkan kesempatan untuk memperbesar dan berfungsi dengan baik, mengapa webapp berbeda? Jika Anda mengatur ukuran font dan tinggi garis yang sesuai dengan kontras yang jelas, Anda akan baik-baik saja.
jotav
39
Mereka yang menggunakan argumen 'tidak apa-apa di aplikasi asli' mengabaikan fakta bahwa aplikasi asli yang dibuat dengan baik mematuhi pengaturan aksesibilitas tingkat OS seperti ukuran teks. Pengguna yang lebih tua dan penglihatan buruk dapat dan memang menggunakan ukuran font OS-wide yang sangat besar karena mereka perlu . Aplikasi web sering tidak atau tidak dapat mematuhi pengaturan ini, oleh karena itu memungkinkan fungsionalitas aksesibilitas built-in web browser seperti zoom sangat penting. Apa pun yang menurut Anda mudah dibaca, percayalah, ada orang yang tidak akan merasa cukup jelas. Jangan tidak mengambil pilihan ini jauh dari pengguna jika Anda menghargai kegunaan.
Ryan Williams
72

Singkatnya jawabannya adalah: setel ukuran font elemen formulir ke setidaknya 16px

Nik
sumber
Ya, ini jelas merupakan praktik terbaik untuk menghindari pembesaran pada perangkat seluler. Tidak ada js, tidak ada peretasan, tidak ada solusi sama sekali. Tetapi bahkan dengan 16px saya melihat sedikit perbesaran di halaman saya jadi saya mencoba 17px, 18px ... untuk melihat apa yang terjadi.
ed1nh0
8
Ini adalah praktik terbaik untuk mendeklarasikan 100% pada body, tombol, input, textarea dan elemen terpilih. Ini memungkinkan pengguna untuk menetapkan default yang bukan 16px yang dikirimkan bersama browser. Seseorang yang mengalami kesulitan membaca di layar mungkin menetapkan default ke 18px atau 20px. Anda tidak ingin mengesampingkan pilihan mereka dengan memaksa 16px pada mereka. Namun, ketika berbicara tentang iOS, mereka membuat keputusan untuk meningkatkan nilai apa pun yang menurut HIG terlalu kecil. Sayangnya sepertinya tidak menginterpretasikan nilai 100%, jadi kami macet menambahkan secara default untuk menenangkannya.
J. Hogue
RE iOS Safari, pada komentar ini tampaknya Safari dengan benar menginterpretasikan font-size: 100%nilai dan mengambil 16px yang diperlukan.
Nathan Lafferty
36
input[type='text'],textarea {font-size:1em;}
penyapu badai
sumber
3
Perhatikan bahwa pengaturan yang dapat diskalakan ke tidak akan menonaktifkan semua pembesaran, yang mungkin merupakan ide yang buruk.
stormsweeper
18
Ini hanya berfungsi jika ukuran font tubuh Anda adalah default (tidak ditentukan, atau 1em, atau 100%). Jika Anda mengatur ukuran font khusus, Anda dapat mengatur font-sizedalam cuplikan Anda 16pxuntuk menghindari pembesaran otomatis.
Alan H.
Saya tahu pertanyaan ini diarahkan pada iPhone tetapi ini lebih kompatibel lintas platform dan ke masa depan lebih banyak platform / perangkat, saya mencoba pendekatan 16px tetapi pada tablet Android hanya mengurangi efek zoom otomatis. Pengaturan ke '1em' seperti yang ditentukan dalam pos memecahkan masalah.
toddles_fp
3
Tidak ada 1emjuga 1remsolusi yang tepat karena keduanya bisa kurang dari 16pxdan Safari membutuhkan setidaknya 16pxuntuk tidak memperbesar.
Finesse
2
saya menggunakan solusi viewport tetapi tidak berfungsi, solusi 16px berfungsi dengan baik, tetapi 16px terlalu besar untuk inputbox situs saya, apakah ada solusi ke 3
Suneth Kalhara
21

Cara yang tepat untuk memperbaiki masalah ini adalah mengubah meta viewport ke:

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

Milos Matic
sumber
32
Ini belum tentu cara yang "tepat" untuk mencegah perilaku ini. Mobile Safari memperbesar jika teks dianggap terlalu kecil untuk dibaca. Menonaktifkan pembesaran secara bersamaan adalah hal yang berat dan mencegah pengguna untuk dapat berinteraksi dengan halaman Anda dengan cara yang mereka harapkan.
AlecRust
3
Rupanya di iOS10 Apple mengubah properti skala maksimum untuk tidak dihormati lagi, memungkinkan semua situs untuk memperbesar terlepas dari pengaturannya.
Wolfr
3
Ini berfungsi untuk versi iOS10 20 / September / 2016 ... setidaknya bekerja di aplikasi saya ... Terima kasih !!! Sebelum saya menggunakan <meta name = "viewport" content = "width = lebar perangkat, skala awal = 1, skala minimum = 1 , skala maksimum = 1"> Tapi saya beralih ke baris pada respons dan itu berhasil ...
eljamz
1
"Pastikan zoom penjepit browser tidak diblokir oleh elemen meta viewport halaman sehingga dapat digunakan untuk memperbesar halaman hingga 200%. Nilai terbatas untuk atribut skalabel yang dapat diukur pengguna dan skala maksimum dari elemen meta ini harus dihindari." w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon
Saya telah melihat komentar bagaimana beberapa meta tag ini tidak berfungsi di iOS 10 dan saya tahu bahwa setidaknya di atas berfungsi di Chrome untuk iOS. :) terima kasih!
cbloss793
16

Tidak ada cara bersih yang bisa saya temukan, tapi ini sebuah retas ...

1) Saya perhatikan bahwa peristiwa mouseover terjadi sebelum zoom, tetapi zoom terjadi sebelum mousedown atau acara fokus.

2) Anda dapat secara dinamis mengubah tag viewport META menggunakan javascript (lihat Mengaktifkan / menonaktifkan zoom pada iPhone safari dengan Javascript? )

Jadi, coba ini (ditunjukkan dalam jquery untuk kekompakan):

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

Ini jelas merupakan peretasan ... mungkin ada situasi di mana mouseover / down tidak selalu menangkap entri / keluar, tetapi itu bekerja dengan baik dalam pengujian saya dan merupakan awal yang solid.

dlo
sumber
5
Tidak yakin kapan perilaku Safari mungkin telah berubah, tetapi mousedown sekarang (iOS6.0.1) sedang terjadi sebelum Autozoom. Jadi dalam solusi saya sebelumnya, zooming diaktifkan kembali terlalu cepat. Saya belum menemukan perbaikan yang memadai, karena semua peristiwa yang saya coba sekarang terjadi sebelum zoom. Anda dapat mengaktifkan kembali zoom pada keydown atau blur, tetapi ada beberapa skenario yang mungkin terlewatkan (seperti jika pengguna ingin memperbesar secara manual sebelum mereka mulai mengetik apa pun).
dlo
15

Tambahkan user-scalable = 0 ke meta viewport sebagai berikut

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

Bekerja untuk saya :)

Tuyen Cao
sumber
11
"Pastikan zoom penjepit browser tidak diblokir oleh elemen meta viewport halaman sehingga dapat digunakan untuk memperbesar halaman hingga 200%. Nilai terbatas untuk atribut skalabel yang dapat diukur pengguna dan skala maksimum dari elemen meta ini harus dihindari." w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon
9
Ini melanggar aturan aksesibilitas yang ditentukan oleh W3.
Joshua Russell
bekerja untuk saya, juga ini adalah solusi terbaik bagi saya karena saya ingin kebebasan untuk mengubah ukuran font input di bawah 16px dan tidak ingin hack JS
Blue Bot
14

Saya baru-baru ini (hari ini: D) harus mengintegrasikan perilaku ini. Agar tidak memengaruhi bidang desain asli, termasuk kombo, saya memilih untuk menerapkan transformasi pada fokus bidang:

input[type="text"]:focus, input[type="password"]:focus,
textarea:focus, select:focus {
  font-size: 16px;
}
piouPiouM
sumber
FYI, Ini bekerja dengan baik pada iphone 5 saya dengan iOS 6, tetapi pada iphone 4 dengan iOS 5 dalam mode potret, styling fokus diterapkan setelah zoom terjadi. Mungkin sesuatu yang halus terjadi, saya tidak menyelidiki lebih jauh.
Vish
Saya hanya ingin mengatakan bahwa saya memiliki banyak pertanyaan yang berbeda menggunakan zoom untuk membuat pengembangan berjalan lebih cepat dan tergantung pada seberapa banyak Anda memperbesar akan menentukan berapa banyak ukuran font yang Anda butuhkan, saya percaya
mike
: fokus tidak bekerja untuk saya iOS 10.2 iPhone 6, tetapi input [type = "text"]: hover bekerja dengan baik.
Amirhossein Rzd
13

Seperti yang telah ditunjukkan oleh banyak jawaban lain, ini dapat dicapai dengan menambahkan maximum-scaleke viewporttag meta . Namun, ini memiliki konsekuensi negatif dengan menonaktifkan zoom pengguna di perangkat Android . ( Ini tidak menonaktifkan zoom pengguna pada perangkat iOS sejak v10 .)

Kita dapat menggunakan JavaScript untuk menambahkan maximum-scalemeta secara dinamis viewportsaat perangkat iOS. Ini mencapai yang terbaik dari kedua dunia: kami memungkinkan pengguna untuk memperbesar dan mencegah iOS memperbesar ke bidang teks pada fokus.

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

Kode:

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
sumber
mengapa Anda membuat salinan addMaximumScaleToMetaViewport? Apakah hanya untuk alasan semantik?
Pherrymason
Ya, hanya memetakan fungsi ke nama yang berbeda sehingga jelas bagaimana itu digunakan.
Oliver Joseph Ash
8

Retas Javascript yang berfungsi pada iOS 7. Ini didasarkan pada jawaban @dlo tetapi acara mouseover dan mouseout digantikan oleh touchstart dan touchend events. Pada dasarnya skrip ini menambahkan batas waktu setengah detik sebelum zoom diaktifkan kembali untuk mencegah 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" />');
} 
Ilkka R.
sumber
Ini bekerja paling baik untuk saya. Tapi, saya mengubah acara touchstart / touchend menjadi satu acara 'fokus' dengan zoomDisable dan zoomEnable.
Justin Cloud
Menambahkan penundaan tampaknya bekerja dengan cukup baik pada versi iOS yang lebih baru, tetapi menarik bahwa itu tidak bekerja dengan baik ketika diatur ke 250ms. Itu mengisyaratkan bahwa dalam beberapa keadaan, 500 ms mungkin tidak berfungsi, tetapi jika itu berfungsi sebagian besar waktu saya kira itu lebih baik daripada tidak bekerja sama sekali. Pemikiran yang bagus.
dlo
7

Ini bekerja untuk saya:

input, textarea {
    font-size: initial;
}

sumber
Sederhana, tetapi apakah ada cara untuk mengontrol ukuran "awal" itu?
2540625
Saya belum mengujinya, tetapi ini harus menjadi cara untuk mengontrol ukuran font. (tolong beri tahu saya jika ini berhasil dan saya akan memperbarui jawaban saya) body {font-size: 20px; } input {font-size: inherit; }
7

Saya menggunakan solusi Christina di atas, tetapi dengan sedikit modifikasi untuk bootstrap dan aturan lain untuk diterapkan pada komputer desktop. Ukuran font default Bootstrap adalah 14px yang menyebabkan zoom. Berikut ini mengubahnya menjadi 16px untuk "kontrol bentuk" di Bootstrap, mencegah zoom.

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

Dan kembali ke 14px untuk browser non-seluler.

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

Saya mencoba menggunakan .form-control: focus, yang membuatnya pada 14px kecuali pada fokus yang mengubahnya menjadi 16px dan itu tidak memperbaiki masalah zoom dengan iOS8. Paling tidak pada iPhone saya menggunakan iOS8, ukuran font harus 16px sebelum fokus agar iPhone tidak memperbesar halaman.

Tanny O'Haley
sumber
6

Saya melakukan ini, juga dengan 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'));
});

Tentu saja, beberapa elemen lain di antarmuka mungkin harus diadaptasi jika 16pxukuran font ini merusak desain.

Nicolas Hoizey
sumber
4
Ini berkelas. Ini adalah stylin '. Saya kehabisan kata-kata. Pendekatan cerdas.
crowjonah
@ Wolfr apakah Anda mencoba perangkat yang sebenarnya?
Nicolas Hoizey
1
Ini bekerja untuk kita di iOS 12. Saya suka pendekatan ini yang terbaik daripada mucking sekitar dengan transformasi css dan margin negatif.
anonim-satu
6

Setelah beberapa saat mencoba saya datang dengan solusi ini

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

Pada "mousedown" itu mengatur ukuran font input ke 16px. Ini akan mencegah pembesaran. Pada acara fokus itu mengubah ukuran font kembali ke nilai awal.

Tidak seperti solusi yang diposting sebelumnya, ini akan memungkinkan Anda mengatur ukuran font input ke apa pun yang Anda inginkan.

jirikuchta
sumber
Yang ini benar-benar berfungsi untuk saya, terutama karena di versi iOS yang lebih baru Anda tidak dapat menggunakan meta tag viewport untuk menonaktifkan zoom.
mparizeau
Dikonfirmasi bekerja di iOS 12.1, terima kasih
Ziki
6

Setelah membaca hampir setiap baris di sini dan menguji berbagai solusi, ini, terima kasih kepada semua yang berbagi solusi mereka, apa yang saya hasilkan, uji dan bekerja untuk saya di 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;}
}

Ini memiliki beberapa kontra, meskipun, terasa "lompatan" sebagai akibat dari perubahan ukuran font cepat terjadi antara "hover" ed dan "fokus" ed negara - dan dampak redraw pada kinerja

lbel
sumber
Terima kasih atas tanggapan Anda, @MikeBoutin. Bisakah Anda membagikan ENV Anda (versi perangkat / iOS)?
l3bel
6

Terinspirasi oleh jawaban @jirikuchta, saya memecahkan masalah ini dengan menambahkan sedikit CSS ini:

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

Tidak ada JS, dan saya tidak melihat ada flash atau apa pun.

Perlu dicatat bahwa dengan viewportwith maximum-scale=1juga berfungsi, tetapi tidak ketika halaman dimuat sebagai iframe, atau jika Anda memiliki beberapa skrip lain yang memodifikasi viewport, dll.

Meligy
sumber
4

Elemen pseudo suka :focustidak berfungsi seperti biasanya. Dari iOS 11, deklarasi reset sederhana dapat ditambahkan sebelum gaya utama Anda (asalkan Anda tidak menimpanya dengan ukuran font yang lebih kecil).

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

Perlu disebutkan bahwa untuk pustaka CSS seperti Tachyons.css maka mudah untuk secara tidak sengaja menimpa ukuran font Anda.

Misalnya kelas: f5setara dengan:fontSize: 1rem yang baik-baik saja jika Anda tetap menggunakan skala font tubuh di default.

Namun: jika Anda memilih kelas ukuran font: f6ini akan sama dengan fontSize: .875remtampilan kecil di atas. Dalam hal itu, Anda harus lebih spesifik tentang deklarasi reset Anda:


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

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

/* not small */

}
Scott Phillips
sumber
3

Omong-omong, jika Anda menggunakan Bootstrap , Anda bisa menggunakan varian ini:

.form-control {
  font-size: 16px;
}
Bohdan Vorona
sumber
3

Saya harus "memperbaiki" perbesaran otomatis ke masalah kontrol formulir untuk situs web Universitas Belanda (yang menggunakan 15px dalam kontrol formulir). Saya datang dengan serangkaian persyaratan berikut:

  • pengguna harus tetap dapat memperbesar
  • ukuran font harus tetap sama
  • tidak ada kilatan gaya berbeda sementara
  • tidak ada persyaratan jQuery
  • harus bekerja pada iOS terbaru dan tidak menghalangi kombinasi OS / perangkat lainnya
  • jika mungkin tidak ada timeout ajaib, dan jika perlu, hapus timer dengan benar

Inilah yang saya kemukakan sejauh ini:

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

Beberapa catatan:

  • Perhatikan bahwa sejauh ini saya hanya mengujinya di iOS 11.3.1, tetapi akan segera mengujinya pada beberapa versi lain
  • Penggunaan fokusDalam acara berarti membutuhkan setidaknya iOS 5.1 (tapi saya melihat situs yang kami buat bekerja dalam versi iOS yang lebih lama sebagai 9 sebagai bonus keren)
  • Menggunakan delegasi acara karena banyak situs tempat saya bekerja memiliki halaman yang secara dinamis dapat membuat kontrol formulir
  • Mengatur eventListeners ke elemen html (documentElement) agar tidak harus menunggu agar body tersedia (tidak mau repot memeriksa apakah dokumen sudah siap / dimuat keadaan atau perlu menunggu acara DOMContentLoaded event)
Pemeriksa ejaan
sumber
3

Alih-alih hanya mengatur ukuran font ke 16px, Anda dapat:

  1. Gaya bidang input sehingga lebih besar dari ukuran yang dimaksudkan, memungkinkan ukuran font logis diatur ke 16px.
  2. Gunakan scale()transformasi CSS dan margin negatif untuk mengecilkan bidang input ke ukuran yang benar.

Misalnya, anggap bidang input Anda awalnya ditata dengan:

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

Jika Anda memperbesar bidang dengan meningkatkan semua dimensi sebesar 16/12 = 133,33%, kemudian mengurangi penggunaan sebesar 12/12 scale()= 75%, bidang input akan memiliki ukuran visual yang benar (dan ukuran font), dan tidak akan ada pembesaran pada fokus.

Karena scale()hanya memengaruhi ukuran visual, Anda juga perlu menambahkan margin negatif untuk mengurangi ukuran logis bidang.

Dengan CSS ini:

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

bidang input akan memiliki ukuran font logis 16px sementara tampaknya memiliki teks 12px.

Saya memiliki posting blog tempat saya membahas sedikit lebih detail, dan memiliki contoh ini sebagai HTML yang dapat dilihat:
Tidak ada input zoom di Safari di iPhone, pixel sempurna

Jeffery To
sumber
3

Bahkan dengan jawaban-jawaban ini, saya perlu tiga hari untuk mencari tahu apa yang sedang terjadi dan saya mungkin perlu solusinya lagi di masa depan.

Situasi saya sedikit berbeda dari yang dijelaskan.

Di tambang, saya memiliki beberapa teks yang dapat diedit di div di halaman. Ketika pengguna mengklik div BERBEDA, tombol macam, saya secara otomatis memilih beberapa teks di div yang dapat diedit (rentang pilihan yang sebelumnya telah disimpan dan dihapus), menjalankan perintah teks kaya perintah pada pilihan itu, dan membersihkannya lagi.

Ini memungkinkan saya untuk secara tak terlihat mengubah warna teks berdasarkan interaksi pengguna dengan div warna di tempat lain di halaman, sambil menjaga pemilihan yang biasanya disembunyikan untuk membiarkan mereka melihat warna dalam konteks yang tepat.

Nah, di Safari iPad, mengklik div warna mengakibatkan keyboard di layar muncul, dan tidak ada yang saya lakukan yang akan mencegahnya.

Saya akhirnya mengetahui bagaimana iPad melakukan ini.

Ini mendengarkan touchstart dan urutan touchend yang memicu pemilihan teks yang dapat diedit.

Ketika kombinasi itu terjadi, itu menunjukkan keyboard di layar.

Sebenarnya, ia melakukan dolly zoom di mana ia memperluas halaman yang mendasarinya saat memperbesar pada teks yang dapat diedit. Saya butuh satu hari hanya untuk memahami apa yang saya lihat.

Jadi solusi yang saya gunakan adalah mencegat touchstart dan touchend pada div warna tertentu. Dalam kedua penangan saya berhenti propagasi dan menggelegak dan mengembalikan false Tetapi dalam acara touchend saya memicu perilaku yang sama dengan klik yang dipicu.

Jadi, sebelumnya, Safari memicu apa yang saya pikir "touchstart", "mousedown", "touchend", "mouseup", "click", dan karena kode saya, pilihan teks, dalam urutan itu.

Urutan baru karena intersep hanyalah pemilihan teks. Segala sesuatu yang lain dicegat sebelum Safari dapat memprosesnya dan melakukan hal-hal keyboard-nya. Touchstart dan touchend intercepts mencegah peristiwa mouse untuk memicu juga, dan dalam konteks ini benar-benar baik-baik saja.

Saya tidak tahu cara yang lebih mudah untuk menggambarkan ini, tetapi saya pikir penting untuk memilikinya di sini karena saya menemukan utas ini dalam satu jam sejak pertama kali menemukan masalah ini.

Saya 98% yakin perbaikan yang sama akan bekerja dengan kotak input dan yang lainnya. Mencegah acara sentuh dan memprosesnya secara terpisah tanpa membiarkannya menyebar atau menggelembung, dan pertimbangkan untuk melakukan pilihan apa pun setelah batas waktu yang singkat hanya untuk memastikan Safari tidak mengenali urutan sebagai pemicu keyboard.

JBlitzen
sumber
Ini adalah penjelasan yang bagus tentang apa yang dilakukan safari. Terima kasih!
Jeremy
2

Saya melihat orang-orang di sini melakukan beberapa hal aneh dengan JavaScript atau fungsi viewport dan mematikan semua pembesaran perangkat secara manual. Itu seharusnya tidak menjadi solusi menurut saya. Menambahkan potongan CSS ini akan mematikan zoom otomatis di iOS tanpa mengubah ukuran font Anda ke nomor tetap seperti 16px.

Secara default, saya menggunakan ukuran font 93,8% (15px) pada kolom input dan dengan menambahkan potongan CSS saya ini tetap pada 93,8%. Tidak perlu mengubah ke 16px atau menjadikannya nomor tetap.

input[type="text"]:focus,
textarea:focus {
    -webkit-text-size-adjust: 100%;
}
Jack Ottermans
sumber
5
Ini tidak berfungsi untuk saya, diuji dengan iOS 6 dan iOS 9.2.1 terbaru. Berikut ini adalah halaman minimal yang dapat direproduksi: pastebin.com/bh5Zhe9h Masih diperbesar saat fokus. Aneh bahwa ini diposting pada tahun 2015 dan dibatalkan tetapi tidak berfungsi di iOS 6.
Alexandre Dieulot
2

Menyetel ukuran font (untuk bidang input) sama dengan ukuran font tubuh, tampaknya yang mencegah peramban memperkecil atau memperbesar. Saya sarankan untuk menggunakan font-size: 1remsebagai solusi yang lebih elegan.

sindiploma
sumber
1

Karena zoom-in otomatis (tanpa zoom-out) masih bersifat anonim di iPhone, inilah JavaScript berdasarkan saran dlo yang bekerja dengan fokus / blur.

Pembesaran dinonaktifkan segera setelah input teks difusi dan diaktifkan kembali saat input dibiarkan.

Catatan: Beberapa pengguna mungkin tidak menghargai mengedit teks dalam input teks kecil! Oleh karena itu, saya pribadi lebih suka mengubah ukuran teks input saat mengedit (lihat kode di bawah).

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

Kode berikut akan mengubah ukuran teks input menjadi 16 piksel (dihitung, yaitu, dalam ukuran zoom saat ini) selama elemen memiliki fokus. Karena itu iPhone tidak akan secara otomatis memperbesar.

Catatan: Faktor zoom dihitung berdasarkan window.innerWidth dan tampilan iPhone dengan 320 piksel. Ini hanya akan berlaku untuk iPhone dalam mode potret.

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

Butuh beberapa saat untuk menemukannya tetapi inilah kode terbaik yang saya temukan ...... 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
sumber
1

Berdasarkan jawaban Stephen Walsh ... Kode ini berfungsi tanpa mengubah ukuran font input pada fokus (yang terlihat lumpuh), ditambah lagi masih berfungsi dengan FastClick , yang saya sarankan tambahkan ke semua situs seluler untuk membantu menghadirkan "tajam". Sesuaikan "lebar viewport" Anda agar sesuai dengan kebutuhan Anda.

// 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)
    });
berbatu
sumber
Jika pengguna telah memperbesar sedikit sebelum mengklik kontrol input, apakah solusi ini akan menyebabkan viewport tiba-tiba "unzoom"?
Bruno Torquato
Ya, tetapi tidak terlihat lebih menggelegar daripada efek "zoom" sebelumnya yang terjadi setiap kali pengguna mengklik input.
Pete
1

Sebuah komentar untuk jawaban teratas tentang pengaturan ukuran font ke 16px bertanya bagaimana itu solusi, bagaimana jika Anda menginginkan font yang lebih besar / lebih kecil.

Saya tidak tahu tentang Anda semua, tetapi menggunakan px untuk ukuran font bukan cara terbaik, Anda harus menggunakan em.

Saya mengalami masalah ini di situs responsif saya di mana bidang teks saya lebih besar dari 16 piksel. Saya mengatur wadah formulir saya ke 2rem dan bidang input saya disetel ke 1.4em. Dalam kueri seluler saya, saya mengubah ukuran font html tergantung pada viewport. Karena html default adalah 10, bidang input saya menghitung hingga 28px di desktop

Untuk menghapus zoom-otomatis, saya harus mengubah input ke 1.6em. Ini meningkatkan ukuran font saya menjadi 32px. Hanya sedikit lebih tinggi dan hampir tidak terlihat. Di iPhone 4 & 5 saya mengubah ukuran font html saya menjadi 15px untuk potret dan kembali ke 10px untuk lanskap. Tampaknya sweet spot untuk ukuran piksel itu adalah 48px itulah sebabnya saya berubah dari 1.4em (42px) menjadi 1.6em (48px).

Hal yang perlu Anda lakukan adalah menemukan sweet spot pada ukuran font dan kemudian mengubahnya mundur dalam ukuran rem / em Anda.

Jon Tinsman
sumber
1

Ini adalah retas yang saya gunakan di salah satu proyek saya:

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

Berakhir dengan gaya dan skala awal yang saya inginkan tetapi tidak ada zoom pada fokus.

magom001
sumber