122

I'm trying to force the "landscape" mode for my application because my application is absolutely not designed for the "portrait" mode. How can I do that?

A-Tech
  • 806
  • 6
  • 22
user1599537
  • 1,269
  • 3
  • 10
  • 10

4 Answers4

114

It is now possible with the HTML5 webapp manifest. See below.


Original answer:

You can't lock a website or a web application in a specific orientation. It goes against the natural behaviour of the device.

You can detect the device orientation with CSS3 media queries like this:

@media screen and (orientation:portrait) {
    // CSS applied when the device is in portrait mode
}

@media screen and (orientation:landscape) {
    // CSS applied when the device is in landscape mode
}

Or by binding a JavaScript orientation change event like this:

document.addEventListener("orientationchange", function(event){
    switch(window.orientation) 
    {  
        case -90: case 90:
            /* Device is in landscape mode */
            break; 
        default:
            /* Device is in portrait mode */
    }
});

Update on November 12, 2014: It is now possible with the HTML5 webapp manifest.

As explained on html5rocks.com, you can now force the orientation mode using a manifest.json file.

You need to include those line into the json file:

{
    "display":      "standalone", /* Could be "fullscreen", "standalone", "minimal-ui", or "browser" */
    "orientation":  "landscape", /* Could be "landscape" or "portrait" */
    ...
}

And you need to include the manifest into your html file like this:

<link rel="manifest" href="manifest.json">

Not exactly sure what the support is on the webapp manifest for locking orientation mode, but Chrome is definitely there. Will update when I have the info.

Luca Fagioli
  • 12,722
  • 5
  • 59
  • 57
Rémi Breton
  • 4,209
  • 2
  • 22
  • 34
54
screen.orientation.lock('landscape');

Will force it to change to and stay in landscape mode. Tested on Nexus 5.

http://www.w3.org/TR/screen-orientation/#examples

ngrashia
  • 9,869
  • 5
  • 43
  • 58
Crowbar
  • 671
  • 5
  • 7
50

I use some css like this (based on css tricks):

@media screen and (min-width: 320px) and (max-width: 767px) and (orientation: portrait) {
  html {
    transform: rotate(-90deg);
    transform-origin: left top;
    width: 100vh;
    height: 100vw;
    overflow-x: hidden;
    position: absolute;
    top: 100%;
    left: 0;
  }
}
php_nub_qq
  • 15,199
  • 21
  • 74
  • 144
pomber
  • 23,132
  • 10
  • 81
  • 94
  • 3
    I used this answer.. all I have to do is to change media query from `landscape` to `portrait` and it works as expected `@media screen and (orientation: portrait)` – ymz Oct 20 '19 at 00:44
  • Edited the answer to help future folks. The rotation should be applied when the current mode is `portrait` (so that it may switch to `landscape`). – lfarroco Dec 23 '19 at 23:51
  • 1
    Thanks. I have been looking for something like this. – underdog Feb 23 '20 at 22:55
  • How I could apply it only on a single page through page-id-xxx? – Homer May 17 '20 at 13:13
  • 4
    thank you for this! I found that you need to change every `vh` to `vw` and `vw` to `vh` in all the CSS files (in portrait mode)... so if somebody didn't succeed it probably because of it. – tomer raitz Dec 16 '20 at 15:26
  • @Homer you can use `html:has(#page-id-xx)` to target it. It's like a pseudo-parent selector. Or you can add the id to the html tag and target with `html#page-id-xx` – Miro Sep 16 '21 at 00:25
  • This is the only solution that works for me. could you tell me how to implement it from the opposite side? that is, now it rotates it pointing to the right, I would like it to point to the left – Luca Jul 14 '22 at 12:43
  • Best answer. The only one that is truly cross device/browser compatible. Manifest approaches still lack support. – Cybernetic Nov 26 '22 at 01:14
  • Warning: if you use `vw` anywhere in your css, things will mess up, because when the device switches between portrait and landscape, `vw` will have different values, while your app always displays horizontally. – ZYinMD Apr 07 '23 at 21:14
1

I had the same problem, it was a missing manifest.json file, if not found the browser decide with orientation is best fit, if you don't specify the file or use a wrong path.

I fixed just calling the manifest.json correctly on html headers.

My html headers:

<meta name="application-name" content="App Name">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="manifest" href="manifest.json">
<meta name="msapplication-starturl" content="/">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#">
<meta name="msapplication-TileColor" content="#">
<meta name="msapplication-config" content="browserconfig.xml">
<link rel="icon" type="image/png" sizes="192x192" href="android-chrome-192x192.png">
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#ffffff">
<link rel="shortcut icon" href="favicon.ico">

And the manifest.json file content:

{
  "display": "standalone",
  "orientation": "portrait",
  "start_url": "/",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "icons": [
  {
    "src": "android-chrome-192x192.png",
    "sizes": "192x192",
    "type": "image/png"
  }
}

To generate your favicons and icons use this webtool: https://realfavicongenerator.net/

To generate your manifest file use: https://tomitm.github.io/appmanifest/

My PWA Works great, hope it helps!

Core972
  • 4,065
  • 3
  • 31
  • 45