禁用“输入”文本标签的自动缩放-iPhone上的Safari


539

我制作了一个带有<input>标记的HTML页面type="text"。当我使用iPhone上的Safari单击它时,页面变大(自动缩放)。有人知道如何禁用此功能吗?


8
对于所有登陆此处的Twitter Bootstrap用户:另请参阅此Github问题
Jeroen

7
我认为@daxmacrog答案完全可以回答您想要的内容,您是否愿意接受它,以便它可以升至最高水平,并节省阅读本书的所有工作量?2018年答案:stackoverflow.com/a/46254706/172651
演变

@Evolve您所说的答案会破坏android的捏和缩放功能。daxmacrog的答案是有缺陷的。
MH

4
我发誓,苹果公司创造了这些反功能只是为了惹恼我们。
安德鲁·科斯特

@AndrewKoster,即使在2020
Ashok

Answers:


491

如果字体大小小于,16px并且表单元素的默认字体大小为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

8
@Nic您需要使用select:focus。也有同样的问题。
DGibbs 2014年

141
我不明白,这是怎么解决的?如果我想要较小/较大的字体大小怎么办?
布莱恩

47
正确的方法是将元标记更改为:<meta name =“ viewport” content =“ width = device-width,initial-scale = 1,maximum-scale = 1,user-scaleable = 0”“
Milos Matic

37
@MilosMatic在大多数情况下,这可能不是一个好的解决方案,因为它完全阻止用户缩放页面。潜在地使您的访客更加烦恼。
BadHorsie

359

您可以阻止Safari在用户输入过程中自动放大文本字段,而不会禁用用户捏缩缩放的功能。只需添加maximum-scale=1但忽略其他答案中建议的用户规模属性。

如果您的图层中的表单在缩放后会“浮动”,这是一个值得选择的选择,这会导致重要的UI元素移出屏幕。

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


65
这是2018年以上的解决方案。像您的生活一样,支持它。
亨里克·佩特森

17
这将破坏android设备的缩放功能
fen1ksss

4
@daxmacrog,你是对的,但OP没有提到他是否想通过允许必要的行为来破坏机器人。这是我个人选择错误的地方。当然,最好指定。
fen1ksss

13
@HenrikPetterson这不仅可以禁用OP指定的自动缩放功能,还可以禁用捏缩缩放功能。所以我认为这不是2018年以后的解决方案。
安德烈·沃朗(AndréWerlang)

4
@AndréWerlang这是不正确的。如答案中明确指出的那样,此解决方案不会禁用Safari要求的Safari(或Firefox)中的缩小缩放。但是,正如之前的评论所指出的那样,它确实禁用了Android设备上的用户缩放以及iOS上的Chrome。
daxmacrog

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

新增:IOS仍将缩放,除非您在输入中不使用焦点而使用16px。

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

我添加了背景,因为IOS在选择中未添加任何背景。


9
这不仅适用于iOS(iphone / ipad / ipod)上的野生动物园,而且适用于Safari / OSX和Chrome(Windows和Mac)。因此,如果您要专门针对iphone,则此操作将无效。
Redtopia

31
为什么每个人都说16像素,却没人在乎为什么要说16像素?为什么这么一个任意数字?为什么我们必须将表单字段文本大小设置为16px而不是..例如1.8rem或2.5em或类似的值?这仅仅是专有操作系统的愚蠢错误吗?
蜜蜂

14
@Beebee 100%字体大小为16px,这是大多数(如果不是全部)浏览器(也是桌面)的默认字体。IOS使用它作为默认值,可能是因为它适合阅读。为什么以这种方式设置它,我不必费神抬头,不在乎。
克里斯蒂娜(Christina)

5
用于@media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)将效果限制为iPhone,但在Chrome浏览器中查看时请勿修改网站。
BurninLeo

9
相反,使用媒体查询的,你应该使用@supports (-webkit-overflow-scrolling: touch),因为这个CSS功能只存在于iOS版
詹姆斯·莫兰

189

如果您的网站是为移动设备设计的,则可以决定不允许扩展。

<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
从用户体验的角度来看,禁用用户缩放功能是一个可怕的做法,应该不惜一切代价避免。能够自由放大是一项基本的可访问性功能,并且是您永远都不应离开用户的控件。
加百利·卢易斯

72
在本机移动应用程序中,您永远都没有机会进行缩放,而且它们工作得很好,为什么Web应用程序会与众不同?如果您设置适当的字体大小和行高,并具有清晰的对比度,则应该可以。
jotav 2014年

39
那些使用“在本机应用程序中很好”参数的用户忽略了以下事实:精心制作的本机应用程序遵循操作系统级别的可访问性设置,例如文本大小。年长且视力不好的用户可以并且确实需要使用非常大的OS字体大小,因为他们要这样做。Web应用程序通常不遵守或不能遵守此设置,因此允许Web浏览器的内置可访问性功能(例如缩放)至关重要。相信我,无论您认为是什么可读性都很好,有些人会觉得它不够清晰。难道,如果你看重实用性,从用户利用这个选项了。
瑞安·威廉姆斯

72

总之,答案是:将表单元素的字体大小设置为至少16px


是的,这绝对是避免放大移动设备的最佳实践。没有js,没有hack,也没有解决方法。但是即使使用16px,我也注意到页面上的缩放很小,所以我尝试使用17px,18px ...来看看会发生什么。
ed1nh0

8
最佳做法是在正文,按钮,输入,文本区域和选择元素上声明100%。这允许用户设置默认值,而不是浏览器附带的16px。屏幕阅读困难的人可能会将其默认设置为18px或20px。您不想通过强加16px来覆盖它们的选择。但是,当涉及到iOS时,他们决定扩大他们的HIG认为太小的价值。不幸的是,它似乎无法解释100%的值,因此我们不得不添加默认值来安抚它。
J. Hogue

RE iOS Safari,截至此注释,似乎Safari正确解释了该font-size: 100%值并获取了16px的像素。
内森·拉弗蒂

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

3
请注意,将user-scalable设置为no将禁用所有缩放,这可能不是一个好主意。
狂风扫荡

18
仅当您的正文字体大小为默认字体大小(未指定,或1em100%)时,此方法才有效。如果您设置自定义字体大小,则可以font-size在代码段中设置16px以避免自动缩放。
艾伦·H.

我知道这个问题是针对iPhone的,但是它在各个平台之间以及与更多平台/设备的未来都更加兼容,我尝试了16px方法,但在Android平板电脑上只能降低自动缩放效果。按照文章中的说明设置为“ 1em”可以解决此问题。
toddles_fp

3
无论是1em也不1rem是一个妥善的解决办法,因为这两个可以小于16px和Safari需要至少16px不放大。
Finesse

2
我使用了视口解决方案,但没有用,16px解决方案可以正常工作,但是16px对于我网站的
输入框

21

解决此问题的正确方法是将元视口更改为:

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


32
这不一定是防止此行为的“正确”方法。如果文本太小而无法阅读,则Mobile Safari会放大。关闭所有缩放功能非常费力,并且会阻止用户以他们期望的方式与您的页面进行交互。
AlecRust

3
显然,在iOS10中,Apple更改了max-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 16-10-16

我已经看到了评论,其中一些元标记在iOS 10上不起作用,并且我知道以上内容至少在iOS的Chrome上有效。:) 谢谢!
cbloss793

16

我找不到干净的方法,但是这里有一个hack ...

1)我注意到mouseover事件在缩放之前发生,但是缩放发生在mousedown或focus事件之前。

2)您可以使用javascript动态更改META视口标签(请参阅使用Javascript 启用/禁用iPhone Safari缩放)?)。

因此,请尝试以下操作(在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" />');
}

这绝对是一种hack ...在某些情况下,鼠标悬停/按下并不一定能捕获条目/退出,但是在我的测试中效果很好,并且是一个良好的开端。


5
不确定Safari的行为何时可能已更改,但是现在(iOS6.0.1)在进行自动缩放之前会发生鼠标下移的情况。因此,在我先前的解决方案中,过早重新启用缩放功能。我尚未提出适当的解决方案,因为我尝试的所有事件现在都在缩放之前发生。您可以在击键或模糊时重新启用缩放功能,但是在某些情况下可能会错过这种情况(例如,如果用户要在开始键入任何内容之前进行手动缩放)。
dlo

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

我只想说我有很多不同的查询,使用缩放来使开发更快,并且取决于您缩放的多少将确定您需要多少字体大小
Mike 2014年

:focus对我而言不适用于iOS 10.2 iPhone 6,但是input [type =“ text”]:hover效果很好。
Amirhossein Rzd

14

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

9
这违反了W3定义的可访问性规则。
Joshua Russell

为我工作,这也是对我来说最好的解决方案,因为我希望自由地将输入字体大小更改为16px以下,并且不希望出现JS hack
Blue Bot,

13

正如许多其他答案已经指出的那样,这可以通过添加maximum-scale到meta 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 hack。这基于@dlo的答案,但mouseover和mouseout事件被touchstart和touchend事件代替。基本上,此脚本会在再次启用缩放功能之前添加半秒超时,以防止缩放。

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

这对我来说效果最好。但是,我同时使用zoomDisable和zoomEnable将touchstart / touchend事件更改为一个“焦点”事件。
贾斯汀·云

添加延迟似乎在新版本的iOS上确实可以很好地工作,但是有趣的是,当设置为250ms时,它不能很好地工作。这暗示了在某些情况下500ms可能也不起作用,但是我想如果大多数时间都起作用,那总比根本不起作用要好。好想法。
dlo

7

这为我工作:

input, textarea {
    font-size: initial;
}

很简单,但是有什么方法可以控制“初始”大小是多少?
2540625

我还没有测试过,但这应该是控制字体大小的一种方法。(请让我知道是否可行,我将更新我的答案)body {font-size:20px; }输入{字体大小:继承;}

7

我在上面使用了克里斯蒂娜(Christina)的解决方案,但对引导程序做了一些小的修改,并将另一条规则应用于台式计算机。Bootstrap的默认字体大小为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,它将焦点保留为14px,但焦点将其更改为16px,并且无法解决iOS8的缩放问题。至少在我使用iOS8的iPhone上,字体大小必须为16px,然后焦点才能使iPhone无法缩放页面。


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

@Wolfr您是否尝试过实际设备?
Nicolas Hoizey

1
这对我们在iOS 12上有效。
匿名一

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

在“ mousedown”上,它将输入的字体大小设置为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,而且我什么也没注意到。

值得注意的是,viewportwith maximum-scale=1也可以使用,但是当页面作为iframe加载时,或者如果您有其他脚本修改viewport,则不能使用。


4

诸如此类的伪元素:focus无法像以前那样工作。从iOS 11开始,可以在主要样式之前添加一个简单的reset声明(前提是您不使用较小的字体覆盖它们)。

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

我不得不为荷兰大学网站(在表单控件中使用15px)“修复”自动缩放表单控件的问题。我提出了以下要求:

  • 用户必须仍然能够放大
  • 字体大小必须保持不变
  • 没有临时不同样式的闪烁
  • 没有jQuery要求
  • 必须在最新的iOS上运行并且不妨碍任何其他操作系统/设备组合
  • 如果可能,没有魔术超时,并且如果需要,请正确清除计时器

到目前为止,这是我想出的:

/*
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(但我认为我们构建的网站都可以在iOS 9之前的版本中工作,这是很不错的奖励)
  • 使用事件委托,因为我工作的许多站点都有页面,这些页面可能动态创建表单控件
  • 将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

即使有了这些答案,我也花了三天时间才弄清楚发生了什么,将来我可能会再次需要解决方案。

我的情况与上述情况略有不同。

在我的页面上,我在div中有一些可编辑的文本。当用户单击DIFFERENT div(一种排序按钮)时,我自动在contenteditable div(先前已保存并清除的选择范围)中选择了一些文本,在该选择上运行了富文本格式execCommand,然后再次将其清除。

这使我能够根据用户与页面其他位置的div的交互来无形地更改文本颜色,同时使选择通常保持隐藏状态,以使他们在适当的上下文中看到颜色。

好吧,在iPad的Safari上,单击color div会导致屏幕上的键盘出现,而我所做的一切都无法阻止它。

我终于想通了iPad的做法。

它侦听触发选择可编辑文本的touchstart和touchend序列。

发生这种组合时,它将显示屏幕键盘。

实际上,它会进行多莉缩放,在放大可编辑文本的同时扩展基础页面。我花了一天的时间才明白我所看到的。

因此,我使用的解决方案是拦截这些特定颜色div上的touchstart和touchend。在这两个处理程序中,我都停止传播和冒泡并返回false。但是在touchend事件中,我会触发与单击触发相同的行为。

因此,以前,Safari触发了我认为是“ touchstart”,“ mousedown”,“ touchend”,“ mouseup”,“ click”的命令,并且由于我的代码,因此依次触发了文本选择。

由于截距,新的序列只是文本选择。Safari可以处理其他所有内容并对其进行键盘处理之前,其他所有内容都会被拦截。touchstart和touchend拦截器也可以防止触发鼠标事件,在上下文中这完全可以。

我不知道更简单的方式来描述此问题,但我认为将其放在此处很重要,因为我在初次遇到此问题的一个小时内就找到了该线程。

我有98%的把握确保相同的解决方案可用于输入框和其他任何东西。拦截触摸事件并单独处理它们,而不会使它们传播或冒泡,并考虑在很小的超时后进行任何选择,以确保Safari不会将序列识别为键盘触发。


这是对野生动物园活动的很好解释。谢谢!
杰里米

2

我看到这里的人使用JavaScript或视口功能做了一些奇怪的事情,并关闭了所有手动缩放设备的功能。我认为这不应该是解决方案。添加此CSS代码段将关闭iOS中的自动缩放功能,而无需将字体大小更改为固定的数字(例如16px)。

默认情况下,我在输入字段中使用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年和upvoted但在iOS的6不起作用
亚历山大Dieulot

2

(将输入字段的字体大小设置为)等于正文的字体大小,似乎阻止了浏览器放大或缩小。我建议使用它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和iPhone的320像素显示来计算的。这仅对纵向模式的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

基于斯蒂芬·沃尔什(Stephen Walsh)的答案 ...该代码无需更改焦点输入的字体大小(看上去很la脚),并且仍可与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)
    });

如果用户在单击输入控件之前已经放大了一点,此解决方案是否会使视口突然“取消缩放”?
布鲁诺·托夸托

是的,它确实可以,但是看起来没有比每次用户单击输入时发生的以前的“缩放”效果更刺耳。
皮特

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

这是我在其中一个项目中使用过的一种技巧:

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

最终得到了我想要的初始样式和比例,但是没有聚焦。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.