Detect viewport orientation, if orientation is Portrait display alert message advising user of instructions
Asked Answered
D

32

251

I am building a website specifically for mobile devices. There is one page in particular which is best viewed in landscape mode.

Is there a way to detect if the user visiting that page is viewing it in Portrait mode and if so, display a message informing the user that the page is best viewed in landscape mode? If the user is already viewing it in landscape mode then no message will appear.

So basically, I want the site to detect the viewport orientation, if orientation is Portrait, then display an alert message advising the user that this page is best viewed in Landscape mode.

Deon answered 7/2, 2011 at 2:29 Comment(0)
W
337
if(window.innerHeight > window.innerWidth){
    alert("Please use Landscape!");
}

jQuery Mobile has an event that handles the change of this property... if you want to warn if someone rotates later - orientationchange

Also, after some googling, check out window.orientation (which is I believe measured in degrees...)

EDIT: On mobile devices, if you open a keyboard then the above may fail, so can use screen.availHeight and screen.availWidth, which gives proper height and width even after the keyboard is opened.

if(screen.availHeight > screen.availWidth){
    alert("Please use Landscape!");
}
Wigging answered 7/2, 2011 at 3:10 Comment(16)
Thanks for your response. Unfortunately, it doesn't solve the problem of detecting the orientation of the device and displaying an alert message if the device is in Portrait mode.Deon
if(window.height > window.width) alert("please view in landscape"); doesn't work?Wigging
No, unfortunately not. However, the following script did work: if(window.innerHeight > window.innerWidth){ alert("Please view in landscape"); }Deon
I'm having a little trouble getting this working myself. Which element do I need to call this function on? If somebody could post a working example it would be greatly appreciated.Saponin
This script won't work if there's a metatag %meta{content: "app-id=, app-argument=#{request.url}", name: "apple-itunes-app"}/ on iPhone4 because even in portrait mode x is bigger than yZephan
this is incorrect. it is relative to how the page loaded if you have fixed or absolute positioned divs.Dehumanize
I was overcomplexifying the problem. This is great. So simple.Amygdaline
On many devices, when the keyboard is shown, the availableWidth will be greater than the height, incorrectly giving landscape orientation.Zeldazelde
to make it work window.orientation I need to include mobile jquery library in to page?Reset
It doesn't work because if the keyboard is displayed, window.innerHeight < window.innerWidth is true but you are in portrait mode.Emancipator
A great quick solution for simple pages. Note that window.orientation doesn't work on all platforms - if you're using a desktop Chrome browsers, for example, that device has the orientation often undefined.Contrive
@Contrive The question was regarding mobile devices. Desktop Chrome is irrelevant.Suboxide
This doesn't work if combined with the orientationchange event. It will show the old orientation instead of the new orientation. This answer works well combined with the orientationchange event.Sylas
Maybe window.innerWidth > window.innerHeight ? "LANDSCAPE" : "PORTRAIT"Commensal
window.orientation deprecated developer.mozilla.org/en-US/docs/Web/API/Window/orientationKumar
This actually doesn't work when bringing up the keyboard on some OSes. The keyboard popup will make this information flip even though they are still in the same orientation. Going by screen size doesn't work. I highly recommend everyone uses: developer.mozilla.org/en-US/docs/Web/API/Screen/orientation AKA: screen.orientation.typeInextensible
R
245

You can also use window.matchMedia, which I use and prefer as it closely resembles CSS syntax:

if (window.matchMedia("(orientation: portrait)").matches) {
   // you're in PORTRAIT mode
}

if (window.matchMedia("(orientation: landscape)").matches) {
   // you're in LANDSCAPE mode
}

Tested on iPad 2.

Raimundo answered 15/5, 2013 at 14:14 Comment(9)
Support for that feature is kinda weak though: caniuse.com/#feat=matchmediaPsychometrics
In Firefox for Android works properly only after the DOM ready event for me.Buford
Support for this is much stronger now. This seems to be a much more robust answer now then the accepted one.Avowal
Beware of this with this (link) solution #8883663Adalai
This is the correct answer now. This feature has full support for all relevant browsers.Suboxide
This falls prey to the issue where the android keyboard causes the width to exceed the height, the browser will report landscape. - mentioned by @dzv3Unending
This doesn't work if combined with the orientationchange event. It will show the old orientation instead of the new orientation. This answer works well combined with the orientationchange event.Sylas
I've seen this fail on Android webview when checked too soon. It sometimes takes a bit for the height to be registered. If document.documentElement.clientHeight = 0 then this check will always say landscape. Same for the width/height comparison check, of course.Tulley
this doesn't work in Android with keyboard visible. To get rid of it without breaking iOS: window.matchMedia("(orientation: portrait)").matches || (window.outerWidth != screen.availHeight && screen.availHeight > screen.availWidth)Viguerie
I
113

David Walsh has a better and to the point approach.

// Listen for orientation changes
window.addEventListener("orientationchange", function() {
  // Announce the new orientation number
  alert(window.orientation);
}, false);

During these changes, the window.orientation property may change. A value of 0 means portrait view, -90 means a the device is landscape rotated to the right, and 90 means the device is landscape rotated to the left.

http://davidwalsh.name/orientation-change

Isacco answered 31/7, 2012 at 7:11 Comment(8)
On the Nexus 10, and I don't know about other Android 10" tablets, the values are backwards. I.e. 0 is returned when the device is in landscape, not portrait. tobyodavies's answer above seems to work well though across all devices I've testedThermometry
Orientation 0 is given to be the "natural" orientation of the device, and thus is vendor-dependent. It could be portrait or landscape...Zeldazelde
on ipad in iframe did not alert anythingObolus
this is not good solution for detection orientation mod of device. Because they return value depend of natural device orientation. Example on Samsung 7' tablet portrait view return 90 but on nexus 4 for portrait they return 0.Centavo
Not all devices will report the same values: notes.matthewgifford.com/…Aboard
On this link: notes.matthewgifford.com/… The author showcase different devices from different manufacturers have different interpretation of what is landscape and portrait. Hence different reported values, which you cannot really rely on.Aboard
orientation is unsupported in iOSEsotropia
orientationchange is deprecatedPenniepenniless
S
41

You can use CSS3 :

@media screen and (orientation:landscape)
{
   body
   {
      background: red;
   }
}
Sideline answered 26/4, 2013 at 8:39 Comment(7)
Best answer to me, because you don't need a listener for changed orientation. Although I combine it with modernizr to detect if it is a touch-device, since it makes no sense on desktop or laptop screens. Still not ok for such screens WITH touch capabilities...Stellular
Not related to javascript. OP needs javascript solution.Tolson
No, he wants to display a message, you can use display:none then display:block to display something.Sideline
What is the support like for this CSS check?Rowdy
I dont know, but I didnt find a mobile that doesnot support it. Also it seems broken on old Android, when keyboard shows up sometimes the media query is trigged.Sideline
Unfortunately although this is pretty awesome, as Thomas said I found that on iPhone and Android when the keyboard comes up the media query is triggered, if anyone has an answer I raised the issue hereChalcanthite
This is great, not giving me any issues when activating the keyboard.Savoury
T
26

There are a few ways to do it, for example:

  • Check window.orientation value
  • Compare innerHeight vs. innerWidth

You can adapt one of the methods below.


Check if device is in portrait mode

function isPortrait() {
    return window.innerHeight > window.innerWidth;
}

Check if device is in landscape mode

function isLandscape() {
    return (window.orientation === 90 || window.orientation === -90);
}

Example usage

if (isPortrait()) {
    alert("This page is best viewed in landscape mode");
}

How do I detect the orientation change?

$(document).ready(function() {
    $(window).on('orientationchange', function(event) {
        console.log(orientation);
    });
});
Techy answered 12/3, 2014 at 1:0 Comment(0)
N
12

I think the more stable solution is to use screen instead of window, because it could be both - landscape or portrait if you will resize your browser window on desktop computer.

if (screen.height > screen.width){
    alert("Please use Landscape!");
}
Namhoi answered 19/1, 2013 at 10:38 Comment(5)
This works in IE 10, Firefox 23 and Chrome 29 (all desktop browsers).Squier
All major browsers support it. IE 7 as wellNamhoi
not standard, though: developer.mozilla.org/en-US/docs/Web/API/…Binah
@Duncan No. It works on mobile. It is a pretty old method and it's supported on old safari and android browsers. It may be not very accurate with retina but for detecting viewport orientation it should work fineNamhoi
@Namhoi I tested it yesterday and it appears that Safari returns the physical screen dimensions neglecting the orientation. So screen.width is always the physical width of the screen.Puffin
A
10

In order to apply all of these great comments to my daily coding, for continuity between all my applications, I have decided to use the following in both my jquery and jquery mobile code.

window.onresize = function (event) {
  applyOrientation();
}

function applyOrientation() {
  if (window.innerHeight > window.innerWidth) {
    alert("You are now in portrait");
  } else {
    alert("You are now in landscape");
  }
}
Achlorhydria answered 23/6, 2014 at 12:51 Comment(0)
A
10

CCS only

@media (max-width: 1024px) and (orientation: portrait){ /* tablet and smaller */
  body:after{
    position: absolute;
    z-index: 9999;
    width: 100%;
    top: 0;
    bottom: 0;
    content: "";
    background: #212121 url(https://i.stack.imgur.com/sValK.png) 0 0 no-repeat; /* replace with an image that tells the visitor to rotate the device to landscape mode */
    background-size: 100% auto;
    opacity: 0.95;
  }
}

In some cases you may want to add a small piece of code to reload to page after the visitor rotated the device, so that the CSS is rendered properly:

window.onorientationchange = function() { 
    var orientation = window.orientation; 
        switch(orientation) { 
            case 0:
            case 90:
            case -90: window.location.reload(); 
            break; } 
};
Amoeboid answered 16/8, 2016 at 15:32 Comment(2)
I know I'm not supposed to but I had to say thanks for this, it's a great solve.Fluctuant
as of 2021, it's supported in all modern browsers caniuse.com/?search=media%20orientationClary
W
8

Don't try fixed window.orientation queries (0, 90 etc doesn't mean portrait, landscape etc):

http://www.matthewgifford.com/blog/2011/12/22/a-misconception-about-window-orientation/

Even on iOS7 depending how you come into the browser 0 isn't always portrait

Witherite answered 13/11, 2013 at 16:8 Comment(2)
i don't think this is true anymoreCoreencorel
It is still true... cannot assume anything from pure orientation.angle. You need to check also orientation.type and this makes it bit complicated.Ancipital
M
7

I combined two solutions and it works fine for me.

window.addEventListener("orientationchange", function() {                   
    if (window.matchMedia("(orientation: portrait)").matches) {
       alert("PORTRAIT")
     }
    if (window.matchMedia("(orientation: landscape)").matches) {
      alert("LANSCAPE")
     }
}, false);
Monies answered 20/6, 2016 at 9:15 Comment(0)
E
7

I disagree with the most voted answer. Use screen and not window

    if(screen.innerHeight > screen.innerWidth){
    alert("Please use Landscape!");
}

Is the proper way to do it. If you calculate with window.height, you ll have trouble on Android. When keyboard is open, window shrinks. So use screen instead of window.

The screen.orientation.type is a good answer but with IE. https://caniuse.com/#search=screen.orientation

Emancipator answered 31/5, 2017 at 7:5 Comment(2)
As of Mar 2021, there is no screen.innerHeight ... on Chrome at least. There is a screen.availHeight. And screen.height exists too.Devotion
Same for Firefox, there is screen.availHeight and screen.availWidth which works for all browsersExclusive
O
7
$(window).on("orientationchange",function( event ){
    alert(screen.orientation.type)
});
Outreach answered 18/7, 2017 at 10:8 Comment(1)
unfortunately not supported by SafariLubricious
W
5

After some experimentation I have found that rotating an orientation aware device will always trigger a browser window's resize event. So in your resize handler simply call a function like:

function is_landscape() {
  return (window.innerWidth > window.innerHeight);
}
Welch answered 23/1, 2013 at 23:41 Comment(1)
See above as to why 90 => landscape isn't something you can rely on across different devices.Rowdy
R
4

iOS doens't update screen.width & screen.height when orientation changes. Android doens't update window.orientation when it changes.

My solution to this problem:

var isAndroid = /(android)/i.test(navigator.userAgent);

if(isAndroid)
{
    if(screen.width < screen.height){
        //portrait mode on Android
    }
} else {
    if(window.orientation == 0){
        //portrait mode iOS and other devices
    }
}

You can detect this change in orientation on Android as well as iOS with the following code:

var supportsOrientationChange = "onorientationchange" in window,
    orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";

window.addEventListener(orientationEvent, function() {
    alert("the orientation has changed");
}, false);

If the onorientationchange event is not supported, the event bound will be the resize event.

Revert answered 19/10, 2016 at 12:4 Comment(0)
E
3

Get the orientation (at any time in your js code) via

window.orientation

When window.orientation returns 0 or 180 then you are in portrait mode, when returning 90 or 270 then you are in landscape mode.

Emeric answered 11/7, 2013 at 13:9 Comment(4)
It doesn't return 270 though, it returns -90.Decadent
@FelipeCorrea The answer is 2 years old!Emeric
I was clarifying to make it valid for new visitors. It helped me btw.Decadent
window.orientation is deprecatedBuckskin
A
3

If you have the latest browsers window.orientation might not work. In that case use following code for getting angle -

var orientation = window.screen.orientation.angle;

This is still an experimental technology, you can check the browser compatibility here

Angle answered 31/8, 2018 at 10:38 Comment(0)
F
2
//see also https://mcmap.net/q/40981/-javascript-window-resize-event
//see also http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html
/*
Be wary of this:
While you can just hook up to the standard window resize event, you'll find that in IE, the event is fired once for every X and once for every Y axis movement, resulting in a ton of events being fired which might have a performance impact on your site if rendering is an intensive task.
*/

//setup 
window.onresize = function(event) {
    window_resize(event);
}

//timeout wrapper points with doResizeCode as callback
function window_resize(e) { 
     window.clearTimeout(resizeTimeoutId); 
     resizeTimeoutId = window.setTimeout('doResizeCode();', 10); 
}

//wrapper for height/width check
function doResizeCode() {
    if(window.innerHeight > window.innerWidth){
        alert("Please view in landscape");
    }
}
Fleurdelis answered 7/2, 2011 at 18:35 Comment(0)
C
2

another alternative to determine orientation, based on comparison of the width/height:

var mql = window.matchMedia("(min-aspect-ratio: 4/3)");
if (mql.matches) {
     orientation = 'landscape';
} 

You use it on "resize" event:

window.addEventListener("resize", function() { ... });
Carlicarlick answered 16/9, 2015 at 14:14 Comment(0)
T
2

Here's the best method I found, based on David Walsh's article (Detect Orientation Change on Mobile Devices)

if ( window.matchMedia("(orientation: portrait)").matches ) {  
   alert("Please use Landscape!") 
}

Explanation:

Window.matchMedia() is a native method that allows you to define a media query rule and check its validity at any point in time.

I find it useful to attach an onchange listener on the return value of this method. Example:

var mediaQueryRule = window.matchMedia("(orientation: portrait)")
mediaQueryRule.onchange = function(){ alert("screen orientation changed") }
Trojan answered 11/5, 2016 at 4:41 Comment(0)
F
2

There's a way by which you can detect if user flipped their device to portrait mode using screen.orientation

Just use the bellow code:

screen.orientation.onchange = function () {
     var type = screen.orientation.type;
     if (type.match(/portrait/)) {
         alert('Please flip to landscape, to use this app!');
     }
}

Now, onchange will get fired when ever user flips the device and alert will pop-up when user using portrait mode.

Flutist answered 30/7, 2016 at 18:30 Comment(0)
F
2

Some devices don't provide the orientationchange event, but do fire the window's resize event:

// Listen for resize changes
window.addEventListener("resize", function() {
    // Get screen size (inner/outerWidth, inner/outerHeight)

}, false);

A bit less obvious than the orientationchange event, but works very well. Please check here

Flaring answered 3/10, 2018 at 15:16 Comment(0)
D
1

Thanks to tobyodavies for guiding the way.

To achieve an alert message based on the mobile device's orientation you need to implement the following script within the function setHeight() {

if(window.innerHeight > window.innerWidth){
    alert("Please view in landscape");
}
Deon answered 7/2, 2011 at 2:29 Comment(0)
M
1

Instead of 270, it can be -90 (minus 90).

Marler answered 14/7, 2013 at 17:9 Comment(0)
L
1

This expands on a previous answer. The best solution I've found is to make an innocuous CSS attribute that only appears if a CSS3 media query is met, and then have the JS test for that attribute.

So for instance, in the CSS you'd have:

@media screen only and (orientation:landscape)
{
    //  Some innocuous rule here
    body
    {
        background-color: #fffffe;
    }
}
@media screen only and (orientation:portrait)
{
    //  Some innocuous rule here
    body
    {
        background-color: #fffeff;
    }
}

You then go to JavaScript (I'm using jQuery for funsies). Color declarations may be weird, so you may want to use something else, but this is the most foolproof method I've found for testing it. You can then just use the resize event to pick up on switching. Put it all together for:

function detectOrientation(){
    //  Referencing the CSS rules here.
    //  Change your attributes and values to match what you have set up.
    var bodyColor = $("body").css("background-color");
    if (bodyColor == "#fffffe") {
        return "landscape";
    } else
    if (bodyColor == "#fffeff") {
        return "portrait";
    }
}
$(document).ready(function(){
    var orientation = detectOrientation();
    alert("Your orientation is " + orientation + "!");
    $(document).resize(function(){
        orientation = detectOrientation();
        alert("Your orientation is " + orientation + "!");
    });
});

The best part of this is that as of my writing this answer, it doesn't appear to have any effect on desktop interfaces, since they (generally) don't (seem to) pass any argument for orientation to the page.

Laevogyrate answered 29/9, 2015 at 21:2 Comment(1)
As a note Windows 10 and Edge might be throwing a wrench into this - I haven't done substantial testing on the new platform yet, but at least initially, it seems like it might be supplying orientation data to the browser. It's still possible to build your site around it, but it is definitely something to be aware of.Laevogyrate
C
1

I used for Android Chrome "The Screen Orientation API"

To look the current orientation call console.log(screen.orientation.type) (and maybe screen.orientation.angle).

Results: portrait-primary | portrait-secondary | landscape-primary | landscape-secondary

Below is my code, I hope it'll be helpful:

var m_isOrientation = ("orientation" in screen) && (typeof screen.orientation.lock == 'function') && (typeof screen.orientation.unlock == 'function');
...
if (!isFullscreen()) return;
screen.orientation.lock('landscape-secondary').then(
    function() {
        console.log('new orientation is landscape-secondary');
    },
    function(e) {
        console.error(e);
    }
);//here's Promise
...
screen.orientation.unlock();
  • I tested only for Android Chrome - ok
Calefacient answered 9/6, 2016 at 13:11 Comment(0)
B
1
screen.orientation.addEventListener("change", function(e) {
 console.log(screen.orientation.type + " " + screen.orientation.angle);
}, false);
Beneficiary answered 4/8, 2016 at 19:12 Comment(2)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations!Disgorge
This answer does not solve the problem in the original question. It shows how to log orientation changes, but it does not show how to display a message only in one particular orientation.Watchmaker
A
1

The window object in JavaScript on iOS devices has an orientation property that can be used to determine the rotation of the device. The following shows the values window.orientation for iOS devices (e.g. iPhone, iPad, iPod) at different orientations.

This solution also works for android devices as well. I checked in android native browser (Internet browser) and in the Chrome browser, even in the old versions of it.

function readDeviceOrientation() {                      
    if (Math.abs(window.orientation) === 90) {
        // Landscape
    } else {
        // Portrait
    }
}
Arlie answered 13/9, 2016 at 11:59 Comment(1)
window.orientation is Deprecated! MDN Window.orientation propertyBrimful
H
1

This is what I use.

function getOrientation() {

    // if window.orientation is available...
    if( window.orientation && typeof window.orientation === 'number' ) {

        // ... and if the absolute value of orientation is 90...
        if( Math.abs( window.orientation ) == 90 ) {

              // ... then it's landscape
              return 'landscape';

        } else {

              // ... otherwise it's portrait
              return 'portrait';

        }

    } else {

        return false; // window.orientation not available

    }

}

Implementation

window.addEventListener("orientationchange", function() {

     // if orientation is landscape...
     if( getOrientation() === 'landscape' ) {

         // ...do your thing

    }

}, false);
Haught answered 6/4, 2017 at 16:21 Comment(1)
Your code have a mistake: // if window.orientation is available... if( window.orientation && typeof window.orientation === 'number' ) { the if in and doesn't work if window.orientation=0Rident
H
0
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>Rotation Test</title>
  <link type="text/css" href="css/style.css" rel="stylesheet"></style>
  <script src="js/jquery-1.5.min.js" type="text/javascript"></script>
  <script type="text/javascript">
        window.addEventListener("resize", function() {
            // Get screen size (inner/outerWidth, inner/outerHeight)
            var height = $(window).height();
            var width = $(window).width();

            if(width>height) {
              // Landscape
              $("#mode").text("LANDSCAPE");
            } else {
              // Portrait
              $("#mode").text("PORTRAIT");
            }
        }, false);

  </script>
 </head>
 <body onorientationchange="updateOrientation();">
   <div id="mode">LANDSCAPE</div>
 </body>
</html>
Haydon answered 8/1, 2015 at 14:10 Comment(0)
P
0

One thing to note about window.orientation is that it will return undefined if you are not on a mobile device. So a good function to check for the orientation might look like this, where x is window.orientation:

//check for orientation
function getOrientation(x){
  if (x===undefined){
    return 'desktop'
  } else {
    var y;
    x < 0 ? y = 'landscape' : y = 'portrait';
    return y;
  }
}

Call it like so:

var o = getOrientation(window.orientation);
window.addEventListener("orientationchange", function() {
  o = getOrientation(window.orientation);
  console.log(o);
}, false);
Punctate answered 19/10, 2016 at 12:5 Comment(0)
R
0

Or you could just use this..

window.addEventListener("orientationchange", function() {
    if (window.orientation == "90" || window.orientation == "-90") {
        //Do stuff
    }
}, false);
Refill answered 4/5, 2017 at 0:44 Comment(1)
It's better to add window.orientation === 90 test egality between number and string is not sure.Ician
G
0

As you know when device is portrait the width is lower than height of screen.
And when device is landscape the height is lower than width of screen so this will be the code :

var isPortrait = window.innerWidth > window.innerHeight ? false : true;
Grantham answered 23/3, 2023 at 16:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.