Я работаю с несколькими планшетными устройствами - оба Android и iOS. В настоящее время у меня есть следующие варианты разрешения для всех планшетов.
- 1280 х 800
- 1280 x 768
1024 x 768 (очевидно, для iPad)- iPad не имеет этой проблемы
Самый простой способ применить стиль, основанный на ориентации устройства, - использовать ориентацию медиа-запроса с использованием следующего синтаксиса.
@media all and (orientation:portrait)
{
/* My portrait based CSS here */
}
@media all and (orientation:landscape)
{
/* My landscape based CSS here */
}
Это отлично работает на всех планшетных устройствах. НО , проблема в том, что когда устройство находится в портретном режиме, а пользователь нажимает на любое поле ввода (например, поиск), появляется программная клавиатура, которая уменьшает видимую область веб-страницы и заставляет ее отображать в ландшафтном CSS. На планшетах Android это зависит от высоты клавиатуры. Итак, в конечном итоге веб-страница выглядит сломанной. Поэтому я не могу использовать медиа-запрос ориентации CSS3 для применения стилей на основе ориентации (если нет лучшего медиа-запроса для целевой ориентации). Вот скрипка http://jsfiddle.net/hossain/S5nYP/5/, которая эмулирует это - для тестирования устройства используйте полную тестовую страницу - http://jsfiddle.net/S5nYP/embedded/result/
Вот скриншот поведения, взятого с демонстрационной страницы.
Итак, есть ли альтернатива решению этой проблемы, я открыт для решения на основе JavaScript, если собственное решение на основе CSS не работает.
Я нашел фрагмент на http://davidbcalhoun.com/2010/dealing-with-device-orientation, который предлагает добавить класс и настроить таргетинг на основе этого. Например:
<html class="landscape">
<body>
<h1 class="landscape-only">Element Heading - Landscape</h1>
<h1 class="portrait-only">Element Heading - Portrait</h1>
<!-- .... more... ->
# CSS
.landscape .landscape-only { display:block; }
.landspace .portrait-only { display:none; }
.portrait .portrait-only { display:block; }
.portrait .landscape-only { display:none; }
Что вы думаете об этом, ребята? У вас есть лучшее решение?
источник
known limitation
.Ответы:
Я знаю, что это опоздание на пару лет, но я нашел отличное решение
Для ландшафтных СМИ:
@media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */}
А для портретных носителей:
@media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */}
Полное решение и причины его работы можно найти здесь Майкл Баррет - Проблемы с браузером Android
Изменить: срок действия этой ссылки истек, но ее снимок можно найти в интернет-архиве: Майкл Баррет - Проблемы с браузером Android
источник
Проблема заключается в способе расчета ориентации:
http://www.w3.org/TR/css3-mediaqueries/#orientation
Поскольку высота / ширина вычисляется для видимого окна просмотра, мягкая клавиатура, по-видимому, заставляет ориентацию переворачиваться теперь, когда ширина окна просмотра меньше высоты. Одним из решений было бы просто использовать ваши медиа-запросы на основе
width
вместо. Это делает его более гибким для разных устройств независимо от ориентации, не говоря уже о том, что ширина / высота поддерживается более широко, чем ориентация.Если вы хотите учитывать ширину, а не ориентацию, я буду использовать в качестве примера iPhone:
@media screen and (max-width: 320px) { /* rules applying to portrait */ } @media screen and (max-width: 480px) { /* rules applying to landscape */ }
Этот подход более гибкий, чем ориентация, поскольку запросы не ограничиваются устройствами / пользовательскими агентами, которые поддерживают ориентацию, не говоря уже о том, что ориентация говорит вам очень мало по сравнению с шириной.
Конечно, если вам действительно нужно знать ориентацию, кажется, что изначально нужно установить класс и просто использовать это может быть вашим лучшим вариантом.
источник
@media all and (max-device-wdith:NNNpx){}
or@media all and (min-device-wdith:NNNpx){}
or@media all and (device-wdith:NNNpx){}
and (orientation:portrait)
и просто применив максимальную и минимальную ширину, я решил мою проблему. !!!Альтернативой может быть использование
device-aspect-ratio
, которое остается неизменным. Однако в Webkit поворот устройства не запускает обновление правил CSS с использованием этого запроса, даже если тесты JavaScript возвращают значение true для нового соотношения сторон. Очевидно, это из-за ошибки , но я не могу найти отчет об ошибке. Использование комбинацииorientation
и,{min,max}-device-aspect-ratio
кажется, работает нормально:@media screen and (max-device-aspect-ratio: 1/1) and (orientation: portrait) @media screen and (min-device-aspect-ratio: 1/1) and (orientation: landscape)
Использование
orientation
триггеров обновляется, как ожидалось, а использованиеdevice-aspect-ratio
ограничений обновляется с учетом фактических изменений ориентации.источник
Я проработал перечисленные выше варианты, и ни один из них не устранил проблемы. Я перешел на screen.availHeight, так как он дает стабильные результаты по высоте, избегая проблем с отображением клавиатуры.
// Avoiding the keyboard in Android causing the portrait orientation to change to landscape. // Not an issue in IOS. Can use window.orientation. var currentOrientation = function() { // Use screen.availHeight as screen height doesn't change when keyboard displays. if(screen.availHeight > screen.availWidth){ $("html").addClass('portrait').removeClass('landscape'); } else { $("html").addClass('landscape').removeClass('portrait'); } } // Set orientation on initiliasation currentOrientation(); // Reset orientation each time window is resized. Keyboard opening, or change in orientation triggers this. $(window).on("resize", currentOrientation);
источник
Для меня это сработало:
@media screen and (max-device-aspect-ratio: 1/1), (max-aspect-ratio: 1/1){ /*Portrait Mode*/ };
В то время как
max-aspect-ratio
заботится о запуске портретного режима, просто изменяя размер окна (полезно для ПК и других устройств с альбомнойmax-device-aspect-ratio
ориентацией ), помогает со смартфонами или другими устройствами с переменной ориентацией. И поскольку я не объявляю конкретные настройки для ландшафтного режима, даже если системаmax-aspect-ratio
сообщает> 1, портретный режим все равно будет активирован,max-device-aspect-ratio
если устройство Android ориентировано таким образом.1/1
Часть в основном означает , что если отношение <= 1, он переходит в режим портретной, в противном случае она переходит в ландшафтный режим.источник
(max-aspect-ratio: 1/1)
. Кажется, нам нужен этот бит только для определения портрета на рабочем столе?Я пробежался по нескольким из приведенных выше ответов, и ни один из них не сделал именно то, что я хотел, а именно, чтобы имитировать функциональность iPhone как можно точнее. Следующее - то, что у меня сейчас работает в продакшене.
Он работает, назначая ширину окна и высоту области просмотра устройства атрибуту данных для будущей проверки. Поскольку телефоны не меняют ширину при поднятии клавиатуры, только высота, проверка соотношения И ширины относительно исходной ширины может сказать вам, поднята ли клавиатура. Я еще не нашел варианта использования, но я уверен, что найду. Если вы все найдете, дайте мне знать.
Я использую некоторые глобальные объекты, такие как InitialRun и MobileOrientation, которые используются для переключения js, я также использую атрибуты данных html5 для хранения информации в DOM для манипуляций css.
var InitialRun = true; // After the initial bootstrapping, this is set to false; var MobileOrientation = 'desktop'; function checkOrientation(winW, winH){ // winW and winH are the window's width and hieght, respectively if (InitialRun){ if (winW > winH){ $('body').attr('data-height',winW); $('body').attr('data-width',winH); MobileOrientation = 'landscape'; $('body').attr('data-orientation','landscape'); } else{ $('body').attr('data-height',winH); $('body').attr('data-width',winW); MobileOrientation = 'portrait'; $('body').attr('data-orientation','portrait'); } } else{ if (winW > winH && winW != $('body').data('width')){ MobileOrientation = 'landscape'; $('body').hdata('orientation','landscape'); //TODO:uncomment $('body, #wrapper').css({'height':"100%",'overflow-y':'hidden'}); //$('body').attr('data-orientation','portrait'); } else{ MobileOrientation = 'portrait'; $('body').attr('data-orientation','portrait'); $('body, #wrapper').css({'height':$('body').data('height'),'overflow-y':'auto'}); } } }
источник
Я использовал простой прием, чтобы решить эту проблему
@media (max-width: 896px) and (min-aspect-ratio: 13/9){/* Landscape content*/}
Я обнаружил, что max-width: 896px можно использовать для всех мобильных устройств. попробуйте это решение, оно работает!
источник
Взгляните на эту ссылку: http://www.alistapart.com/articles/a-pixel-identity-crisis/
Опора не только на ориентацию, но и на
max-device-height
то, чтоdevice-pixel-ratio
может помочь. Во всяком случае, я не тестировал, поэтому не уверен, что это поможет.источник
Идея: уберите параметр портрета из своего медиа-запроса и оставьте его только с минимальной шириной. Сделайте свой обычный стиль для портретного режима в этом медиа-запросе. Затем создайте еще один медиа-запрос для ландшафтного режима с минимальной высотой, достаточной для того, чтобы браузер не использовал этот запрос при появлении клавиатуры. Вам придется поэкспериментировать с тем, что такое эта «достаточно высокая минимальная высота», но это не должно быть слишком сложно, поскольку большинство (если не все) ландшафтные режимы имеют высоту больше, чем у вас, когда появляется клавиатура. Кроме того, вы можете добавить «минимальную ширину» к запросу с альбомной ориентацией, которая больше, чем у большинства смартфонов в портретной ориентации (т.е. около 400 пикселей), чтобы ограничить область действия запроса.
Вот альтернативное (и непрочное) решение: - Добавьте в свой html пустой произвольный элемент, который будет иметь «display: none» ни в чем другом, кроме портретного режима. - Создайте прослушиватель jquery или javascript для input: focus. При щелчке по входу ваш javascript проверяет свойство отображения произвольного элемента. Если он возвращает «block» или что-то еще, что вы установили в портретном режиме, вы можете переопределить свой стиль с помощью JS для запросов в портретном режиме. И наоборот, у вас будет прослушиватель input: blur, чтобы очистить свойства style.cssText элементов, которые вы жестко закодировали.
Я сам сейчас экспериментирую с этим - я выложу код того, что работает, когда получу что-то надежное и управляемое. (Мое первое решение кажется наиболее разумным).
источник
У меня это работает надежно. Я использую http://detectmobilebrowsers.com/ для расширения jQuery для обнаружения $ .browser.mobile.
if ($.browser.mobile) { var newOrientationPortrait = true; //Set orientation based on height/width by default if ($(window).width() < $(window).height()) newOrientationPortrait = true; else newOrientationPortrait = false; //Overwrite orientation if mobile browser supports window.orientation if (window.orientation != null) if (window.orientation === 0) newOrientationPortrait = true; else newOrientationPortrait = false;
Вот мой код для изменения области просмотра в зависимости от ориентации. Эта функция вызывается только для мобильных устройств, даже не для планшетов. Это позволяет мне легко писать CSS для 400 пикселей и 800 пикселей (портрет против ландшафта).
_onOrientationChange = function() { if (_orientationPortrait) $("meta[name=viewport]").attr("content", "width=400,user-scalable=no"); else $("meta[name=viewport]").attr("content", "width=800"); }
Из-за характера моих требований я не мог сделать это только в запросах CSS Media, так как сама DOM должна была изменяться в зависимости от ориентации. К сожалению, на моей работе деловые люди пишут требования к программному обеспечению без предварительной консультации с разработчиками.
источник
Я столкнулся с той же проблемой в iPad.
т.е. когда программная клавиатура отображается в портретном режиме, устройство обнаруживается в альбомной ориентации, и к экрану применяются стили для альбомной ориентации, что приводит к искаженному представлению.
Спецификация устройства
к сожалению, для меня это решение не сработало.
@media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */} @media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */}
Итак, что я сделал, я написал такой медиа-запрос для моего портретного режима.
@media only screen and (min-width : 300px) and (max-width : 768px) and (orientation : landscape) { /* portrait styles, when softkeyboard appears, goes here */ }
т.е. когда появляется программная клавиатура, высота экрана уменьшается, но ширина экрана остается до 768 пикселей, в результате чего медиа-запрос обнаруживает экран как альбомную ориентацию. Следовательно, работа вокруг дана, как указано выше.
источник
Так как iPhone 11 Pro Max Viewport имеет размер 414 x 896 PX, этого должно быть достаточно, чтобы иметь ориентацию: альбомная с min-width: 500 пикселей.
источник