Detecting device orientation

  • Revision slug: Detecting_device_orientation
  • Revision title: Detecting device orientation
  • Revision id: 348179
  • Created:
  • Creator: ziyunfei
  • Is current revision? No
  • Comment

Revision Content

{{ gecko_minversion_header("1.9.1") }}

Increasingly, web-enabled devices are capable of determining their orientation; that is, they can report data indicating changes to their orientation with relation to the pull of gravity. In particular, hand-held devices such as mobile phones can use this information to automatically rotate the display to remain upright, presenting a wide-screen view of the web content when the device is rotated so that its width is greater than its height.

There are three ways to deal with orientation information in Gecko. The first is the orientation media query. This lets content adjust its layout using CSS, based on whether the device is in landscape mode (that is, its width is greater than its height) or portrait mode (its height is greater than its width).

The second way to handle orientation information is the DeviceOrientationEvent which was added in Firefox 6.  This event is sent when the accelerometer detects a change to the orientation of the device. By receiving and processing the data reported by these orientation events, it's possible to interactively respond to rotation and elevation changes caused by the user moving the device. Previous to this implementation was the experimental MozOrientation event added in Gecko 1.9.2 (Firefox 3.6).

The third way is to listen for the DeviceMotionEvent. This event is sent when a change in acceleration was added. It is different from the DeviceOrientationEvent because it is listening for changes in acceleration as opposed to orientation. Sensors that are commonly capable of detecting DeviceMotionEvent include sensors in laptops to protect moving storage devices. DeviceOrientationEvent are more commonly found in mobile devices.

Adjusting layout when the orientation changes

One of the most common cases in which you'll be interested in orientation changes is when you want to revise the layout of your content based on the orientation of the device. For example, perhaps you want a button bar to stretch along the longest dimension of the device's display. By using a media query, you can do this easily and automatically.

Build the CSS for each orientation

For this use case, you'll need two stylesheets: one to be used when the device is in portrait orientation (its height is greater than its width), and one to be used when the device is in landscape orientation (its width is greater than its height).

Portrait Landscape

#toolbar {
  width: 100%;
}

#toolbar {
  min-height: 500px;
  width: 125px;
  margin-right: 8px;
  float: left;
}

As you can see if you study the two CSS fragments above, when in portrait mode, we make the toolbar stretch horizontally across the top of the window, in order to maximize the horizontal space available for content. In landscape mode, the toolbar stretches vertically down the left side of the document.

Applying the correct CSS based on the current orientation

All you have to do now is establish the media queries that will automatically select the correct CSS file based on the orientation of the device. This is simple:

<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css">
<link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css">

From this point on, loading the content results in the correct layout being applied based on the device's orientation.

Processing orientation events

{{ gecko_minversion_header("6.0") }}

Firefox 6 removed the MozOrientation event when adding support for the DeviceOrientationEvent , which you can listen for in order to receive updates as the user adjusts the orientation of the device.

All you need to do in order to begin receiving orientation events is this:

window.addEventListener("deviceorientation", handleOrientation, true);

After registering your event listener (in this case, a JavaScript function called handleOrientation()), your listener function periodically gets called with updated orientation data.

The orientation event contains four values:

{{ domxref("DeviceOrientationEvent.absolute") }}

{{ domxref("DeviceOrientationEvent.alpha") }}

{{ domxref("DeviceOrientationEvent.beta") }}

{{ domxref("DeviceOrientationEvent.gamma") }}

The event handler function can look something like this:

function handleOrientation(orientData) {
  var absolute = orientData.absolute;
  var alpha = orientData.alpha;
  var beta = orientData.beta;
  var gamma = orientData.gamma;

  // Do stuff with the new orientation data
}

Accelerometer values explained

The value reported for each axis indicates the amount of rotation around a given axis in reference to a standard coordinate frame.  These are described in greater detail in the Orientation and motion data explained article which is summarized below. 

The DeviceOrientationEvent.alpha value represents the motion of the device around the z axis, represented in degrees with values ranging from 0 to 360.

The DeviceOrientationEvent.beta value represents the motion of the device around the x axis, represented in degrees with values ranging from -180 to 180.  This represents a front to back motion of the device.

The DeviceOrientationEvent.gamma value represents the motion of the device around the y axis, represented in degrees with values ranging from -90 to 90. This represents a left to right motion of the device.

Browser Compatibility

Compatibility for DeviceOrientationEvent:

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)

Basic support

7.0

3.6

{{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }}
Feature Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Basic support

3.0

3.6

{{ CompatNo() }} {{ CompatNo() }}

4.2

Firefox 3.6, 4, and 5 supported mozOrientation versus the specified DeviceOrientation event

See also

Specification

Revision Source

<p>{{ gecko_minversion_header("1.9.1") }}</p>
<p>Increasingly, web-enabled devices are capable of determining their <strong>orientation</strong>; that is, they can report data indicating changes to their orientation with relation to the pull of gravity. In particular, hand-held devices such as mobile phones can use this information to automatically rotate the display to remain upright, presenting a wide-screen view of the web content when the device is rotated so that its width is greater than its height.</p>
<p>There are three ways to deal with orientation information in Gecko. The first is the <a href="/en-US/CSS/Media_queries#orientation" title="en-US/CSS/Media queries#orientation">orientation media query</a>. This lets content adjust its layout using CSS, based on whether the device is in landscape mode (that is, its width is greater than its height) or portrait mode (its height is greater than its width).</p>
<p>The second way to handle orientation information is the <a href="/en-US/DOM/DeviceOrientationEvent" title="DeviceOrientationEvent">DeviceOrientationEvent</a> which was added in Firefox 6.&nbsp; This event is sent when the accelerometer detects a change to the orientation of the device. By receiving and processing the data reported by these orientation events, it's possible to interactively respond to rotation and elevation changes caused by the user moving the device. Previous to this implementation was <a href="/en-US/DOM/MozOrientation" title="en-US/DOM/MozOrientation">the experimental <code>MozOrientation</code> event</a> added in Gecko 1.9.2 (Firefox 3.6).</p>
<p>The third way is to listen for the <a href="/en-US/DOM/DeviceMotionEvent" title="DeviceMotionEvent">DeviceMotionEvent</a>. This event is sent when a change in acceleration was added. It is different from the <a href="/en-US/DOM/DeviceOrientationEvent" title="DeviceOrientationEvent">DeviceOrientationEvent</a> because it is listening for changes in acceleration as opposed to orientation. Sensors that are commonly capable of detecting <a href="/en-US/DOM/DeviceMotionEvent" title="DeviceMotionEvent">DeviceMotionEvent</a> include sensors in laptops to protect moving storage devices. <a href="/en-US/DOM/DeviceOrientationEvent" title="DeviceOrientationEvent">DeviceOrientationEvent</a> are more commonly found in mobile devices.</p>
<h2 id="Adjusting_layout_when_the_orientation_changes">Adjusting layout when the orientation changes</h2>
<p>One of the most common cases in which you'll be interested in orientation changes is when you want to revise the layout of your content based on the orientation of the device. For example, perhaps you want a button bar to stretch along the longest dimension of the device's display. By using a media query, you can do this easily and automatically.</p>
<h3 id="Build_the_CSS_for_each_orientation">Build the CSS for each orientation</h3>
<p>For this use case, you'll need two stylesheets:&nbsp;one to be used when the device is in portrait orientation (its height is greater than its width), and one to be used when the device is in landscape orientation (its width is greater than its height).</p>
<table class="standard-table" style="width: auto;">
  <tbody>
    <tr>
      <td class="header">Portrait</td>
      <td class="header">Landscape</td>
    </tr>
    <tr>
      <td>
        <p><code>#toolbar {<br />
          &nbsp; width: 100%;<br />
          }</code></p>
      </td>
      <td><code>#toolbar {<br />
        &nbsp; min-height: 500px;<br />
        &nbsp; width: 125px;<br />
        &nbsp; margin-right: 8px;<br />
        &nbsp; float: left;<br />
        }</code></td>
    </tr>
  </tbody>
</table>
<p>As you can see if you study the two CSS&nbsp;fragments above, when in portrait mode, we make the toolbar stretch horizontally across the top of the window, in order to maximize the horizontal space available for content. In landscape mode, the toolbar stretches vertically down the left side of the document.</p>
<h3 id="Applying_the_correct_CSS.C2.A0based_on_the_current_orientation">Applying the correct CSS&nbsp;based on the current orientation</h3>
<p>All you have to do now is establish the media queries that will automatically select the correct CSS file based on the orientation of the device. This is simple:</p>
<pre class="brush: css">
&lt;link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"&gt;
&lt;link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css"&gt;
</pre>
<p>From this point on, loading the content results in the correct layout being applied based on the device's orientation.</p>
<h2 id="Processing_orientation_events">Processing orientation events</h2>
<p>{{ gecko_minversion_header("6.0") }}</p>
<p>Firefox 6 removed the <code>MozOrientation</code> event when adding support for the <code>DeviceOrientationEvent</code> , which you can listen for in order to receive updates as the user adjusts the orientation of the device.</p>
<p>All you need to do in order to begin receiving orientation events is this:</p>
<pre class="brush: js">
window.addEventListener("deviceorientation", handleOrientation, true);
</pre>
<p>After registering your event listener (in this case, a JavaScript function called handleOrientation()), your listener function periodically gets called with updated orientation data.</p>
<p>The orientation event contains four values:</p>
<p>{{ domxref("DeviceOrientationEvent.absolute") }}</p>
<p>{{ domxref("DeviceOrientationEvent.alpha") }}</p>
<p>{{ domxref("DeviceOrientationEvent.beta") }}</p>
<p>{{ domxref("DeviceOrientationEvent.gamma") }}</p>
<p>The event handler function can look something like this:</p>
<pre class="brush: js">
function handleOrientation(orientData)&nbsp;{
&nbsp; var absolute = orientData.absolute;
&nbsp; var alpha = orientData.alpha;
&nbsp; var beta = orientData.beta;
&nbsp; var gamma = orientData.gamma;

&nbsp; // Do stuff with the new orientation data
}
</pre>
<h3 id="Accelerometer_values_explained">Accelerometer values explained</h3>
<p>The value reported for each axis indicates the amount of rotation around a given axis in reference to a standard coordinate frame.&nbsp; These are described in greater detail in the <a href="/en-US/DOM/Orientation_and_motion_data_explained" title="Orientation and motion data explained">Orientation and motion data explained</a> article which is summarized below.&nbsp;</p>
<p>The <code>DeviceOrientationEvent.alpha </code>value represents the motion of the device around the z axis, represented in degrees with values ranging from 0 to 360.</p>
<p>The <code>DeviceOrientationEvent.beta </code>value represents the motion of the device around the x axis, represented in degrees with values ranging from -180 to 180.&nbsp; This represents a front to back motion of the device.</p>
<p>The <code>DeviceOrientationEvent.gamma </code>value represents the motion of the device around the y axis, represented in degrees with values ranging from -90 to 90. This represents a left to right motion of the device.</p>
<h3 id="Browser_Compatibility">Browser Compatibility</h3>
<p>Compatibility for DeviceOrientationEvent:</p>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Chrome</th>
        <th>Firefox (Gecko)</th>
        <th>Internet Explorer</th>
        <th>Opera</th>
        <th>Safari (WebKit)</th>
      </tr>
      <tr>
        <td>
          <p>Basic support</p>
        </td>
        <td>
          <p>7.0</p>
        </td>
        <td>
          <p>3.6</p>
        </td>
        <td>{{ CompatUnknown() }}</td>
        <td>{{ CompatUnknown() }}</td>
        <td>{{ CompatUnknown() }}</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="compat-mobile">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Android</th>
        <th>Firefox Mobile (Gecko)</th>
        <th>IE Phone</th>
        <th>Opera Mobile</th>
        <th>Safari Mobile</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>
          <p>3.0</p>
        </td>
        <td>
          <p>3.6</p>
        </td>
        <td>{{ CompatNo() }}</td>
        <td>{{ CompatNo() }}</td>
        <td>
          <p>4.2</p>
        </td>
      </tr>
    </tbody>
  </table>
</div>
<p>Firefox 3.6, 4, and 5 supported <a href="/en-US/DOM/MozOrientation" title="MozOrientation">mozOrientation </a>versus the specified DeviceOrientation event</p>
<h2 id="See_also">See also</h2>
<ul>
  <li><a href="/en-US/DOM/DeviceOrientationEvent" title="DeviceOrientationEvent">DeviceOrientationEvent</a></li>
  <li><a href="/en-US/DOM/Orientation_and_motion_data_explained" title="Orientation and motion data explained">Orientation and motion data explained</a></li>
  <li><code><a href="/en-US/DOM/MozOrientation" title="en-US/DOM/MozOrientation">MozOrientation</a></code></li>
  <li><a class="external" href="http://hacks.mozilla.org/2009/06/media-queries/" title="http://hacks.mozilla.org/2009/06/media-queries/">A short introduction to media queries in Firefox 3.5</a></li>
  <li><a href="/en-US/Using_Deviceorientation_In_3D_Transforms" title="Using Deviceorientation In 3D Transforms">Using deviceorientation in 3D Transforms</a></li>
</ul>
<h3 id="Specification" name="Specification">Specification</h3>
<ul>
  <li><a class="external" href="http://www.w3.org/TR/orientation-event/" title="http://www.w3.org/TR/orientation-event/">DeviceOrientation Event Specification</a></li>
</ul>
Revert to this revision