入力「テキスト」タグの自動ズームを無効にする-iPhoneのSafari


540

<input>タグが付いたHTMLページを作成しましたtype="text"。iPhoneのSafariを使用してクリックすると、ページが大きくなります(自動ズーム)。誰かがこれを無効にする方法を知っていますか?


8
ここにアクセスしたすべてのTwitter Bootstrapユーザーについては、このGithubの問題も参照してください。
Jeroen、2015年

7
私は@daxmacrogの答えがあなたが望むものに正確に答えると思います、あなたはそれを受け入れてもいいのでそれを上に上げて、これらすべてを読んでいる人々から多くのやり直しを節約できますか?2018回答:stackoverflow.com/a/46254706/172651
Evolve

@Evolveは、Androidのピンチ機能とズーム機能を壊しました。daxmacrogの回答に欠陥があります。
MH

4
私は誓います、Appleは私たちの頭を混乱させるためだけにこれらの反機能を作成します。
Andrew Koster

@AndrewKoster、私は2020年には今もあなたに同意
アショク

回答:


492

font-sizeが小さく、16pxフォーム要素のデフォルトのfont-sizeが11px(少なくともChromeとSafariでは)である場合、ブラウザはズームします。

さらに、select要素にはfocus疑似クラスがアタッチされている必要があります。

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

それは例えば、あなたが必要な要素だけでスタイルすることができ、上記のすべてを使用する必要はありません。ただtextnumbertextarea

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

入力要素に親スタイルを継承させる代替ソリューション:

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

81
すべてを網羅するために: 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 2013

8
@Nicを使用する必要がありますselect:focus。同じ問題も抱えていました。
DGibbs 2014年

141
わかりません。これはどのように修正しますか?小さい/大きいフォントサイズが必要な場合はどうなりますか?
ブライアン2015

47
適切な方法は、メタタグを次のように変更することです:<meta name = "viewport" content = "width = device-width、initial-scale = 1、maximum-scale = 1、user-scalable = 0" />
Milos Matic

37
@MilosMaticユーザーがページを拡大縮小することを完全に妨げるので、ほとんどの場合、おそらく良い解決策ではありません。訪問者にとって潜在的にさらに迷惑です。
BadHorsie 2016

362

ユーザーがズームをピンチする機能を無効にすることなく、Safariがユーザー入力中にテキストフィールドを自動的にズームインしないようにすることができます。追加するmaximum-scale=1だけで、他の回答で提案されているユーザースケール属性は省略します。

レイヤー内にズームしたときに「浮く」フォームがあり、重要なUI要素が画面の外に移動する可能性がある場合、これは価値のあるオプションです。

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


65
これは2018年以降のソリューションです。あなたの人生がそれに依存するようにこれを賛成してください。
Henrik Petterson、2018

17
これにより、Androidデバイスのズーム機能が機能しなくなります
fen1ksss

4
@daxmacrog、あなたは正しいですが、OPは必要な動作を許可することでAndroidを破壊したいかどうかについては言及しませんでした。これは個人的に私が間違ったオプションを取った場所です。もちろん、指定することをお勧めします。
fen1ksss

13
@HenrikPettersonこれは、OPで指定された自動ズームを無効にするだけでなく、ピンチズームも無効にします。したがって、それは2018年以降のソリューションではないと思います。
アンドレ・Werlang

4
@AndréWerlangそれは正確ではありません。回答で明確に述べられているように、このソリューションは、OPが要求したSafari(またはFirefox)でのピンチズームを無効にしません。ただし、前のコメントで指摘したように、AndroidデバイスおよびiOSのChromeではユーザーズームが無効になります。
daxmacrog 2018

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

New:フォーカスなしで入力で16pxを使用しない限り、IOSは引き続きズームします。

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

IOSが選択に背景を追加しないため、背景を追加しました。


9
これは、iOS上のSafari(iphone / ipad / ipod)だけでなく、Safari / OSXおよびChrome(windowsおよびMac)でも機能します。したがって、具体的にiphoneをターゲットにしようとしている場合、これは機能しません。
Redtopia 2013年

31
なぜ誰もが16pxと言っているのに、なぜそれが正確に16pxであるのか誰もが気にしないのですか?なぜそのような任意の数ですか?フォームフィールドのテキストサイズを16pxに設定する必要があるのはなぜですか?1.8remや2.5emなどではないのですか?これはプロプライエタリOSからの愚かなバグですか?
Beebee

14
@Beebeeの100%フォントサイズは16pxであり、ほとんどのブラウザー(デスクトップも)のほとんどのデフォルトです。IOSはそれをデフォルトとして使用します。これはおそらく、読みやすいサイズだからです。なぜそれがこのように設定されているのか、私は気にする必要はありません。気にしないでください。
クリスティーナ

5
@media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)効果をiPhoneに制限するために使用しますが、Chromeで表示したときにWebサイトを変更しないでください。
BurninLeo

9
@supports (-webkit-overflow-scrolling: touch)このcss機能はiOSにのみ存在するため、メディアクエリを使用する代わりにを使用する必要があります
James Moran

189

Webサイトがモバイルデバイス用に適切に設計されている場合は、スケーリングを許可しないことを決定できます。

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

これにより、モバイルページまたはフォームが「フロート」するという問題が解決します。


123
技術的には正しいが、私はその推論に同意しない。適切に設計されたサイトでユーザーズームを無効にすることは、一般的にはまだ悪い考えです。
2013

20
「適切に設計」は非常に主観的です。完全に応答性があり、すべてのブラウザーで機能するサイトの上部にある固定の50pxヘッダーを検討してください。iOS Safariでズームインすると、ヘッダーの配置が壊れ、サイト全体がかなり壊れます。
Redtopia 2013年

62
ユーザーズーム機能を無効にすることはUXの観点からすればひどい習慣であり、すべてのコストで本当に回避されるべきです。自由にズームインできることは基本的なアクセシビリティ機能であり、ユーザーから決して奪ってはならないコントロールです。
Gabriel Luethje 2014年

72
ネイティブモバイルアプリでは、ズームする機会がなく、正常に動作しますが、なぜWebアプリが異なるのでしょうか?適切なfont-sizeとline-heightを明確なコントラストで設定すれば、大丈夫です。
jotav 2014

39
「ネイティブアプリでは問題ない」という議論を利用している人たちは、よくできたネイティブアプリがテキストサイズなどのOSレベルのアクセシビリティ設定に準拠しているという事実を見過ごしています。老眼で視力の悪いユーザーは、OS全体で非常に大きなフォントサイズを使用する必要があるため、使用することができます。多くの場合、Webアプリはこの設定を順守しないか、順守できないため、ズームなどのWebブラウザーの組み込みのアクセシビリティ機能を許可することが重要です。あなたが完全に読みやすいと思うものは何でも、私を信じてください、それを十分に明確に見つけられない人々がいます。んではないあなたは使いやすさを重視場合、ユーザーから離れて、このオプションを取ります。
ライアンウィリアムズ

72

要約すると、答えは次のとおりです。フォーム要素のフォントサイズを少なくとも16pxに設定します


はい、これは明らかにモバイルデバイスでのズームを回避するためのベストプラクティスです。js、ハック、回避策はまったくありません。しかし、16pxでもページのズームが非常に小さいことに気付いたので、17px、18px ...を試して何が起こるかを確認しました。
ed1nh0 2013年

8
body、button、input、textarea、select要素で100%を宣言することをお勧めします。これにより、ユーザーはブラウザーに同梱されている16pxではないデフォルトを設定できます。画面での読み取りに問題がある人は、デフォルトを18pxまたは20pxに設定する可能性があります。あなたはそれらに16pxを強制することによってそれらの選択を上書きしたくないでしょう。けれどもそれがiOSになると、彼らはHIGが小さすぎると言っている値をスケールアップすることを決定しました。残念ながら、それは100%の値を解釈しないように見えるので、それを緩和するためにデフォルトを追加することに行き詰まっています。
J.ホグ

RE iOS Safari、このコメントの時点で、Safariはfont-size: 100%値を正しく解釈し、必要な16pxを取得しているようです。
Nathan Lafferty、2018年

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

3
user-scalableをnoに設定すると、すべてのズームが無効になることに注意してください。これはおそらく悪い考えです。
stormsweeper

18
これは、本文のフォントサイズがデフォルト(未指定、または1em、または100%)の場合にのみ機能します。カスタムフォントサイズを設定する場合font-size、スニペットでを設定して、16px自動ズームを回避できます。
アランH.

私はこの質問がiPhoneに向けられたのを知っていますが、これはプラットフォーム間でより互換性があり、より多くのプラットフォーム/デバイスの将来に向けて、16pxアプローチを試しましたが、Androidタブレットでは自動ズーム効果のみを減らしました。投稿で指定されているように「1em」に設定すると、問題が解決しました。
toddles_fp

3
どちら1em1rem少なくなる可能性が16pxあり、Safariは少なくとも16pxズームしないことが必要であるため、どちらも適切な解決策ではありません。
Finesse

2
ビューポートソリューションを使用しましたが、機能しませんでした。16pxソリューションは正常に機能しますが、16pxは私のサイトの入力ボックスには大きすぎます。3番目のソリューションがあります
Suneth Kalhara

21

この問題を修正する適切な方法は、メタビューポートを次のように変更することです。

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


32
これは、必ずしもこの動作を防ぐ「適切な」方法ではありません。テキストが小さすぎて読めないと判断された場合、Mobile Safariはズームインします。ズーム機能をすべてオフに切り替えることは非常に手間がかかり、ユーザーが期待する方法でページを操作できなくなります。
AlecRust 2016年

3
どうやらiOS10ではAppleはmaximum-scaleプロパティをもう尊重しないように変更し、設定に関係なくすべてのサイトがズームインできるようにした。
Wolfr

3
これはiOS10 20 / September / 2016バージョンで動作します...少なくとも私のアプリでは動作します...ありがとう!!! <meta name = "viewport" content = "width = device-width、initial-scale = 1、minimum-scale = 1、maximum-scale = 1">を使用する前は、応答の行に切り替えて、うまくいった...
eljamz

1
「ブラウザのピンチズームがページのビューポートメタ要素によってブロックされていないことを確認してください。ページを200%にズームするために使用できます。このメタ要素のユーザースケーラブルおよび最大スケール属性の制限値は避けてください。」w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon

これらのメタタグの一部がiOS 10で機能しないというコメントを見てきたが、少なくとも上記のiOS向けChromeでは機能することがわかっている。:)ありがとう!
cbloss793 2017年

16

私が見つけることができる明確な方法はありませんが、ここにハックがあります...

1)マウスオーバーイベントはズームの前に発生しますが、ズームはマウスダウンイベントまたはフォーカスイベントの前に発生します。

2)JavaScriptを使用してMETAビューポートタグを動的に変更できます(JavaScriptを使用したiPhoneサファリでのズームの有効化/無効化を参照してください

だから、これを試してください(コンパクトさのためにjqueryに示されています):

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

これは間違いなくハックです...マウスオーバー/ダウンが常にエントリ/終了をキャッチしない状況があるかもしれませんが、それは私のテストでうまく機能し、確かなスタートです。


5
Safariの動作がいつ変更されたかはわかりませんが、現在(iOS6.0.1)自動ズームの前にマウスダウンが発生しています。したがって、私の以前のソリューションでは、ズーム機能がすぐに再度有効になります。私が試したすべてのイベントはズームの前に発生するので、十分な修正ができていません。キーダウンまたはぼかし時にズームを再度有効にすることもできますが、これが見逃される可能性のあるシナリオがいくつかあります(ユーザーが入力を始める前に手動でズームしたい場合など)。
dlo、2013

15

次のようにビューポートメタにuser-scalable = 0を追加します。

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

私のために働いた:)


11
「ブラウザのピンチズームがページのビューポートメタ要素によってブロックされていないことを確認してください。ページを200%にズームするために使用できます。このメタ要素のユーザースケーラブルおよび最大スケール属性の制限値は避けてください。」w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
danielnixon

9
これは、W3で定義されているアクセシビリティの規則に違反しています。
Joshua Russell、

私にとってはうまくいきました。入力フォントサイズを16px未満に自由に変更し、JSハックを望まないので、これは私にとって最良の解決策です
Blue Bot

14

私は最近(今日:D)この動作を統合する必要がありました。コンボを含む元のデザインフィールドに影響を与えないようにするため、フィールドの焦点に変換を適用することにしました。

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

ちなみに、これはiOS 6を搭載したiphone 5ではうまく機能しましたが、ポートレートモードのiOS 5を搭載したiphone 4では、ズームが発生した後にフォーカススタイリングが適用されました。何か微妙なことが起こっているのかもしれませんが、これ以上調査しませんでした。
Vish

ズームを使用して多くの異なるクエリを実行して開発を高速化し、ズームの大きさによって必要なフォントサイズが決まると言いたいだけです
マイク

:focusは私にとってiOS 10.2 iPhone 6では機能しませんでしたが、input [type = "text"]:hoverはうまく機能しました。
Amirhossein Rzd 2017

13

他の多くの回答がすでに指摘しているように、これmaximum-scaleはメタタグに追加することで実現できますviewport。ただし、これにより、Androidデバイスでユーザーズームが無効になるというマイナスの影響があります。(v10以降、iOSデバイスのユーザーズームは無効になりません。)

デバイスがiOSの場合、JavaScriptを使用maximum-scaleしてメタviewportに動的に追加できます。これは、両方の長所を実現:私たちは、ユーザーがズームすることが可能フォーカスのテキストフィールドにズームから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               |

コード:

const addMaximumScaleToMetaViewport = () => {
  const el = document.querySelector('meta[name=viewport]');

  if (el !== null) {
    let content = el.getAttribute('content');
    let re = /maximum\-scale=[0-9\.]+/g;

    if (re.test(content)) {
        content = content.replace(re, 'maximum-scale=1.0');
    } else {
        content = [content, 'maximum-scale=1.0'].join(', ')
    }

    el.setAttribute('content', content);
  }
};

const disableIosTextFieldZoom = addMaximumScaleToMetaViewport;

// /programming/9038625/detect-if-device-is-ios/9039885#9039885
const checkIsIOS = () =>
  /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

if (checkIsIOS()) {
  disableIosTextFieldZoom();
}

なぜあなたはのコピーを作成しますかaddMaximumScaleToMetaViewport?それは意味的な理由のためだけですか?
Pherrymason

はい、関数を別の名前にマッピングするだけで、それがどのように使用されているかがわかります。
オリバージョセフアッシュ

8

iOS 7で動作するJavascriptハック。これは@dloの回答に基づいていますが、マウスオーバーイベントとマウスアウトイベントはtouchstartイベントとtouchendイベントに置き換えられています。基本的にこのスクリプトは、ズームを再び有効にする前に0.5秒のタイムアウトを追加して、ズームを防止します。

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

これは私にとって最も効果的でした。しかし、touchstart / touchendイベントを、zoomDisableとzoomEnableの両方を持つ1つの「フォーカス」イベントに変更しました。
Justin Cloud

遅延を追加することは、iOSの新しいバージョンではかなりうまく機能するように見えますが、250msに設定した場合、遅延があまりうまく機能しないのは興味深いことです。これは、ある状況下では500msも機能しない可能性があることを示唆していますが、ほとんどの場合それが機能する場合は、まったく機能しないよりはましだと思います。いい考え。
dlo、2015年

7

これは私のために働きました:

input, textarea {
    font-size: initial;
}

とてもシンプルですが、その「初期」サイズを制御する方法はありますか?
2540625 2014

私はそれをテストしていませんが、これはフォントサイズを制御する方法であるはずです。(これが機能するかどうかを教えてください。私の答えを更新します)body {font-size:20px; } input {font-size:inherit; }

7

私は上記のクリスティーナのソリューションを使用しましたが、ブートストラップの小さな変更と、デスクトップコンピューターに適用する別のルールを使用しました。Bootstrapのデフォルトのfont-sizeは14pxで、これによりズームが発生します。次の例では、Bootstrapの「フォームコントロール」を16pxに変更して、ズームを防止しています。

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

モバイル以外のブラウザでは14pxに戻ります。

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

.form-control:focusを使用してみましたが、16pxに変更したフォーカス以外は14pxのままで、iOS8でのズームの問題は修正されませんでした。少なくともiOS8を使用している私のiPhoneでは、iPhoneがページをズームしないようにフォーカスする前にfont-sizeを16pxにする必要があります。


6

私もこれを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'));
});

もちろん、この16pxフォントサイズがデザインを壊す場合、インターフェースの他のいくつかの要素を適応させる必要があるかもしれません。


4
これは上品です。これはスタイリンです。私は駄洒落ではありません。賢いアプローチ。
crowjonah 2013

@Wolfr実際のデバイスで試しましたか?
Nicolas Hoizey

1
これはiOS 12でうまくいきました。CSS変換や負のマージンをいじる代わりに、このアプローチが一番好きです。
anonymous-one

6

しばらくすると、この解決策が思いつきました

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

「マウスダウン」では、入力のフォントサイズを16pxに設定します。これはズームを防ぎます。フォーカスイベントでは、フォントサイズを初期値に戻します。

以前に投稿されたソリューションとは異なり、これにより、入力のフォントサイズを好きなように設定できます。


特に新しいiOSバージョンでは、ビューポートメタタグを使用してズームを無効にすることができないため、これは実際に機能します。
mparizeau

iOS 12.1で動作することが確認されました。ありがとう
Ziki

6

ここでほぼすべての行を読んでさまざまなソリューションをテストした後、これは、ソリューションを共有してくれたすべての人のおかげで、私が思いついた、テストし、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;}
}

しかし、いくつかの短所があります。「ホバー」状態と「フォーカス」状態の間で発生するフォントサイズの迅速な変化と、再描画によるパフォーマンスへの影響により、「ジャンプ」が顕著になります。


@MikeBoutin、フィードバックをありがとうございます。環境(デバイス/ iOSバージョン)を共有していただけますか?
l3bel

6

@jirikuchtaの回答に触発されて、私はこの問題を次のCSSを追加することで解決しました。

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

JSはありません。フラッシュなどは何もありません。

注目にそれの価値ことviewportmaximum-scale=1も動作しますが、ページはインラインフレームとしてロードされていないとき、またはあなたには、いくつかの他のスクリプトの変更がある場合viewportなど


4

のような疑似要素:focusは、以前のように機能しません。iOS 11以降、メインのスタイルの前に簡単なリセット宣言を追加できます(小さいフォントサイズでオーバーライドしない場合)。

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

Tachyons.cssなどのCSSライブラリの場合、フォントサイズを誤って上書きしてしまう可能性があることに言及する価値があります。

たとえば、class:f5は次と同等です:fontSize: 1rem、本体のフォントスケールをデフォルトのままにしておけば問題ありません。

ただし、フォントサイズクラスを選択した場合、f6これはfontSize: .875rem上向きの小さなディスプレイと同じになります。その場合、リセット宣言についてより具体的にする必要があります。


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

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

/* not small */

}

3

ちなみに、Bootstrapを使用する場合は、次のバリアントを使用できます。

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

3

私はオランダの大学のWebサイト(フォームコントロールで15pxを使用)のフォームコントロールの問題への自動ズームを「修正」する必要がありました。私は次の一連の要件を思い付きました:

  • ユーザーは引き続きズームインできる必要があります
  • font-sizeは同じままにする必要があります
  • 一時的な異なるスタイルの点滅はありません
  • jQuery要件なし
  • 最新のiOSで動作する必要があり、他のOS /デバイスの組み合わせを妨げない
  • 可能であれば魔法のタイムアウトはなく、必要に応じてタイマーを正しくクリアする

これは私がこれまでに思いついたものです:

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

いくつかのメモ:

  • これまでのところ、iOS 11.3.1でのみテストしましたが、他のいくつかのバージョンでもすぐにテストすることに注意してください
  • focusInイベントの使用は、少なくともiOS 5.1が必要であることを意味します(ただし、私たちが構築したサイトは、9として古いiOSバージョンで動作しているのはとにかくクールなボーナスだと思います)
  • 私が取り組んでいる多くのサイトには、フォームコントロールを動的に作成するページがあるため、イベント委任を使用します。
  • bodyが利用可能になるのを待つ必要がないように、eventListenersをhtml要素(documentElement)に設定します(ドキュメントが準備完了/ロード済み状態かどうか、またはDOMContentLoadedイベントを待つ必要があるかどうかを確認する必要はありません)。

3

フォントサイズを単に16pxに設定する代わりに、次のことができます。

  1. 入力フィールドを意図したサイズよりも大きくなるようにスタイル設定し、論理フォントサイズを16pxに設定できるようにします。
  2. 使用するscale()CSS変換正しいサイズまでの入力フィールドを縮小するために、負のマージン。

たとえば、入力フィールドのスタイルが最初は次のようになっているとします。

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

すべての次元を16/12 = 133.33%だけ増やしてフィールドを拡大し、次に12/16 scale()= 75%だけ使用を減らすと、入力フィールドは正しい視覚的なサイズ(およびフォントサイズ)になり、ズームされません。フォーカス。

scale()だけで視覚的な大きさに影響を与え、あなたはまた、フィールドの論理的なサイズを小さくするために、負のマージンを追加する必要があります。

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

入力フィールドの論理フォントサイズは16pxですが、テキストは12pxのように見えます。

ブログの投稿でもう少し詳しく説明します。この例は表示可能なHTMLです
。iPhoneのSafariでは入力ズームなし、ピクセルに最適な方法


3

これらの答えがあっても、何が起こっているのかを理解するのに3日かかりました。将来、もう一度解決策が必要になるかもしれません。

私の状況は、説明した状況とは少し異なりました。

私の場合、ページのdivにコンテンツ編集可能なテキストがありました。ユーザーがDIFFERENT div(並べ替えのボタン)をクリックすると、contenteditable div(以前に保存およびクリアされた選択範囲)のテキストが自動的に選択され、その選択に対してリッチテキストexecCommandが実行され、再度クリアされました。

これにより、ページの他の場所にあるカラーdivとのユーザーインタラクションに基づいてテキストの色を目に見えないように変更しながら、適切なコンテキストで色を表示できるように選択を通常は非表示にできます。

さて、iPadのSafariでは、カラーdivをクリックすると画面上のキーボードが表示され、私が何をしてもそれを妨げることはありませんでした。

私はついにiPadがこれをどのように行っているかを理解しました。

編集可能なテキストの選択をトリガーするタッチスタートとタッチエンドシーケンスをリッスンします。

その組み合わせが発生すると、画面キーボードが表示されます。

実際には、編集可能なテキストを拡大しているときに、基になるページを拡大するドリーズームを実行します。私が見ているものを理解するだけで一日かかりました。

したがって、私が使用した解決策は、これらの特定のカラーdivでタッチスタートとタッチエンドの両方をインターセプトすることでした。どちらのハンドラでも、伝播とバブリングを停止し、falseを返します。しかし、タッチエンドイベントでは、クリックがトリガーしたのと同じ動作をトリガーします。

そのため、以前は、Safariは「タッチスタート」、「マウスダウン」、「タッチエンド」、「マウスアップ」、「クリック」、そして私のコードのために、テキストの選択をこの順序でトリガーしていました。

インターセプトのための新しいシーケンスは、単にテキストの選択です。Safariが処理してキーボードの処理を行う前に、他のすべてが傍受されます。touchstartとtouchendのインターセプトは、マウスイベントのトリガーも防ぎます。コンテキストでは、これで問題ありません。

これを説明する簡単な方法はわかりませんが、問題が発生してから1時間以内にこのスレッドが見つかったので、ここにあることが重要だと思います。

98%は、同じ修正が入力ボックスやその他のものでも機能すると確信しています。Safariがシーケンスをキーボードトリガーとして認識しないようにするために、タッチイベントをインターセプトして、それらを伝播またはバブルせずに個別に処理し、小さなタイムアウト後に選択を行うことを検討してください。


これは、サファリが何をしているかについての素晴らしい説明です。ありがとう!
ジェレミー

2

私はここの人々がJavaScriptまたはビューポート機能で奇妙なことをし、デバイスで手動でズームすることをすべてオフにしているのを目にします。それは私の意見では解決策ではないはずです。このCSSスニペットを追加すると、フォントサイズを16pxなどの固定数に変更せずに、iOSの自動ズームがオフになります。

デフォルトでは、入力フィールドで93.8%(15px)のフォントサイズを使用しており、CSSスニペットを追加することで、これは93.8%のままです。16pxに変更したり、固定数にする必要はありません。

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

5
これは私にはうまくいきません、最新のiOS 6とiOS 9.2.1の両方でテストしました。これは最小限の再現可能なページです:pastebin.com/bh5Zhe9hそれでもフォーカスにズームします。これは2015年に掲載さとiOS 6では動作しません。まだupvotedされたことを奇妙な
アレクサンドルDieulot

2

ボディのfont-sizeと等しい(入力フィールドの)font-sizeを設定すると、ブラウザがズームアウトまたはズームインできなくなるようfont-size: 1remです。よりエレガントなソリューションとして使用することをお勧めします。


1

iPhoneでは、自動ズームイン(ズームアウトなし)はまだ意味がないので、dloの提案に基づくJavaScriptを使用して、フォーカス/ぼかしを操作します。

テキスト入力がぼやけて入力が残っているときに再び有効になるとすぐに、ズームは無効になります。

注:一部のユーザーは、小さなテキスト入力でテキストの編集を承認しない場合があります。したがって、私は編集中に入力のテキストサイズを変更することを個人的に好みます(以下のコードを参照)。

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

次のコードは、要素にフォーカスがある間に、入力のテキストサイズを16ピクセル(計算、つまり現在のズームサイズ)に変更します。したがって、iPhoneは自動的にズームインしません。

注:ズーム率はwindow.innerWidthと320ピクセルのiPhoneのディスプレイに基づいて計算されます。これは、縦向きモードのiPhoneでのみ有効です。

<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

スティーブンウォルシュの回答に基づいて...このコードは、フォーカスの入力のフォントサイズを変更せずに動作します(これは不自然に見えます)。さらに、FastClickでも動作します。すべてのモバイルサイトに追加して、「きびきび」させるのに役立ちます。「ビューポートの幅」をニーズに合わせて調整します。

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

ユーザーが入力コントロールをクリックする前に少し拡大していた場合、この解決策によってビューポートが突然「ズーム解除」されますか?
Bruno Torquato 2015

はい、ありますが、ユーザーが入力をクリックするたびに発生した以前の「ズーム」効果よりも不快に見えません。
ピート

1

font-sizeを16pxに設定することについての上位の回答に対するコメントは、それがどのように解決策であるか、より大きな/より小さなフォントが必要な場合はどうなるのかを尋ねました。

私はあなたのことはすべて知りませんが、フォントサイズにpxを使用するのは最善の方法ではありません。emを使用する必要があります。

テキストフィールドが16ピクセルを超えるレスポンシブサイトでこの問題に遭遇しました。フォームコンテナーを2remに、入力フィールドを1.4emに設定しました。私のモバイルクエリでは、ビューポートに応じてHTMLフォントサイズを変更します。デフォルトのhtmlは10なので、私の入力フィールドはデスクトップで28pxに計算されます

自動ズームを削除するには、入力を1.6emに変更する必要がありました。これによりフォントサイズが32pxに増加しました。わずかに高く、ほとんど目立ちません。iPhone 4&5では、htmlフォントサイズを縦向きに15pxに、横向きに10pxに戻します。そのピクセルサイズのスイートスポットは48pxであるように見えたため、1.4em(42px)から1.6em(48px)に変更しました。

あなたがしなければならないことは、font-sizeのスイートスポットを見つけ、それをrem / emサイズに逆変換することです。


1

これが私のプロジェクトの1つで使用したハックです。

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

最終的には、私が欲しかった初期のスタイルとスケールになりましたが、フォーカスを拡大できませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.