我制作了一个HTML页面,其中有一个<input>标记,类型为“text”。当我在iPhone上使用Safari点击它时,页面会变大(自动缩放)。有人知道如何禁用此功能吗?


当前回答

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

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

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

例如,class:f5相当于:fontSize:1rem,如果您将主体字体比例保持为默认值,则可以使用。

但是:如果您选择字体大小class:f6,则在向上的小屏幕上,这将相当于fontSize:.875rem。在这种情况下,您需要更具体地说明重置声明:


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

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

/* not small */

}

其他回答

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

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

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

值得注意的是,最大比例为1的视口也可以工作,但当页面作为iframe加载时,或者如果您有其他脚本修改视口等,则无法工作。

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

在*.module.ts中声明后,可以像这样使用<input noZoomiOS>

您可以防止Safari在用户输入期间自动放大文本字段,而不禁用用户的缩放功能。只需添加最大比例=1,但忽略其他答案中建议的用户比例属性。

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

<meta name=“viewport”content=“width=设备宽度,初始比例=1,最大比例=1”>

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

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

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