Я сделал 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, и я не замечаю ни вспышки, ни чего-либо.
Стоит отметить, что viewportwith 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.