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

Disable Auto Zoom in Input "Text" tag - Safari on iPhone

提问人:Eduardo Montenegro 提问时间:6/7/2010 最后编辑:VegaEduardo Montenegro 更新时间:9/12/2023 访问量:742570

问:

我制作了一个带有 .当我在 iPhone 上使用 Safari 单击它时,页面会变大(自动缩放)。有谁知道如何禁用它?<input>type="text"

HTML iphone 缩放 mobile-safari html-input

评论

11赞 Jeroen 3/9/2015
对于所有登陆此处的 Twitter Bootstrap 用户:另请参阅此 Github 问题
79赞 Andrew Koster 8/25/2019
我发誓,苹果创造这些负面功能只是为了扰乱我们的头脑。
12赞 Ashok 2/13/2020
@AndrewKoster,即使在 2020 年的现在,我也同意你的看法。
13赞 Marc 8/6/2020
2020 年 8 月,我又一次回到这里,希望答案能有奇迹。看到你的下一年。我要吃一个苹果。
14赞 step 11/26/2020
iOS 是下一个 IE。

答:

39赞 stormsweeper 9/24/2010 #1
input[type='text'],textarea {font-size:1em;}

评论

3赞 stormsweeper 9/24/2010
请注意,将 user-scalable 设置为 no 将禁用所有缩放,这可能是一个坏主意。
19赞 Alan H. 6/2/2011
仅当正文字型大小为默认值(未指定、或 或 )。如果设置了自定义字体大小,则可以在代码段中设置 以避免自动缩放。1em100%font-size16px
0赞 toddles_fp 9/15/2013
我知道这个问题是针对 iPhone 的,但这在跨平台和更多平台/设备的未来更兼容,我尝试了 16px 方法,但在 Android 平板电脑上只降低了自动缩放效果。按照帖子中的规定设置为“1em”解决了该问题。
0赞 Felipe Castro 11/7/2016
我有一个自定义字体大小(15px),并且将字体大小设置为1rem(不是em)有效。
4赞 Finesse 4/30/2019
两者都不是一个合适的解决方案,因为两者都可能小于,并且 Safari 至少需要不缩放。1em1rem16px16px
17赞 dlo 3/5/2011 #2

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

1) 我注意到鼠标悬停事件发生在缩放之前,但缩放发生在鼠标按下或焦点事件之前。

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

这绝对是一个黑客......在某些情况下,鼠标悬停/向下并不总是能捕捉到进入/退出,但它在我的测试中效果很好,是一个坚实的开始。

评论

5赞 dlo 2/2/2013
不确定 Safari 行为何时可能发生了变化,但现在 (iOS6.0.1) 鼠标按下发生在自动缩放之前。因此,在我之前的解决方案中,缩放过早地重新启用。我还没有想出一个充分的修复方法,因为我现在尝试的所有事件都发生在缩放之前。您可以在按下键或模糊时重新启用缩放,但在某些情况下可能会错过(例如,如果用户想要在开始键入任何内容之前手动缩放)。
656赞 srikanth 6/18/2011 #3

如果字体大小小于,并且表单元素的默认字体大小为 (至少在 Chrome 和 Safari 中),则浏览器将缩放。16px11px

此外,该元素需要附加伪类。selectfocus

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

评论

86赞 Nic Barbier 7/5/2013
只是为了涵盖所有内容: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; }
8赞 DGibbs 6/9/2014
@Nic 您需要使用 .也有同样的问题。select:focus
225赞 bryan 8/4/2015
我不明白,这是怎么解决的?如果我想要更小/更大的字体怎么办?
54赞 Milos Matic 12/4/2015
正确的方法是将元标记更改为:<meta name=“viewport” content=“width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0”/>
50赞 BadHorsie 7/8/2016
@MilosMatic 在大多数情况下可能不是一个好的解决方案,因为它完全阻止了用户缩放页面。对您的访问者来说可能更烦人。
101赞 Nik 10/5/2011 #4

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

评论

0赞 ed1nh0 3/6/2013
是的,这绝对是避免在移动设备上缩放的最佳实践。没有js,没有黑客,根本没有解决方法。但即使有 16px,我注意到我的页面缩放非常小,所以我尝试了 17px、18px......看看会发生什么。
9赞 J. Hogue 10/19/2016
最佳做法是在 body、button、input、textarea 和 select 元素上声明 100%。这允许用户设置一个默认值,该默认值不是浏览器附带的 16px。在屏幕上阅读有困难的人可能会将其默认值设置为 18px 或 20px。您不想通过对他们施加 16px 来覆盖他们的选择。然而,当谈到 iOS 时,他们决定扩大他们的 HIG 认为太小的任何价值。不幸的是,它看起来没有解释 100% 的值,所以我们只能添加默认值来安抚它。
0赞 Nathan Lafferty 10/27/2018
RE iOS Safari,截至此评论,Safari似乎正确解释了该值并获取了必要的16px。font-size: 100%
227赞 Marcellino Bommezijn 12/4/2012 #5

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

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

这解决了您的移动页面或表单将“浮动”的问题。

评论

151赞 Fer 2/5/2013
技术上是正确的,但我不同意这种推理。在设计合理的网站上禁用用户缩放通常仍然是一个坏主意。
27赞 Redtopia 10/16/2013
“设计得当”是非常主观的。考虑在网站顶部放置一个固定的 50px 标题,该标题是完全响应式的,并且应该适用于所有浏览器。在iOS Safari中放大会破坏标题定位,并且几乎会破坏整个网站。
71赞 Gabriel Luethje 1/22/2014
从 UX 的角度来看,禁用用户缩放功能是一种可怕的做法,应该不惜一切代价避免。能够自由放大是一项基本的辅助功能,也是您永远不应从用户手中夺走的控件。
87赞 jotav 9/4/2014
在原生移动应用程序中,您永远没有机会缩放,而且它们工作得很好,为什么 Web 应用程序会有所不同?如果您设置了适当的字体大小和行高,并具有清晰的对比度,您应该没问题。
51赞 Ryan Williams 6/29/2015
那些使用“原生应用没问题”论点的人忽略了这样一个事实,即制作精良的原生应用会遵循操作系统级别的辅助功能设置,例如文本大小。年龄较大和视力不佳的用户可以而且确实使用非常大的操作系统范围的字体大小,因为他们需要这样做。Web 应用程序通常不遵守或不能遵守此设置,因此允许 Web 浏览器的内置辅助功能(如缩放)至关重要。无论你认为什么都是完全可读的,相信我,有些人会觉得它不够清晰。如果您重视可用性,请不要将此选项从用户手中夺走。
7赞 Nicolas Hoizey 12/18/2012 #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 7/26/2013
这很优雅。这是风格。我没有双关语。聪明的方法。
0赞 Nicolas Hoizey 6/25/2016
您在实际设备上尝试过@Wolfr?
1赞 anonymous-one 9/19/2019
这在iOS 12上对我们有用。我最喜欢这种方法,而不是用 css 转换和负边距来糊弄。
14赞 piouPiouM 12/18/2012 #7

我最近(今天:D)不得不整合这种行为。为了不影响原始设计领域,包括组合,我选择在领域焦点处应用转换:

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

评论

0赞 Vish 4/13/2013
仅供参考,这在装有 iOS 6 的 iphone 5 上运行良好,但在装有 iOS 5 纵向模式的 iphone 4 上,焦点样式是在缩放发生后应用的。也许是有什么微妙的事情发生,我没有进一步调查。
0赞 mike 5/3/2014
我只想说,我有很多不同的查询,使用缩放来加快开发速度,并且根据缩放的程度将决定您需要多少字体大小,我相信
0赞 Amirhossein Rzd 2/20/2017
:focus对我不起作用 iOS 10.2 iPhone 6,但 input[type=“text”]:hover 效果很好。
264赞 Christina 4/28/2013 #8
@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在选择时没有添加背景。

评论

11赞 Redtopia 10/17/2013
这不仅适用于 iOS (iphone/ipad/ipod) 上的 Safari,也适用于 Safari/OSX 和 Chrome(Windows 和 Mac)。因此,如果您尝试专门针对 iphone,这将行不通。
45赞 Beebee 7/14/2015
为什么每个人都说 16px,但没有人愿意提及为什么是 16px?为什么会有这么一个任意的数字?为什么我们必须将表单字段文本大小设置为 16px 而不是 ..比如说 1.8rem 或 2.5em 之类的?这只是来自专有操作系统的愚蠢错误吗?
16赞 Christina 7/15/2015
@Beebee 100% 字体大小为 16px,这是大多数(如果不是所有)浏览器(桌面)的默认值。IOS将其用作默认值,可能是因为它的阅读尺寸很舒适。为什么会这样设置,我懒得抬头,不在乎。
7赞 BurninLeo 11/17/2015
用于将效果限制为 iPhone,但在 Chrome 中查看时不修改网站。@media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)
12赞 James Moran 6/26/2018
您应该使用 ,而不是使用媒体查询,因为此 css 功能仅存在于 iOS 上@supports (-webkit-overflow-scrolling: touch)
1赞 BurninLeo 7/14/2013 #9

由于自动放大(没有缩小)仍在 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>
8赞 Ilkka R. 11/5/2013 #10

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

评论

0赞 Justin Elkow 11/12/2013
这对我来说最有效。但是,我将 touchstart/touchend 事件更改为一个同时具有 zoomDisable 和 zoomEnable 的“焦点”事件。
0赞 dlo 1/26/2015
添加延迟似乎在较新版本的 iOS 上效果很好,但有趣的是,当设置为 250 毫秒时,它效果不佳。这表明在某些情况下,500 毫秒也可能不起作用,但如果它大部分时间都有效,我想总比根本不工作要好。好主意。
-13赞 ygaradon 5/14/2014 #11

这是工作!!我完成了我的搜索之旅!

<meta name="viewport" content="width=640px, initial-scale=.5, maximum-scale=.5" />

iPhone OS6Android 2.3.3 模拟器上测试

我有一个固定宽度为 640px 的移动网站,我面对的是自动变焦对焦。

我正在尝试分配一些 slution,但没有一个在 iPhone 和 Android 上都有效!

现在对我来说,禁用缩放是可以的,因为该网站是移动优先的设计!

这是我找到它的地方: 如何进行视口大小调整和缩放以获得跨浏览器支持?

评论

6赞 dano 4/25/2015
这会对视图大小造成一些非常讨厌的事情,例如不让可访问的人缩放。我不认为这是一个很好的解决方案?
2赞 Lucent Fox 6/16/2015
是的,这个解决方案通常不是很好,因为它修复了视口大小,并在您迁移到不同设备时导致问题。
0赞 Usman Arshad 11/13/2018
超出标准。
0赞 stphnwlsh 6/6/2014 #12

我花了一段时间才找到它,但这是我找到的最好的代码......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));
});
2赞 rocky 6/27/2014 #13

根据斯蒂芬·沃尔什(Stephen Walsh)的回答...这段代码在不改变焦点输入的字体大小的情况下工作(看起来很蹩脚),而且它仍然适用于 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)
    });

评论

0赞 Bruno Torquato 4/22/2015
如果用户在单击输入控件之前已经放大了一点,此解决方案是否会导致视口突然“取消缩放”?
0赞 Pete 11/12/2015
是的,它确实如此,但它看起来并不比用户每次单击输入时发生的先前“缩放”效果更刺耳。
8赞 user1000952 9/2/2014 #14

这对我有用:

input, textarea {
    font-size: initial;
}

评论

0赞 2540625 9/15/2014
很简单,但是有没有办法控制“初始”大小?
0赞 9/16/2014
我还没有测试过,但这应该是一种控制字体大小的方法。(请让我知道这是否有效,我会更新我的答案) body { font-size: 20px; } input { font-size: inherit;
8赞 Tanny O'Haley 9/27/2014 #15

我使用了上面 Christina 的解决方案,但对 bootstrap 进行了小幅修改,并制定了另一条适用于台式计算机的规则。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,除了 on focus 将其更改为 16px,并且它没有解决 iOS8 的缩放问题。至少在我使用 iOS8 的 iPhone 上,字体大小必须在焦点前为 16px,以便 iPhone 不缩放页面。

2赞 Jack Ottermans 4/14/2015 #16

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

默认情况下,我在输入字段中使用 93.8% (15px) 的字体大小,通过添加我的 CSS 片段,这保持在 93.8%。无需更改为 16px 或使其成为固定数字。

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

评论

5赞 Alexandre Dieulot 2/15/2016
这对我不起作用,在最新的 iOS 6 和 iOS 9.2.1 中进行了测试。这是一个最小的可重现页面: pastebin.com/bh5Zhe9h 它仍然会放大焦点。奇怪的是,这是在 2015 年发布的,并且被点赞,但在 iOS 6 中不起作用。
2赞 sindiploma 4/26/2015 #17

将字体大小(对于输入字段)设置为等于正文的字体大小,似乎是阻止浏览器缩小或缩小的原因。 我建议用作更优雅的解决方案。font-size: 1rem

110赞 Milos Matic 12/4/2015 #18

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

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

重要提示:请勿设置 !这将使页面保持可手动缩放。minimum-scale

评论

57赞 Alec Rust 1/21/2016
这不一定是防止这种行为的“适当”方法。如果文本被认为太小而无法阅读,Mobile Safari 会放大。关闭一起缩放是很严厉的,并且会阻止用户以他们可能期望的方式与您的页面进行交互。
8赞 Wolfr 6/15/2016
显然,在 iOS10 中,Apple 将 max-scale 属性更改为不再被尊重,允许所有网站放大,无论其设置如何。
4赞 eljamz 9/22/2016
这适用于iOS10 20 / September / 2016版本...至少在我的应用程序上工作......谢谢!!!在我使用 <meta name=“viewport” content=“width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1” 之前> 但是我把它切换到响应上的行,它起作用了......
4赞 danielnixon 10/17/2016
“确保浏览器捏合缩放不会被页面的视口元元素阻止,以便它可以用于将页面缩放到 200%。应避免此元元素的用户可扩展属性和最大规模属性的限制值。w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
1赞 Pein 8/30/2018
这在 iOS 中有效,但在 Android 中 Pich Zoom 不起作用
0赞 Jon Tinsman 5/27/2016 #19

关于将 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) 的原因。

您需要做的是找到字体大小的最佳位置,然后将其向后转换为您的 rem/em 大小。

评论

2赞 Artimus 9/22/2021
对于未来的读者:没有人应该使用它们,因为它打开了潘多拉的盒子。无论如何,没有人会在不重新设计页面的情况下更改字体大小,因为很多布局可能会被破坏。为了增加操作系统的字体大小,所有浏览器都会自然地扩展到 16 的基数,这使得 rem 过时,因为 px 因此行为相同,但更易于处理。否则,无论如何,您都会遇到通过插件将 rem 与 px 混合的麻烦。
0赞 Jon Tinsman 3/10/2022
@Artimus您的评论说“没有人应该使用它们”是个人评论。如果有人学会了正确使用 em 和 rem,那么它就会使网站扩展到设备变得更加容易。PX 和 PT 是固定的,因此如果您的网站具有响应性,则需要对需要更改的每种字体进行媒体查询。如果您正确使用 rem 和 em,您的媒体查询只会在 html font-size 上,其他所有内容都会正确缩放。
13赞 Tuyen Cao 10/11/2016 #20

user-scalable=0 添加到视口元,如下所示

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

为我工作:)

评论

16赞 danielnixon 10/17/2016
“确保浏览器捏合缩放不会被页面的视口元元素阻止,以便它可以用于将页面缩放到 200%。应避免此元元素的用户可扩展属性和最大规模属性的限制值。w3.org/TR/mobile-accessibility-mapping/#zoom-magnification
12赞 Joshua Russell 12/12/2016
这打破了 W3 定义的可访问性规则。
0赞 Blue Bot 10/21/2018
对我有用,这对我来说也是最好的解决方案,因为我希望可以自由地将输入字体大小更改为 16px 以下,并且不想要 JS hack
7赞 jirikuchta 1/5/2017 #21

经过一段时间的尝试,我想出了这个解决方案

// 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。这将阻止缩放。在焦点事件中,它会将字体大小更改回初始值。

与之前发布的解决方案不同,这将允许您将输入的字体大小设置为您想要的任何字体大小。

评论

0赞 mparizeau 2/6/2018
这个实际上对我有用,特别是因为在较新的 iOS 版本中,您不能使用视口元标记来禁用缩放。
6赞 l3bel 2/9/2017 #22

在阅读了这里的几乎每一行并测试了各种解决方案之后,感谢所有分享他们的解决方案的人,这是我在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;}
}

不过,它有一些缺点,由于在“悬停”和“聚焦”状态之间快速改变字体大小,以及重绘对性能的影响,因此出现了明显的“跳跃”

评论

0赞 l3bel 3/19/2019
感谢您的反馈,@MikeBoutin。你能分享你的环境(设备/iOS 版本)吗?
875赞 daxmacrog 9/16/2017 #23

您可以阻止 Safari 浏览器在用户输入期间自动放大文本栏,而不会停用用户捏合缩放的功能。只需添加但省略其他答案中建议的 user-scale 属性。maximum-scale=1

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

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

评论

71赞 fen1ksss 8/14/2018
这将破坏Android设备的缩放能力
5赞 fen1ksss 8/15/2018
@daxmacrog,你是对的,但 OP 没有提到他是否想通过允许必要的行为来破坏机器人。这是我个人采取错误选择的地方。当然,最好指定。
38赞 André Werlang 9/18/2018
@HenrikPetterson 这不仅可以禁用 OP 指定的自动缩放功能,还可以禁用捏合缩放。所以我不认为这是 2018+ 的解决方案。
6赞 daxmacrog 9/18/2018
@AndréWerlang 这不准确。正如答案中明确指出的那样,此解决方案不会禁用 Safari(或 Firefox)中的捏合缩放,这是 OP 所要求的。但正如之前的评论所指出的,它确实禁用了 Android 设备和 iOS 上 Chrome 上的用户缩放。
18赞 Dem Pilafian 10/27/2019
关于是否令人讨厌地禁用用户捏合缩放,存在很多困惑。当 Apple 正确地决定忽略禁用用户捏合缩放时,该行为在 iOS 10 中发生了变化。好消息是,该设置仍然可以防止自动变焦对焦。maximum-scale=1
2赞 Bohdan Vorona 12/1/2017 #24

顺便说一句,如果您使用 Bootstrap,则可以使用此变体:

.form-control {
  font-size: 16px;
}
4赞 Spellcoder 7/7/2018 #25

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

  • 用户必须仍能够放大
  • font-size 必须保持不变
  • 没有临时不同样式的闪光
  • 无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),这样就不必等待 body 变得可用(不想费心检查文档是否具有就绪/加载状态或需要等待 DOMContentLoaded 事件)

评论

0赞 Sven 1/25/2021
这对我来说并不完全完美(输入缩放是为用户按下按钮时动态添加的<输入>触发的),但它适用于我 85% 的情况,这在目前已经足够好了。只是想感谢您分享您的解决方案!
0赞 magom001 8/1/2018 #26

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

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

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

19赞 Jeffery To 11/2/2018 #27

您可以:

  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 = 75%,则输入字段将具有正确的视觉大小(和字体大小),并且不会对焦进行缩放。scale()

由于仅影响视觉对象大小,因此还需要添加负边距以减小字段的逻辑大小。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赞 Adrien Castagliola 11/5/2018 #28

在 Angular 中,您可以使用指令来防止在 IOS 设备上缩放焦点。没有元标记来保留可访问性。

import { Directive, ElementRef, HostListener } from '@angular/core';

const MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX = 16;

@Directive({ selector: '[noZoomiOS]' })

export class NoZoomiOSDirective {
  constructor(private el: ElementRef) {}

@HostListener('focus')
  onFocus() {
    this.setFontSize('');
  }

@HostListener('mousedown')
  onMouseDown() {
    this.setFontSize(`${MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX}px`);
  }

private setFontSize(size: string) {
  const { fontSize: currentInputFontSize } = window.getComputedStyle(this.el.nativeElement, null);

  if (MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX <= +currentInputFontSize.match(/\d+/)) {
      return;
   }

  const iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
  iOS 
     && (this.el.nativeElement.style.fontSize = size);
 }
}

<input noZoomiOS >*.module.ts

-3赞 Chocoprins18 12/10/2018 #29

请不要使用 Javascript 或 hacks 来使其工作。这将影响您在网络上的项目分数。

这将解决问题:

input, input:active, input:focus, input:focus-within, input:hover, input:visited {
    font-size: 16px!important;
}

评论

4赞 nextgentech 12/14/2018
这怎么不是黑客?除非您碰巧希望所有输入的字体大小为 16px,否则这将搞砸网站的外观/布局。根本不是一个合适的解决方案。
0赞 Chocoprins18 12/14/2018
这是这个问题的完美解决方案。你对我的解决方案的回答有点太早了。先好好阅读问题。为什么他/她不希望所有输入缩放都固定?这不是很奇怪吗?所以你要解决一个页面上的缩放输入,而不是另一个页面上的缩放输入?
9赞 nextgentech 12/15/2018
关键是你通过引入另一个问题来“解决”一个问题——被迫让每个输入都使用 16px 作为字体大小。如果您的输入大小较小或较大(经常发生这种情况)怎么办?我的主要批评是,您正在呼吁其他人使用“黑客”,但所有这一切都是强制所有输入到固定字体大小以解决此问题(顺便说一句,7 年前评分最高的答案已经指出了这一点)。也许你应该先阅读许多其他答案。
7赞 Scott Phillips 4/1/2019 #30

伪元素,如,不能像以前那样工作。从 iOS 11 开始,可以在主要样式之前添加简单的重置声明(前提是您不会使用较小的字体大小覆盖它们)。:focus

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

值得一提的是,对于像Tachyons.css这样的CSS库,很容易意外地覆盖你的字体大小。

例如,class: 等同于 :,如果您将正文字体比例保持在默认值,这很好。f5fontSize: 1rem

但是:如果您选择字体大小类:这将相当于在小型显示器上向上。在这种情况下,您需要更具体地了解重置声明:f6fontSize: .875rem


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

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

/* not small */

}

69赞 Oliver Joseph Ash 8/16/2019 #31

正如许多其他答案已经指出的那样,这可以通过添加到元标记来实现。但是,这会产生在 Android 设备上禁用用户缩放的负面影响。(自 v10 以来,它不会在 iOS 设备上禁用用户缩放maximum-scaleviewport

当设备是 iOS 时,我们可以使用 JavaScript 动态添加到元中。这实现了两全其美:我们允许用户缩放防止 iOS 在焦点上放大文本字段。maximum-scaleviewport

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

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

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

评论

0赞 Pherrymason 9/18/2019
为什么要创建 的副本?仅仅是出于语义原因吗?addMaximumScaleToMetaViewport
0赞 Oliver Joseph Ash 9/18/2019
是的,只需将函数映射到不同的名称,以便清楚地了解它的使用方式。
6赞 Crocsx 5/11/2021
截至 2021 年今天的最佳解决方案(带有一些安排的代码)
1赞 btown 1/29/2023
仍然是 2023 年的最佳解决方案!
0赞 bora89 6/2/2023
没门,它有效!
4赞 JBlitzen 8/30/2019 #32

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

我的情况与所描述的情况略有不同。

在我的页面中,我在页面上的 div 中有一些可编辑的文本。当用户单击不同的 div(一种按钮)时,我会自动在 contenteditable div(先前已保存和清除的选择范围)中选择一些文本,对该选择运行富文本 execCommand,然后再次清除它。

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

好吧,在 iPad 的 Safari 上,单击颜色 div 会导致屏幕键盘出现,我所做的任何事情都无法阻止它。

我终于弄清楚了iPad是如何做到这一点的。

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

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

实际上,它执行了推车缩放,在放大可编辑文本的同时扩展底层页面。我花了一天时间才明白我所看到的。

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

所以,在此之前,Safari 会触发我认为是“touchstart”、“mousedown”、“touchend”、“mouseup”、“click”,并且由于我的代码,按此顺序触发文本选择。

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

我不知道有更简单的方法来描述这一点,但我认为把它放在这里很重要,因为我在第一次遇到问题后的一个小时内就发现了这个线程。

我 98% 确定相同的修复程序适用于输入框和其他任何东西。拦截触摸事件并单独处理它们,不要让它们传播或冒泡,并考虑在微小的超时后进行任何选择,以确保 Safari 不会将序列识别为键盘触发器。

评论

0赞 Jeremy 9/13/2019
这是对野生动物园正在做的事情的一个很好的解释。谢谢!
18赞 Meligy 10/29/2019 #33

受到 @jirikuchta 的回答的启发,我通过添加以下 CSS 解决了这个问题:

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

没有 JS,我没有注意到任何闪光灯或任何东西。

值得注意的是,a with 也有效,但当页面作为 iframe 加载时,或者如果您有其他脚本修改 ,等等时就不行了。viewportmaximum-scale=1viewport

10赞 Amey Vartak 7/6/2020 #34

我已经查看了多个答案。

  1. 在标签中设置的答案在 iOS 设备上工作正常,但在 Android 设备上禁用捏合缩放功能。maximum-scale=1meta
  2. 有设置的那个对我来说太骇人听闻了。font-size: 16px;onfocus

所以我写了一个JS函数来动态改变标签。meta

var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
if (iOS)
    document.head.querySelector('meta[name="viewport"]').content = "width=device-width, initial-scale=1, maximum-scale=1";
else
    document.head.querySelector('meta[name="viewport"]').content = "width=device-width, initial-scale=1";
3赞 mike nelson 10/14/2020 #35

令人惊讶的是,这里有几十个关于javascript和视口的答案,只有一个提到我认为这是最好的解决方案。text-size-adjust

您可以将其设置为 。none

添加以下 CSS:

* {
 -webkit-text-size-adjust: none;
  text-size-adjust: none;
}

评论

0赞 jimmont 10/21/2020
这似乎不适用于 iOS,是否还有更多方法可以成功应用于解决方案——这意味着其他要求,例如具有适当值的元视口?
7赞 Elliot Plant 3/10/2021
不幸的是,这在 safari iOS 14.4 上对我不起作用
0赞 rocky 12/4/2021
根据 developer.mozilla.org 的说法,它仍然被认为是实验性的,但受当前移动 Chrome 和 Safari 的支持。与往常一样,请检查 caniuse.comtext-size-adjust
0赞 Adam Jagosz 4/2/2022
这个CSS属性甚至与自动缩放有什么关系吗?它旨在控制呈现的字体大小,而不是屏幕缩放。
0赞 mike nelson 4/3/2022
@adam 是的,确实如此。它增加了输入框的字体大小,从而导致自动缩放。
16赞 lortschi 11/28/2020 #36

这在 iOS、Safari 和 Chrome 上对我有用。对于输入选择器,可以设置类或 id 以包围当前。

@supports (-webkit-overflow-scrolling: touch) {
   input {
     font-size: 16px;
   }
}

评论

1赞 Fikret 6/11/2021
它有帮助,但如何帮助?
0赞 FBB 7/29/2022
也为我工作。我只是将其粘贴到 index.css 和 boom 中,不再卡顿的 ios 缩放。
9赞 jonhobbs 9/28/2021 #37

2021年解决方案...

好的,我已经通读了所有的旧答案,但没有一个对我有用。经过几个小时的尝试,最终解决方案似乎很简单。

input{
    transform: scale(0.875);
    transform-origin: left center;
    margin-right: -14.28%;
}

在 PC 上的 iOS/Android/Chrome 上测试

这允许您使用 14px 字体,如果您需要不同的大小,则缩放因子为 14/16 = 0.875,负边距为 (1 - 0.875) / 0.875 * 100

我的输入将父项设置为“display:flex”,并且由于具有“flex: 1 1 auto”,因此它会增长以适合父项。您可能需要也可能不需要它,但我将其包括在内以确保完整。

6赞 Rounin 8/31/2022 #38

使用 (hover: none) 和 (pointer: coarse) 定位所有触摸屏设备:

这里的许多答案都诉诸于部署 JavaScriptjQuery

但是它应该(而且是)完全可以控制诸如使用CSS的条件字体呈现之类的问题。


Safari Mobile 要求(有充分的理由)任何表单元素在交互时必须具有最小字体大小(或视觉等效字体)。16px

让我们致力于使经过深思熟虑的用户体验适用于所有触摸屏浏览器。

然后我们可以采用以下方法:

@media only screen and (hover: none) and (pointer: coarse) {

  input,
  select,
  textarea {
    font-size: 11px;
  }

  input:focus,
  select:focus,
  textarea:focus {
    font-size: 16px;
  }
}

结果

使用触摸屏设备时,当上述任何交互式表单元素聚焦时,该表单元素的 OF 将暂时设置为 。font-size16px

反过来,这会禁用 iOS Safari Mobile .auto-zoom

用户启动的捏合缩放在所有设备上都不受影响,并且永远不会被禁用。

2赞 Abhinav Akhil 12/6/2022 #39

此问题的简单解决方案是:

@media screen and (max-width: 599px) {
  input, select, textarea {
    font-size: 16px;
  }
}

注意:max-width可以根据您的要求定制。

评论

0赞 Antoine Weber 3/29/2023
这似乎有效。我不得不使用它来覆盖 UI 组件库设置的其他规则font-size: 16px !important;
0赞 Abhinav Akhil 3/30/2023
很高兴听到这个消息
0赞 Mavelo 9/12/2023 #40

最近使用包含 .仅使用以下 CSS 解决(无视口或脚本黑客)....input-group-sm.form-control

input, textarea {
    font-size: 1rem !important;
}
@media (min-width: 768px) {
    input, textarea {
        font-size: inherit !important;
    }
}

这应该使字体足够大,以避免在小型设备上自动缩放。根据需要增加平板电脑的媒体断点(没有可用于测试的断点)。min-width

0赞 MD Obaidullah Al-Faruk 12/14/2023 #41

对于 android 和 iOS,解决方案是不同的。如果我们放置 maximum-scale=1,那么它将停止 android 设备的放大功能,但在 iOS 设备上,它可以预期地工作。 添加此解决方案以在 react 应用程序中解决此问题(在 index.js 文件中)

// Detect the device OS
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);

// Set viewport properties based on the device OS
const viewportContent = isIOS
    ? 'width=device-width, initial-scale=1, maximum-scale=1'
    : 'width=device-width, initial-scale=1, shrink-to-fit=no';

// Create a meta tag and append it to the document head
const metaTag = document.createElement('meta');
metaTag.name = 'viewport';
metaTag.content = viewportContent;
document.head.appendChild(metaTag);