CSS媒体查询 – 软键盘打破了css的方向规则 – 替代解决scheme?

我正在使用多个平板电脑设备 – 包括Android 和iOS 。 目前我所有的平板电脑都有以下的分辨率变化。

  • 1280 x 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 */ } 

这在所有平板设备上都可以正常工作。 但是 ,问题是,当设备处于纵向模式,用户在任何input字段(例如search)上点击时,软键popup – 这减less了网页的可见区域,并迫使它在基于CSS的景观中呈现。 在Android平板设备上,这取决于键盘的高度。 所以,最终网页看起来破碎了。 因此,我不能使用CSS3的方向媒体查询来根据方向应用样式(除非有更好的媒体查询来定位方向)。 这是一个小提琴http://jsfiddle.net/hossain/S5nYP/5/模拟这个 – 为设备testing使用完整的testing页面 – http://jsfiddle.net/S5nYP/embedded/result/

以下是从演示页面获取的行为的屏幕截图。 在这里输入图像说明

那么,有没有其他办法来解决这个问题,如果本地基于CSS的解决scheme不工作,我打开基于JavaScript的解决scheme。

我在http://davidbcalhoun.com/2010/dealing-with-device-orientation上find了一个片段,build议在其上添加class和target。 例如:

 <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; } 

你们怎么看待这个? 你有更好的解决scheme吗?

我知道这是晚了几年,但我find了一个很好的解决scheme

对于风景媒体:

 @media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */} 

而对于肖像媒体:

 @media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */} 

完整的解决scheme,为什么它的作品可以在这里find迈克尔·巴雷特 – Android浏览器的挑战

问题在于计算方向的方式:

http://www.w3.org/TR/css3-mediaqueries/#orientation

当“高度”媒体特征的值大于或等于“宽度”媒体特征的值时,“方向”媒体特征是“纵向”。 否则“方向”是“风景”。

由于高度/宽度是在可见视口上计算的,软键盘显然会导致方向翻转,因此视口宽度小于高度。 一种解决scheme就是使用基于width媒体查询。 这使得不pipe方向如何,在设备之间都更加灵活,更不用说宽度/高​​度比定位更广泛的支持。

如果你想考虑宽度而不是方向,我将使用iPhone作为例子:

 @media screen and (max-width: 320px) { /* rules applying to portrait */ } @media screen and (max-width: 480px) { /* rules applying to landscape */ } 

这种方法比定位更灵活,因为查询并不局限于支持定位的设备/用户代理,更不用说定位告诉你很less的宽度。

当然,如果你真的需要知道方向,那么最初设置class级,只是使用这可能是你最好的select。

另一种可能是使用device-aspect-ratio ,它保持不变。 但是,在Webkit中,旋转设备不会触发使用此查询的CSS规则更新,即使JavaScripttesting对于新的宽高比返回true。 这显然是由于一个错误 ,但我无法find一个错误报告。 使用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); 

我已经经历了上面的几个答案,没有一个完全按照我想要的那样做,就是尽可能地模仿iPhone的function。 以下是现在在生产中为我工作的东西。

它通过将设备视口的窗口宽度和高度分配给数据属性以供将来检查。 由于手机在拉起键盘时没有调整宽度,因此只有高度,检查比例和宽度与原始宽度的比较,才能知道键盘是否打开。 我还没有find这个失败的用例,但我相信我会的。 如果你们都find了,请让我知道。

我正在使用一些全局variables,如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'}); } } } 

看看这个链接: http : //www.alistapart.com/articles/a-pixel-identity-crisis/
不仅依赖于方向,而且还取决于max-device-heightdevice-pixel-ratio可能有所帮助。 无论如何,我没有testing它,所以不知道它会有帮助。

build议:将肖像参数从您的媒体查询中取出,并仅以最小宽度保留。 在媒体查询中为肖像模式做正常的样式。 然后,创build另一个横向模式的媒体查询,使用足够高的最小高度,以便在popup键盘时浏览器不会使用该查询。 你必须尝试一下这个“高度足够高的最小高度”是什么,但是它不应该太难,因为大多数(如果不是全部的话)风景模式的高度比popup键盘的高度要大。 此外,你可以添加一个“最小宽度”景观查询,这是大多数智能手机在纵向视图(即大约400px),以限制查询的范围。

下面是一个可选的方法: – 在你的html中添加一个空的任意元素,除了纵向模式之外,其它的都是“display:none”。 – 为input:focus创build一个jQuery或JavaScript侦听器。 当一个input被点击时,你的javascript检查任意元素的显示属性。 如果它返回“块”或任何你在纵向模式下设置它,那么你可以用你的肖像模式查询重写你的样式与JS。 相反,您将有一个input:blur侦听器,以清空您硬编码的元素的style.cssText属性。

我现在正在对这个问题进行实验 – 当我得到一些可靠和可pipe理的东西时,我会发布一些有用的代码。 (我的第一个解决scheme似乎是最合理的)。

这对我来说是可靠的。 我使用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; 

这里是我的代码基于方向修改视口。 此function仅适用于移动设备,不包括平板电脑。 这使我可以轻松地编写400px和800px的CSS(纵向vs横向)。

 _onOrientationChange = function() { if (_orientationPortrait) $("meta[name=viewport]").attr("content", "width=400,user-scalable=no"); else $("meta[name=viewport]").attr("content", "width=800"); } 

由于我的要求的性质,我无法单独在CSS媒体查询中做到这一点,因为DOM本身需要根据方向进行更改。 不幸的是,在我的工作中,业务人员没有先咨询开发就写软件需求。

对我来说,这个窍门是:

  @media screen and (max-device-aspect-ratio: 1/1), (max-aspect-ratio: 1/1){ /*Portrait Mode*/ }; 

尽pipemax-aspect-ratio只需调整窗口大小(对个人电脑和其他横向设备非常有用),但触发纵向模式时, max-device-aspect-ratio可以帮助智能手机或具有可变方向的其他设备。 而且由于我没有声明横向模式的特定设置,即使max-aspect-ratio向系统报告> 1,纵向模式仍然会被max-device-aspect-ratio触发,如果Android设备是这样定向的。

1/1部分基本上意味着如果比例<= 1,则进入纵向模式,否则进入横向模式。