我制作了一个带有<input>
标记的HTML页面type="text"
。当我使用iPhone上的Safari单击它时,页面变大(自动缩放)。有人知道如何禁用此功能吗?
我制作了一个带有<input>
标记的HTML页面type="text"
。当我使用iPhone上的Safari单击它时,页面变大(自动缩放)。有人知道如何禁用此功能吗?
Answers:
如果字体大小小于,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;
}
这是没有必要使用所有的上面,你可以风格你所需要的元素,如:只是text
,number
和textarea
:
input[type='text'],
input[type='number'],
textarea {
font-size: 16px;
}
使输入元素从父样式继承的替代解决方案:
body {
font-size: 16px;
}
input[type="text"] {
font-size: inherit;
}
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; }
select:focus
。也有同样的问题。
您可以阻止Safari在用户输入过程中自动放大文本字段,而不会禁用用户捏缩缩放的功能。只需添加maximum-scale=1
但忽略其他答案中建议的用户规模属性。
如果您的图层中的表单在缩放后会“浮动”,这是一个值得选择的选择,这会导致重要的UI元素移出屏幕。
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
@media screen and (-webkit-min-device-pixel-ratio:0) {
select:focus,
textarea:focus,
input:focus {
font-size: 16px;
background: #eee;
}
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
select,
textarea,
input {
font-size: 16px;
}
}
我添加了背景,因为IOS在选择中未添加任何背景。
@media screen and (-webkit-min-device-pixel-ratio:0) and (max-device-width:1024px)
将效果限制为iPhone,但在Chrome浏览器中查看时请勿修改网站。
@supports (-webkit-overflow-scrolling: touch)
,因为这个CSS功能只存在于iOS版
如果您的网站是为移动设备设计的,则可以决定不允许扩展。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
这解决了您的移动页面或表单将“浮动”的问题。
总之,答案是:将表单元素的字体大小设置为至少16px
font-size: 100%
值并获取了16px的像素。
input[type='text'],textarea {font-size:1em;}
1em
或100%
)时,此方法才有效。如果您设置自定义字体大小,则可以font-size
在代码段中设置16px
以避免自动缩放。
1em
也不1rem
是一个妥善的解决办法,因为这两个可以小于16px
和Safari需要至少16px
不放大。
解决此问题的正确方法是将元视口更改为:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
我找不到干净的方法,但是这里有一个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 ...在某些情况下,鼠标悬停/按下并不一定能捕获条目/退出,但是在我的测试中效果很好,并且是一个良好的开端。
我最近(今天:D)不得不整合这种行为。为了不影响包括组合在内的原始设计领域,我选择将转换应用于该领域的重点:
input[type="text"]:focus, input[type="password"]:focus,
textarea:focus, select:focus {
font-size: 16px;
}
将user-scalable = 0添加到视口元,如下所示
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
为我工作:)
正如许多其他答案已经指出的那样,这可以通过添加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
?是否仅出于语义原因?
可在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" />');
}
我在上面使用了克里斯蒂娜(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无法缩放页面。
我做到了,也使用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
字体大小破坏了设计,则可能必须修改界面中的某些其他元素。
经过一段时间的尝试,我想出了这个解决方案
// 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。这将阻止缩放。发生焦点事件时,它将字体大小改回初始值。
与以前发布的解决方案不同,这将使您可以将输入的字体大小设置为所需的大小。
在阅读了几乎每行内容并测试了各种解决方案之后,这要归功于所有共享解决方案的人,这些都是我在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;}
}
但是,由于在“悬停”状态和“聚焦”状态之间字体大小快速变化而导致的“跳跃”,这显然有一些弊端-重绘对性能的影响
诸如此类的伪元素: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 */
}
我不得不为荷兰大学网站(在表单控件中使用15px)“修复”自动缩放表单控件的问题。我提出了以下要求:
到目前为止,这是我想出的:
/*
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);
}
}
一些注意事项:
除了简单地将字体大小设置为16px,您还可以:
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中没有输入缩放功能,像素完美的方式
即使有了这些答案,我也花了三天时间才弄清楚发生了什么,将来我可能会再次需要解决方案。
我的情况与上述情况略有不同。
在我的页面上,我在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不会将序列识别为键盘触发。
我看到这里的人使用JavaScript或视口功能做了一些奇怪的事情,并关闭了所有手动缩放设备的功能。我认为这不应该是解决方案。添加此CSS代码段将关闭iOS中的自动缩放功能,而无需将字体大小更改为固定的数字(例如16px)。
默认情况下,我在输入字段中使用93.8%(15px)的字体大小,并添加我的CSS代码段,使它保持在93.8%。无需更改为16px或将其设置为固定数字。
input[type="text"]:focus,
textarea:focus {
-webkit-text-size-adjust: 100%;
}
由于自动放大(无缩小)在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>
我花了一段时间才找到它,但这是我找到的最好的代码…… 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));
});
基于斯蒂芬·沃尔什(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)
});
有关将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大小。