在iPhone上的Safari浏览器中禁用“文本”标签的自动缩放

863

我制作了一个包含 <input> 标签以及 type="text" 属性的 HTML 页面。当我在 iPhone 上使用 Safari 点击它时,页面会变大(自动缩放)。有人知道如何禁用此功能吗?


11
所有使用 Twitter Bootstrap 的用户注意:还可以参考这个 Github 问题 - Jeroen
78
我发誓,苹果公司是有意制造这些反功能来搞乱我们的思维。 - Andrew Koster
12
@AndrewKoster,即使到了2020年,我仍然同意你的观点。 - Ashok
13
2020年8月,我再次来到这里,希望能在回答中得到奇迹。明年再见。我要吃一个苹果。 - Marc
14
iOS 是下一个 IE。 - step
显示剩余4条评论
40个回答

872

您可以在用户输入期间防止Safari自动放大文本字段,而无需禁用用户拥有缩放的能力。只需添加maximum-scale=1,但不要包含其他答案中建议的user-scale属性。

如果您有一个浮动层中的表单,如果进行缩放会导致重要的UI元素移出屏幕,那么这是一个值得选择的选项。

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


70
这会破坏 Android 设备的缩放功能。 - fen1ksss
5
@daxmacrog,你说得对,但是原帖没有提到他是否希望通过允许所需的行为来打破Android系统。这就是我个人做出错误选择的地方。当然,最好是明确说明。 - fen1ksss
38
@HenrikPetterson,这不仅仅是禁用 OP 指定的自动缩放,还禁用了捏合缩放。因此,我认为这不是2018年以后的解决方案。 - André Werlang
6
这并不准确。正如答案中明确说明的那样,这种解决方案并未禁用Safari(或Firefox)中的双指捏合缩放功能,而这恰恰是原帖提到的问题。但是正如先前的评论所指出的,它确实会禁用安卓设备上的用户缩放功能以及iOS上Chrome浏览器的缩放功能。 - daxmacrog
18
关于maximum-scale=1是否会影响用户手势缩放的问题,有很多人存在困惑。然而,随着苹果在iOS 10中做出正确决定并不再禁用用户手势缩放,这种行为已经发生了改变。好消息是,该设置仍然可以防止自动缩放焦点。 - Dem Pilafian
显示剩余12条评论

655

如果字体大小小于 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;
}

86
为了覆盖所有情况: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"] { 字体大小:16像素; } - Nic Barbier
8
@Nic,你需要使用select:focus。我之前也遇到了同样的问题。 - DGibbs
223
我不明白,这怎么是修正的方法?如果我想要更小/更大的字体大小怎么办? - bryan
54
应该将meta标签更改为:<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> 这样做的正确方式是保持原意不变,但使内容更加通俗易懂。 - Milos Matic
50
在大多数情况下,这可能不是一个好的解决方案,因为它完全防止用户对页面进行缩放。这甚至可能会更加恼人,给您的访客带来困扰。 - BadHorsie
显示剩余22条评论

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

新增: 在输入框没有焦点时,除非使用16px的字体大小,否则IOS仍会放大显示。

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

我添加了一个背景,因为IOS在选择时不会添加背景。


11
这不仅适用于iOS上的Safari(iPhone/iPad/iPod),还适用于Safari/OSX和Chrome(Windows和Mac)。因此,如果你想特别针对iPhone进行定位,这种方法将行不通。 - Redtopia
45
为什么每个人都在说16像素,但没有人提到为什么确切地是16像素?为什么是这个任意的数字?我们为什么要将表单字段文本大小设置为16像素而不是1.8rem或2.5em之类的其他值?这只是一种来自专有操作系统的愚蠢错误吗? - Beebee
15
@Beebee:100%的字体大小是16像素,这是大多数(如果不是所有)浏览器的默认设置(包括桌面版)。IOS也将其设置为默认值,可能是因为这个大小对阅读来说很舒适。为什么会这样设置我没有去研究,也不关心。 - Christina
7
使用 @media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px) 来限制效果只在iPhone上生效,但不要改变在Chrome浏览器中的网站显示。 - BurninLeo
12
不要使用媒体查询,应该使用 @supports (-webkit-overflow-scrolling: touch),因为这个 CSS 特性只存在于 iOS 上。 - James Moran
显示剩余12条评论

227

如果您的网站已经为移动设备进行了适当的设计,您可以决定不允许缩放。

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

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


151
从技术角度来说,这个说法是正确的,但我不同意其理由。在设计良好的网站上禁用用户缩放通常仍然不是一个好主意。 - Fer
26
“Properly designed” 是非常主观的。考虑一个固定的,50像素高的网站头部,在完全响应式并应该在所有浏览器中正常工作的情况下。在iOS Safari上放大会破坏头部的定位,基本上会破坏整个网站。 - Redtopia
71
从用户体验的角度来看,禁用用户缩放功能是一种可怕的做法,应该尽可能避免。自由缩放是一项基本的辅助功能,是您绝不能从用户那里夺走的控制权。 - Gabriel Luethje
87
在原生的移动应用程序中,您从不需要缩放,它们可以正常工作,为什么Web应用程序会有所不同?如果您设置适当的字体大小和行高,并具有清晰的对比度,那么就应该没有问题。 - jotav
51
那些使用“本地应用程序很好”的论点的人忽视了一个事实,即制作精良的本地应用程序遵循操作系统级别的可访问性设置,例如文本大小。年长或视力不佳的用户可以并且确实使用非常大的操作系统范围字体大小,因为他们需要这样做。网络应用程序通常不会或不能遵循此设置,因此允许Web浏览器内置的可访问性功能(如缩放)至关重要。无论您认为什么内容是完全可读的,相信我,总有人会认为它不够清晰。如果您重视可用性,请不要剥夺用户使用此选项的权利。 - Ryan Williams
显示剩余13条评论

107

修复此问题的正确方法是更改视口为:

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

重要提示:请勿设置minimum-scale属性!这将使页面无法手动缩放。


57
这并不是防止此行为的“正确”方式。如果文本被认为太小而无法阅读,则移动Safari会放大它。完全关闭缩放是过于武断的,会阻止用户以他们可能期望的方式与您的页面进行交互。 - AlecRust
8
据称在 iOS10 中,苹果公司更改了 maximum-scale 属性不再被尊重的设置,使得所有站点都可以缩放,而不受其设置的限制。 - Wolfr
4
这适用于iOS10 2016年9月20日版本...至少在我的应用程序上有效...谢谢!!!之前我使用的是<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"> 但我将其更改为响应中的行,它就有效了... - eljamz
4
确保浏览器的捏合缩放功能不会被网页的视口元素所阻挡,以便将页面缩放至200%。应避免在此视口元素中使用限制用户可缩放和最大缩放属性的值。 - danielnixon
1
抱歉打负面评价,但这样做非常有害...您不应该阻止网站的缩放和缩放功能,因为这会损害用户体验。残障人士,特别是那些视力有问题的人可能无法使用您的产品。 - Mike
显示剩余5条评论

101

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


是的,这绝对是避免在移动设备上缩放的最佳实践。没有 js,没有黑客技巧,完全没有变通方法。但即使使用16px,我注意到我的页面仍然有一点缩放,所以我尝试了17px、18px等来观察会发生什么。 - ed1nh0
9
在编写网页时,最好在<body>、<button>、<input>、<textarea>和<select>元素上声明字体大小为100%。这样用户可以设置一个默认值,而不是使用浏览器默认的16像素。有些人在屏幕阅读时可能会遇到困难,他们可能会将默认字体大小设置为18像素或20像素。你不希望强制让他们使用16像素的字体,从而覆盖了他们的选择。不过,在iOS系统中,他们决定放大任何被他们认为太小的字号。不幸的是,看起来它无法解释100%的字号值,所以我们只能添加默认值以满足其需求。 - J. Hogue
关于iOS Safari,截至本评论,Safari似乎正确解释了font-size: 100%的值,并获取了所需的16px。 - Nathan Lafferty

66

正如其他答案已经指出的那样,可以通过在meta viewport标签中添加maximum-scale来实现此目标。但是,这样做会导致Android设备上禁用用户缩放功能。(自版本10起,它不会在iOS设备上禁用用户缩放功能。)

当设备为iOS时,我们可以使用JavaScript动态地将maximum-scale添加到meta 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;

// https://dev59.com/EGox5IYBdhLWcg3wr2To#9039885
const checkIsIOS = () =>
  /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

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

为什么要创建 addMaximumScaleToMetaViewport 的副本?这仅仅是为了语义上的原因吗? - Pherrymason
是的,只需将函数映射到不同的名称,以便清楚地了解它的使用方式。 - Oliver Joseph Ash
5
2021年至今最佳解决方案(稍微整理了一下代码)。 - Crocsx
2023年仍是最佳解决方案! - btown
不可能,它能运行! - bora89

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

3
请注意,将用户可缩放性设置为“否”将禁用所有缩放功能,这可能不是一个好主意。 - stormsweeper
19
只有当你的正文字体大小是默认值(未指定、或 1em、或 100%)时,这才有效。如果你设置了自定义字体大小,你可以将代码片段中的 font-size 设置为 16px 以避免自动缩放。 - Alan H.
我知道这个问题是针对iPhone的,但这种方法更适用于跨平台和未来更多的平台/设备。我尝试了16px的方法,但在Android平板上只减少了自动缩放效果。按照帖子中指定的设置为“1em”解决了这个问题。 - toddles_fp
我有一个自定义字体大小(15像素),将字体大小设置为1rem(而不是em)有效。 - Felipe Castro
4
“1em”和“1rem”都不是合适的解决方案,因为它们都可以小于“16px”,而Safari要求至少为“16px”才能避免缩放。 - Finesse
即使我明确将input元素的font-size设置为16px,在iOS Safari或Chrome上仍无法正常工作... - oldboy

19

不要简单地将字体大小设置为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%来扩大字段,然后使用scale()减少12/16=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示例:
Safari在iPhone上没有输入缩放,完美呈现像素

18

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

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

没有JS,我也没有注意到任何闪存或其他东西。

值得注意的是,具有maximum-scale=1viewport也可以工作,但在页面作为iframe加载时不起作用,或者如果您有某些其他脚本修改了viewport等情况下也不起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接