Prevent orientation change in iOS Safari

Is it possible to avoid transition to landscape view in Safari for iOS when the device is rotated?

iOS Safari has the "orentationchange" event, I tried to intercept it and disable the default behavior, like this:

<html>
<head>
<script type="text/javascript">
function changeOrientation(event) {
    alert("Rotate");
    event.preventDefault();
}
</script>
</head>
<body onorientationchange="changeOrientation(event);">
PAGE CONTENT
</body>
</html>

but when testing the page on my iPhone, when I rotate the device the alert is shown, but the view switch to landscape. It seems that event.preventDefault() does not stops the rotation.

Is there a way to block this behavior?


Jonathan Snook has a work around to this problem. In his slides here, he shows how to (sort of) lock to portrait (see slide 54 and 55).

The JS code from those slides:

window.addEventListener('orientationchange', function () {
    if (window.orientation == -90) {
        document.getElementById('orient').className = 'orientright';
    }
    if (window.orientation == 90) {
        document.getElementById('orient').className = 'orientleft';
    }
    if (window.orientation == 0) {
        document.getElementById('orient').className = '';
    }
}, true);

and the CSS:

.orientleft #shell {
    -webkit-transform: rotate(-90deg);
    -webkit-transform-origin:160px 160px;
}

.orientright #shell {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin:230px 230px;
} 

I tried to get this working for landscape on the iPhone, but it never looked 100% correct. I came close with the following jQueryian code, however. This would be within the onready function. Also note: this was within a "saved to homescreen" context, and I think that altered the position of the tranform-origin.

$(window).bind('orientationchange', function(e, onready){
   if(onready){
       $(document.body).addClass('portrait-onready');
   }
   if (Math.abs(window.orientation) != 90){
       $(document.body).addClass('portrait');
   } 
   else {
       $(document.body).removeClass('portrait').removeClass('portrait-onready');
   }
});
$(window).trigger('orientationchange', true); // fire the orientation change event at the start, to make sure 

And the CSS:

.portrait {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin: 200px 190px;
}
.portrait-onready {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin: 165px 150px;
}

Hope that helps someone get close to the desired result...


There is no way to force a particular orientation in Mobile Safari; it'll always autorotate when the user rotates their device.

Perhaps you can display something for unsupported orientations informing the user that the orientations aren't supported, and that they need to rotate the device back in order to use your web app.


While you cannot prevent orientation change from taking effect you can emulate no change as stated in other answers.

First detect device orientation or reorientation and, using JavaScript, add a class name to your wrapping element (in this example I use the body tag).

function deviceOrientation() {
  var body = document.body;
  body.classList = '';
  switch(window.orientation) {
    case 90:
      body.classList.add('rotation90');
      break;
    case -90:
      body.classList.add('rotation-90');
      break;
    default:
      body.classList.add('portrait');
      break;
  }
}
window.addEventListener('orientationchange', deviceOrientation);
deviceOrientation();

Then if the device is landscape, use CSS to set the body width to the viewport height and the body height to the viewport width. And let’s set the transform origin while we’re at it.

@media screen and (orientation: landscape) {
  body {
    width: 100vh;
    height: 100vw;
    transform-origin: 0 0;
  }
}

Now, reorient the body element and slide (translate) it into position.

body.rotation-90 {
  transform: rotate(90deg) translateY(-100%);
}
body.rotation90 {
  transform: rotate(-90deg) translateX(-100%);
}