-webkit-transform: масштаб ломается при увеличении на iOS

EDIT: Похоже, что эти проблемы были исправлены в iOS8. Считайте эту проблему ошибкой iOS7 и более ранних версий.

У меня есть некоторый контент (с учетом CORS), который я отправляю в iframe, и я хочу, чтобы он всегда был растянут в нижней части окна браузера. Мне нужно, чтобы этот контент сохранял то же соотношение сторон и заполнял всю ширину браузера, иначе все будет выглядеть странно. Поскольку у меня нет доступа к содержимому iframe, я использую -webkit-transform: scale для правильного размера всего.

Я рассчитываю масштабный фактор:

width = 600; // this is the original width of the iframe's contents and never changes
scaleFactor = window.innerWidth/width;

Затем я устанавливаю некоторый CSS на основе этого масштабного коэффициента всякий раз, когда размер window.innerWidth изменяется:

$container.css({
    'width': (width * scaleFactor) + 'px',
    'height': (height * scaleFactor) + 'px',
    'padding': 0
});
$iframe.css({
    '-webkit-transform': 'scale('+scaleFactor+')',
    'transform': 'scale('+scaleFactor+')',

    '-webkit-transform-origin': '0 0',
    'transform-origin': '0 0'
});

Это отлично работает везде, кроме iOS, где оно начинает ломаться, если вы слишком сильно увеличиваете масштаб. iFrame начинает смещаться со страницы и становится недостаточно широким. Я понятия не имею, что здесь происходит.

Изображения того, о чем я говорю: Хорошее масштабирование, Плохое масштабирование.

У меня есть настройка тестовой страницы, которая наглядно демонстрирует проблему на любой iOS.

У кого-нибудь есть идеи?


person Mordred    schedule 22.01.2014    source источник


Ответы (2)


Вот результат моего обширного расследования, прежде чем я сдался.

Есть две основные проблемы, связанные с применением преобразования: масштабирование до содержимого внутри фреймов на iOS. Во-первых, я указал в исходном вопросе, что контент начинает отклоняться от указанного места на странице, если вы используете элементы с фиксированной позицией. Он работает до точки, которая, кажется, основана на исходном размере элемента, коэффициенте масштабирования и, предположительно, ширине области просмотра. В моих тестах большой элемент мог идеально масштабироваться и позиционироваться при масштабировании с любым коэффициентом больше 0,85. Небольшой элемент может быть расположен идеально, если коэффициент масштабирования не менее >3,5. Это кажется почти случайным, поэтому я не удосужился определить точную точку.

Я не пробовал это на относительно позиционированных элементах, но я предполагаю, что они функционируют аналогично элементам с фиксированным положением.

Для этого существует довольно неуклюжий обходной путь, включающий использование абсолютно позиционированных элементов, привязанных к нижней части страницы с использованием смещений прокрутки и innerHeight. то есть:

container.css('top', (document.body.scrollTop + window.innerHeight - container.height()) + 'px');
container.css('left', document.body.scrollLeft);

И обновлять это при каждом перетаскивании, преобразовании, сжатии, изменении размера и т. д. С этим методом связана некоторая странность (iOS не обновляет смещения прокрутки до тех пор, пока перетаскивание полностью не остановится), но это работает, если вам абсолютно необходимо это сделать.

Однако, несмотря на то, что это возможно, при масштабировании содержимого внутри iframe на iOS, если у вас есть ЛЮБЫЕ теги привязки (или другие элементы, на которые нужно нажимать), область, по которой можно щелкнуть, остается немасштабируемой. Если у вас есть изображение внутри тега привязки размером 200x100, и вы масштабируете его в 2 раза, изображение будет в два раза больше, но привязка будет реагировать только на первые 200x100. Используя симулятор iOS, если вы дважды щелкнете по изображению за пределами кликабельной области, Safari даже достаточно полезен, чтобы затемнить исходные границы, чтобы вы знали, где вы могли щелкнуть. Это в значительной степени нарушает условия сделки, если вы хотите отобразить что-либо, кроме текста/изображений, которые не требуют кликов или других входных данных. Больше информации здесь:

Проблема масштабирования преобразования CSS3 в iPad Safari

-webkit-transform: scale(2) не не влияет на область щелчка кнопки «Нравится» Facebook (на iPad)

Пока Apple не исправит эти давние ошибки в мобильном Safari, кажется, что попытка масштабировать содержимое iframe с помощью webkit-transform не является жизнеспособным вариантом, если вы не ориентируетесь только на Chrome.

Изменить:

Демонстрация проблем масштабирования здесь.

person Mordred    schedule 27.01.2014
comment
Я подозреваю, что это не ошибки, а меры безопасности, принятые против атак кликджекинга на основе iframe. Вот почему он влияет только на интерактивные элементы. Обычно прозрачность используется для кликджекинга, но, возможно, Apple считает, что преобразование css также можно использовать, поскольку оно может искажать расположение и внешний вид элемента во многих отношениях. - person CodeToad; 27.01.2014
comment
Это, безусловно, возможно в случае мест кликов. Почему масштабированные фреймы не отображаются в правильном месте на странице... но только при определенных коэффициентах масштабирования, похоже, это ошибка. - person Mordred; 27.01.2014
comment
Вы пытались использовать тег для встраивания вместо iframe? вот скрипка, которая работает в ipad при первоначальном тестировании, хотя я не пробовал в меньшем масштабе. jsfiddle.net/Hh7Jf/18. Его часть POC предназначена для изменения масштаба родителя, придавая противоположный масштаб объекту встраивания, не совсем то, что вы делаете, но показывает, что встраивание может работать - person CodeToad; 27.01.2014
comment
Я не пробовал вставлять, пока вы не предложили это. К сожалению, это не работает, потому что я не владею кодом, который вызывается через iframe, и он делает document.write, который, похоже, не становится просто текстом внутри встраивания. Я посмотрел на ваш пример кода, и, похоже, он работает довольно хорошо, даже довольно сильно увеличен. Возможно, стоит продолжить расследование, если вы не привязаны к фреймам. - person Mordred; 27.01.2014

Комбинация iframe, масштаба преобразования и ios сложна.

Есть баги с трансформацией масштаба. Не всегда под вашим контролем.

Вы можете попробовать свойство масштабирования вместо масштаба и использовать масштаб для Firefox, где он не поддерживается.

У меня нет iOS, поэтому я не могу проверить, но это часто творит чудеса. Хотя у вас могут быть проблемы с разрывами строк в тексте с масштабированием.

масштабирование решает эту ошибку в хроме

person CodeToad    schedule 22.01.2014
comment
Проблема в том, что масштабирование не работает с содержимым iframe из-за ограничений CORS. - person Mordred; 23.01.2014
comment
Вы имеете в виду свойство масштабирования css? или какой-то другой зум, например, в метатеге html? если вы примените масштабирование css к родителю iframe, я не верю, что CORS может коснуться этого. - person CodeToad; 23.01.2014
comment
Да, свойство масштабирования css. Я заменил «-webkit-transform»: «масштаб (1.7)» в iframe на «масштабирование»: «1.7», и это ничего не дало. - person Mordred; 24.01.2014