Я сделал HTML-страницу с <input>
тегом type="text"
. Когда я нажимаю на него с помощью Safari на iPhone, страница становится больше (автоматическое увеличение). Кто-нибудь знает, как это отключить?
Я сделал HTML-страницу с <input>
тегом type="text"
. Когда я нажимаю на него с помощью Safari на iPhone, страница становится больше (автоматическое увеличение). Кто-нибудь знает, как это отключить?
Ответы:
Браузер будет изменять масштаб, если размер шрифта меньше, чем 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
но не указывайте атрибут пользовательского масштаба, предложенный в других ответах.
Это полезный вариант, если у вас есть форма в слое, которая «плавает» при увеличении, что может привести к тому, что важные элементы пользовательского интерфейса переместятся за пределы экрана.
<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" />
Это решает проблему, с которой ваша мобильная страница или форма будут «плавать» вокруг.
В итоге ответ таков: установите размер шрифта элементов формы не менее 16 пикселей
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"/>
Там нет чистого способа я мог бы найти, но вот взломать ...
1) Я заметил, что событие наведения мыши происходит до масштабирования, но масштабирование происходит до событий mousedown или focus.
2) Вы можете динамически изменять тег окна просмотра META, используя javascript (см. Включить / отключить увеличение iPhone Safari с помощью Javascript? )
Итак, попробуйте это (показано в 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" />');
}
Это определенно хак ... могут быть ситуации, когда при наведении / выключении мыши не всегда перехватываются входы / выходы, но это хорошо сработало в моих тестах и является хорошим началом.
Добавьте пользовательский масштабируемый = 0 к мета области просмотра следующим образом
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
Работал для меня :)
Мне недавно (сегодня: D) пришлось интегрировать это поведение. Чтобы не влиять на исходные поля дизайна, включая поля со списком, я решил применить преобразование в фокусе поля:
input[type="text"]:focus, input[type="password"]:focus,
textarea:focus, select:focus {
font-size: 16px;
}
Как уже указывалось во многих других ответах, этого можно достичь, добавив maximum-scale
метатег viewport
. Однако это отрицательно сказывается на отключении пользовательского масштабирования на устройствах Android . ( Он не отключает масштабирование пользователя на устройствах iOS начиная с версии 10 ).
Мы можем использовать JavaScript для динамического добавления maximum-scale
в мету, viewport
когда устройством является iOS. Это обеспечивает лучшее из обоих миров: мы позволяем пользователю увеличивать масштаб и не позволяем 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
? Это исключительно по семантическим причинам?
Взлом Javascript, который работает на iOS 7. Это основано на ответе @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" />');
}
Это сработало для меня:
input, textarea {
font-size: initial;
}
Я использовал решение Кристины выше, но с небольшой модификацией для начальной загрузки и другим правилом, применимым к настольным компьютерам. Размер шрифта по умолчанию в Bootstrap составляет 14 пикселей, что вызывает увеличение. Следующее изменяет его на 16px для «элементов управления форм» в Bootstrap, предотвращая масштабирование.
@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. По крайней мере, на моем iPhone, использующем iOS8, размер шрифта должен быть 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;}
}
Тем не менее, он имеет некоторые недостатки: заметно «скачок» в результате быстрого изменения размера шрифта, происходящего между состояниями «зависание» и «фокус», а также влияние перерисовки на производительность.
Вдохновленный ответом @jirikuchta, я решил эту проблему, добавив немного CSS:
#myTextArea:active {
font-size: 16px; /* `16px` is safer I assume, although `1rem` works too */
}
Нет JS, и я не замечаю ни вспышки, ни чего-либо.
Стоит отметить, что viewport
with maximum-scale=1
также работает, но не тогда, когда страница загружается как iframe, или если у вас есть другой скрипт, модифицирующий и viewport
т. Д.
Псевдоэлементы вроде :focus
не работают, как раньше. Начиная с iOS 11, простое объявление сброса может быть добавлено перед вашими основными стилями (при условии, что вы не переопределите их с меньшим размером шрифта).
/* Prevent zoom */
select, input, textarea {
font-size: 16px;
}
Стоит отметить, что для библиотек CSS, таких как Tachyons.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 */
}
Кстати, если вы используете Bootstrap , вы можете просто использовать этот вариант:
.form-control {
font-size: 16px;
}
Мне пришлось «исправить» проблему с автоматическим увеличением в элементах управления формы для веб-сайта Голландского университета (который использовал 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%, а затем уменьшите 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%;
}
поле ввода будет иметь логический размер шрифта 16 пикселей, в то время как будет отображаться текст размером 12 пикселей.
У меня есть запись в блоге, в которой я немного подробнее расскажу, и этот пример представлен в виде просматриваемого HTML:
в iPhone Safari нет увеличения при вводе, идеальный пиксельный способ
Даже с этими ответами мне потребовалось три дня, чтобы понять, что происходит, и мне может понадобиться решение снова в будущем.
Моя ситуация немного отличалась от описанной.
У меня был какой-то спорный текст в div на странице. Когда пользователь нажал на кнопку DIFFERENT div, своего рода кнопку, я автоматически выделил некоторый текст в contenteditable div (диапазон выбора, который ранее был сохранен и очищен), запустил execCommand расширенного текста в этом выделении и очистил его снова.
Это позволило мне незаметно изменять цвета текста на основе взаимодействия пользователя с цветовыми элементами в других местах на странице, сохраняя при этом выделение, как правило, скрытым, чтобы они могли видеть цвета в правильном контексте.
Что ж, на iPad Safari нажатие на div цвета привело к появлению экранной клавиатуры, и я ничего не сделал, чтобы помешать этому.
Я наконец понял, как iPad делает это.
Он прослушивает последовательность прикосновений и касаний, которые запускают выделение редактируемого текста.
Когда эта комбинация происходит, она показывает экранную клавиатуру.
На самом деле, он выполняет масштабирование тележки, где он расширяет нижележащую страницу, в то же время увеличивая редактируемый текст. Мне потребовался день, чтобы понять, что я вижу.
Таким образом, решение, которое я использовал, состояло в том, чтобы перехватить как touchstart, так и touchend для этих конкретных цветовых элементов. В обоих обработчиках я прекращаю распространение и всплывающие сообщения и возвращаю false. Но в событии touchend я запускаю то же поведение, что и нажатие.
Итак, раньше Safari запускал, как мне кажется, «touchstart», «mousedown», «touchend», «mouseup», «click», и из-за моего кода, выделение текста, в таком порядке.
Новая последовательность из-за перехватов - это просто выделение текста. Все остальное перехватывается до того, как Safari сможет обработать его и выполнить работу с клавиатурой. Перехваты touchstart и touchend также предотвращают запуск событий мыши, и в контексте это вполне нормально.
Я не знаю более простой способ описать это, но я думаю, что важно иметь его здесь, потому что я нашел эту тему в течение часа после первого столкновения с проблемой.
Я на 98% уверен, что то же самое исправление будет работать с полями ввода и всем остальным. Перехватывайте события касания и обрабатывайте их отдельно, не позволяя им распространяться или пузыриться, и подумайте о том, чтобы сделать какие-либо выборки после небольшого тайм-аута, просто чтобы убедиться, что Safari не распознает последовательность как триггер клавиатуры.
Я вижу, что люди здесь делают странные вещи с помощью JavaScript или функции окна просмотра и отключают все масштабирование вручную на устройствах. Это не должно быть решением по моему мнению. Добавление этого фрагмента CSS отключит автоматическое масштабирование в iOS без изменения размера шрифта до фиксированного числа, например 16px.
По умолчанию я использую размер шрифта 93,8% (15 пикселей) в полях ввода и добавляя свой фрагмент кода CSS, он остается на уровне 93,8%. Не нужно менять на 16px или сделать его фиксированным числом.
input[type="text"]:focus,
textarea:focus {
-webkit-text-size-adjust: 100%;
}
Установка размера шрифта (для полей ввода), равного размеру шрифта тела, кажется, что мешает браузеру уменьшать или уменьшать масштаб. Я бы предложил использовать font-size: 1rem
как более элегантное решение.
Поскольку автоматическое увеличение (без уменьшения) все еще раздражает iPhone, вот JavaScript, основанный на предложении dlo работать с фокусом / размытием.
Масштабирование отключается, как только ввод текста дублируется и повторно активируется, когда ввод оставлен.
Примечание: некоторые пользователи могут не ценить редактирование текстов при небольшом вводе текста! Поэтому я лично предпочитаю изменять размер текста ввода во время редактирования (см. Код ниже).
<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));
});
Основываясь на ответе Стивена Уолша ... Этот код работает без изменения размера шрифта для ввода в фокусе (что выглядит неубедительно), плюс он все еще работает с 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)
});
В комментарии к главному ответу об установке размера шрифта в 16px спрашивалось, как это решение, что делать, если вы хотите увеличить / уменьшить шрифт.
Я не знаю всех вас, но использование px для размеров шрифта не лучший способ, вы должны использовать em.
Я столкнулся с этой проблемой на моем адаптивном сайте, где мое текстовое поле больше 16 пикселей. У меня был контейнер формы для 2rem и поле ввода 1.4em. В моих мобильных запросах я изменяю размер шрифта html в зависимости от области просмотра. Поскольку html по умолчанию равен 10, мое поле ввода рассчитывается на 28 пикселей на рабочем столе
Чтобы удалить авто-зум, мне пришлось изменить свой ввод на 1.6em. Это увеличило мой размер шрифта до 32 пикселей. Просто чуть выше и едва заметно. На моем iPhone 4 & 5 я изменяю свой размер шрифта html на 15 пикселей для портрета и обратно на 10 пикселей для ландшафта. Похоже, что лучшим местом для этого размера пикселя было 48 пикселей, поэтому я перешел с 1.4em (42px) на 1.6em (48px).
Все, что вам нужно сделать, это найти нужное место на шрифте, а затем преобразовать его обратно в ваши размеры rem / em.