[javascript] Detect viewport orientation, if orientation is Portrait display alert message advising user of instructions

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.

This question is related to javascript jquery mobile viewport device-orientation

The answer is


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


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

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

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.


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

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.


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(http://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; } 
};

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


Or you could just use this..

window.addEventListener("orientationchange", function() {
    if (window.orientation == "90" || window.orientation == "-90") {
        //Do stuff
    }
}, false);

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() { ... });

$(window).on("orientationchange",function( event ){
    alert(screen.orientation.type)
});

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


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.


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

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


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

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

//see also http://stackoverflow.com/questions/641857/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");
    }
}

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") }

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!");
}

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.


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


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

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.


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

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


screen.orientation.addEventListener("change", function(e) {
 console.log(screen.orientation.type + " " + screen.orientation.angle);
}, false);

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

You can use CSS3 :

@media screen and (orientation:landscape)
{
   body
   {
      background: red;
   }
}

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

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to mobile

How to center a component in Material-UI and make it responsive? NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference Asus Zenfone 5 not detected by computer background: fixed no repeat not working on mobile Check box size change with CSS onClick not working on mobile (touch) Sharing link on WhatsApp from mobile website (not application) for Android Bootstrap 3 Slide in Menu / Navbar on Mobile How to create a link for all mobile devices that opens google maps with a route starting at the current location, destinating a given place? Using form input to access camera and immediately upload photos using web app

Examples related to viewport

disable viewport zooming iOS 10+ safari? Get viewport/window height in ReactJS What does the shrink-to-fit viewport meta attribute do? What is initial scale, user-scalable, minimum-scale, maximum-scale attribute in meta tag? Mobile overflow:scroll and overflow-scrolling: touch // prevent viewport "bounce" Overflow-x:hidden doesn't prevent content from overflowing in mobile browsers Disable Pinch Zoom on Mobile Web scale fit mobile web content using viewport meta tag div with dynamic min-height based on browser window height What's the point of 'meta viewport user-scalable=no' in the Google Maps API

Examples related to device-orientation

How to lock orientation of one view controller to portrait mode only in Swift Force “landscape” orientation mode Detect viewport orientation, if orientation is Portrait display alert message advising user of instructions