我正在使用多个平板电脑设备 - Android 和iOS 。目前,我对所有平板电脑都有以下分辨率变化。
应用基于设备方向的样式的最简单方法是使用以下语法使用媒体查询的方向。
@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/
以下是从演示页面获取的行为的屏幕截图。
那么,有没有替代方案来解决这个问题,如果基于CSS的原生解决方案不起作用,我会接受基于JavaScript的解决方案。
我在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; }
你们对此有何看法?你有更好的解决方案吗?
答案 0 :(得分:89)
我知道这已经晚了几年但我找到了一个很好的解决方案
对于风景媒体:
@media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */}
对于肖像媒体:
@media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */}
完整的解决方案及其工作原理可以在Michael Barret - Android browser challenges
找到编辑:此链接现已过期,但可以在互联网档案中找到快照:Michael Barret - Android browser challenges
答案 1 :(得分:27)
问题在于计算方向的方式:
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 */
}
此方法比方向更灵活,因为查询不仅限于支持方向的设备/用户代理,更不用说方向tells you very little与宽度的对比。
当然,如果您确实需要了解方向,那么最初设置该类似乎只是使用它可能是您的最佳选择。
答案 2 :(得分:12)
替代方案可能是使用device-aspect-ratio
,它保持不变。但是,在Webkit中,即使JavaScript测试对于新的宽高比返回true,旋转设备也不会使用此查询触发CSS规则的更新。这显然是due to a bug,但我无法找到错误报告。使用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
的使用会将更新限制为实际的方向更改。
答案 3 :(得分:6)
我通过上面列出的选项进行了工作,没有人为我解决问题。我切换到使用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);
答案 4 :(得分:2)
对我来说,这就是诀窍:
@media screen and (max-device-aspect-ratio: 1/1), (max-aspect-ratio: 1/1){
/*Portrait Mode*/
};
虽然max-aspect-ratio
仅通过调整窗口大小(仅适用于PC和其他仅限横向设备)来处理纵向模式,但max-device-aspect-ratio
可帮助智能手机或其他具有可变方向的设备。由于我没有声明横向模式的特定设置,即使max-aspect-ratio
向系统报告&gt; 1,如果Android设备面向的是max-device-aspect-ratio
,仍会触发纵向模式办法。
1/1
部分基本上意味着如果比率<= 1,则进入纵向模式,否则进入横向模式。
答案 5 :(得分:1)
我已经完成了上面的几个答案,但没有一个能够实现我想要的,即尽可能地模仿iPhone的功能。以下是现在正在为我工作的内容。
它的工作原理是将设备视口的窗口宽度和高度分配给数据属性以供将来检查。由于手机在拉起键盘时没有调整宽度,因此只有高度,检查比率和宽度与原始宽度可以告诉您键盘是否已启动。我还没有找到一个失败的用例,但我相信我会。如果你们都找到了,请告诉我。
我正在使用一些全局变量,比如用于js切换的InitialRun和MobileOrientation,我也使用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'});
}
}
}
答案 6 :(得分:1)
我用一个简单的技巧来解决这个问题
node_dev:
build:
context: .
dockerfile: ./.docker/dockerFiles/node.yml
image: foobar/node_dev:latest
container_name: node_dev
working_dir: /home/node/app
ports:
- 8000:8000
- 9000:9000
environment:
- NODE_ENV=development
- GATSBY_WEBPACK_PUBLICPATH=/
volumes:
- ./foobar-blog-ui/:/home/node/app
- ui_node_modules:/home/node/app/node_modules
- ui_gatsbycli_node_module:/usr/local/lib/node_modules/gatsby-cli
- ./.docker/scripts/wait-for-it.sh:/home/node/wait-for-it.sh
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn start'
depends_on:
- mysql
- wordpress
networks:
- foobar-wordpress-network
volumes:
ui_node_modules:
ui_gatsbycli_node_module:
我发现最大宽度:896像素可用于所有移动设备。试试这个解决方案吧!
答案 7 :(得分:0)
看一下这个链接:
http://www.alistapart.com/articles/a-pixel-identity-crisis/
不仅依赖于方向,还依赖于max-device-height
或device-pixel-ratio
可能有所帮助。无论如何,我没有测试它,所以不确定它会有所帮助。
答案 8 :(得分:0)
创意:将肖像参数从媒体查询中删除,并仅保留最小宽度。在该媒体查询中为纵向模式执行正常样式。然后,为景观模式创建另一个媒体查询,其最小高度足够高,以便在弹出键盘时浏览器不会使用该查询。你必须试验这个“足够高的最小高度”是什么,但它不应该太难,因为大多数(如果不是全部)横向模式的高度都比键盘弹出时的高度要大。此外,您可以向横向查询添加“最小宽度”,该纵向查询比纵向视图中的大多数智能手机(即大约400像素左右)更大,以限制查询范围。
这是另一种(和脆弱的)解决方案: - 在你的html中添加一个空的任意元素,除了纵向模式之外,它将具有'display:none'。 - 为input:focus创建一个jquery或javascript监听器。单击输入时,您的javascript将检查任意元素的display属性。如果它返回“阻止”或在纵向模式下设置的任何内容,那么您可以使用JS覆盖您的肖像模式查询样式。相反,你有一个输入:模糊监听器来清空硬编码元素的style.cssText属性。
我现在正在自己尝试这个 - 我会发布一些代码,当我得到一些可靠且易于管理的东西时。 (我的第一个解决方案似乎最合理)。
答案 9 :(得分:0)
这对我来说可靠。我使用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;
以下是我根据方向修改视口的代码。此功能仅适用于移动设备,甚至不适用于平板电脑。这使我可以轻松地为400px和800px(肖像与风景)编写CSS。
_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本身需要根据方向进行更改。不幸的是,在我的工作中,商务人员在没有先咨询开发的情况下编写软件需求。
答案 10 :(得分:0)
我在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 */
}
即;当软键盘出现时,屏幕高度降低但屏幕宽度保持为768px,这导致媒体查询检测屏幕为横向。因此,如上所述的工作。
答案 11 :(得分:0)
由于iPhone 11 Pro Max视口为414 x 896 PX-应该足以定向:横向且最小宽度为500px