Home | History | Annotate | Download | only in webapps
      1 page.title=Targeting Screens from Web Apps
      2 @jd:body
      3 
      4 <div id="qv-wrapper">
      5 <div id="qv">
      6 <h2>Quickview</h2>
      7 <ul>
      8   <li>You can target your web page for different screens using viewport metadata, CSS, and
      9 JavaScript</li>
     10   <li>Techniques in this document work for Android 2.0 and greater, and for web pages rendered
     11 in the default Android Browser and in a {@link android.webkit.WebView}</li>
     12 </ul>
     13 
     14 <h2>In this document</h2>
     15 <ol>
     16 <li><a href="#Metadata">Using Viewport Metadata</a>
     17   <ol>
     18     <li><a href="#ViewportSize">Defining the viewport size</a></li>
     19     <li><a href="#ViewportScale">Defining the viewport scale</a></li>
     20     <li><a href="#ViewportDensity">Defining the viewport target density</a></li>
     21   </ol>
     22 </li>
     23 <li><a href="#DensityCSS">Targeting Device Density with CSS</a></li>
     24 <li><a href="#DensityJS">targeting Device Density with JavaScript</a></li>
     25 </ol>
     26 
     27 </div>
     28 </div>
     29 
     30 
     31 <p>If you're developing a web application for Android or redesigning one for mobile devices, you
     32 should carefully consider how your web pages appear on different kinds of screens. Because
     33 Android is available on devices with different types of screens, you should account for some factors
     34 that affect the way your web pages appear on Android devices.</p>
     35 
     36 <p class="note"><strong>Note:</strong> The features described in this document are supported
     37 by the Android Browser application (provided with the default Android platform) and {@link
     38 android.webkit.WebView} (the framework view widget for displaying web pages), on Android 2.0 and
     39 greater. Third-party web browsers running on Android might not support these features for
     40 controlling the viewport size and screen densities.</p>
     41 
     42 <p>When targeting your web pages for Android devices, there are two fundamental factors that you
     43 should account for:</p>
     44 
     45 <dl>
     46   <dt>The size of the viewport and scale of the web page</dt>
     47     <dd>When the Android Browser loads a web page, the default behavior is to load the
     48 page in "overview mode," which provides a zoomed-out perspective of the web page. You can override
     49 this behavior for your web page by defining the default dimensions of the viewport or the initial
     50 scale of the viewport. You can also control how much the user can zoom in and out of your web
     51 page, if at all. The user can also disable overview mode in the
     52 Browser settings, so you should never assume that your page will load in overview mode. You
     53 should instead customize the viewport size and/or scale as appropriate for your page.</p>
     54     <p>However, when your page is rendered in a {@link android.webkit.WebView}, the page loads at
     55 full zoom (not in "overview mode"). That is, it appears at the default size for the page,
     56 instead of zoomed out. (This is also how the page appears if the user disables overview
     57 mode.)</p></dd>
     58 
     59   <dt>The device's screen density</dt>
     60     <dd>The screen density (the number of pixels per inch) on an Android-powered device affects
     61 the resolution and size at which a web page is displayed. (There are three screen density
     62 categories: low, medium, and high.) The Android Browser and {@link android.webkit.WebView}
     63 compensate for variations in the screen
     64 density by scaling a web page so that all devices display the web page at the same perceivable size
     65 as a medium-density screen. If graphics are an important element of your web design, you
     66 should pay close attention to the scaling that occurs on different densities, because image scaling
     67 can produce artifacts (blurring and pixelation).
     68       <p>To provide the best visual representation on all
     69 screen densities, you should control how scaling occurs by providing viewport metadata about
     70 your web page's target screen density and providing alternative graphics for different screen
     71 densities, which you can apply to different screens using CSS or JavaScript.</p></dd>
     72 </dl>
     73 
     74 <p>The rest of this document describes how you can account for these effects and provide a good
     75 design on multiple types of screens.</p>
     76 
     77 
     78 
     79 <h2 id="Metadata">Using Viewport Metadata</h2>
     80 
     81 <p>The viewport is the area in which your web page is drawn. Although the viewport's visible area
     82 matches the size of the screen,
     83 the viewport has its own dimensions that determine the number of pixels available to a web page.
     84 That is, the number of pixels available to a web page before it exceeds the screen area is
     85 defined by the dimensions of the viewport,
     86 not the dimensions of the device screen. For example, although a device screen might have a width of
     87 480 pixels, the viewport can have a width of 800 pixels, so that a web page designed to be 800
     88 pixels wide is completely visible on the screen.</p>
     89 
     90 <p>You can define properties of the viewport for your web page using the {@code "viewport"}
     91 property in an HTML {@code &lt;meta&gt;} tag (which must
     92 be placed in your document {@code &lt;head&gt;}). You can define multiple viewport properties in the
     93 {@code &lt;meta&gt;} tag's {@code content} attribute. For example, you can define the height and
     94 width of the viewport, the initial scale of the page, and the target screen density.
     95 Each viewport property in the {@code content} attribute must be separated by a comma.</p>
     96 
     97 <p>For example, the following snippet from an HTML document specifies that the viewport width
     98 should exactly match the device screen width and that the ability to zoom should be disabled:</p>
     99 
    100 <pre>
    101 &lt;head&gt;
    102     &lt;title&gt;Example&lt;/title&gt;
    103     &lt;meta name="viewport" content="width=device-width, user-scalable=no" /&gt;
    104 &lt;/head&gt;
    105 </pre>
    106 
    107 <p>That's an example of just two viewport properties. The following syntax shows all of the
    108 supported viewport properties and the general types of values accepted by each one:</p>
    109 
    110 <pre>
    111 &lt;meta name="viewport"
    112       content="
    113           <b>height</b> = [<em>pixel_value</em> | device-height] ,
    114           <b>width</b> = [<em>pixel_value</em> | device-width ] ,
    115           <b>initial-scale</b> = <em>float_value</em> ,
    116           <b>minimum-scale</b> = <em>float_value</em> ,
    117           <b>maximum-scale</b> = <em>float_value</em> ,
    118           <b>user-scalable</b> = [yes | no] ,
    119           <b>target-densitydpi</b> = [<em>dpi_value</em> | device-dpi |
    120                                high-dpi | medium-dpi | low-dpi]
    121           " /&gt;
    122 </pre>
    123 
    124 <p>The following sections discuss how to use each of these viewport properties and exactly what the
    125 accepted values are.</p>
    126 
    127 <div class="figure" style="width:300px">
    128   <img src="{@docRoot}images/webapps/compare-default.png" alt="" height="300" />
    129   <p class="img-caption"><strong>Figure 1.</strong> A web page with an image that's 320 pixels
    130 wide, in the Android Browser when there is no viewport metadata set (with "overview mode"
    131 enabled, the viewport is 800 pixels wide, by default).</p>
    132 </div>
    133 
    134 
    135 <div class="figure" style="width:300px">
    136   <img src="{@docRoot}images/webapps/compare-width400.png" alt="" height="300" />
    137   <p class="img-caption"><strong>Figure 2.</strong> A web page with viewport {@code width=400} and
    138 "overview mode" enabled (the image in the web page is 320 pixels wide).</p>
    139 </div>
    140 
    141 
    142 <h3 id="ViewportSize">Defining the viewport size</h3>
    143 
    144 <p>Viewport's {@code height} and {@code width} properties allow you to specify the size of the
    145 viewport (the number of pixels available to the web page before it goes off screen).</p>
    146 
    147 <p>As mentioned in the introduction above, the Android Browser loads pages in "overview mode" by
    148 default (unless disable by the user), which sets the minimum viewport width to 800 pixels. So, if
    149 your web page specifies its size to be 320 pixels wide, then your page appears smaller than the
    150 visible screen (even if the physical screen is 320 pixels wide, because the viewport simulates a
    151 drawable area that's 800 pixels wide), as shown in figure 1. To avoid this effect, you should
    152 explicitly define the viewport {@code width} to match the width for which you have designed your web
    153 page.</p>
    154 
    155 <p>For example, if your web page is designed to be exactly 320 pixels wide, then you might
    156 want to specify that size for the viewport width:</p>
    157 
    158 <pre>
    159 &lt;meta name="viewport" content="width=320" /&gt;
    160 </pre>
    161 
    162 <p>In this case, your web page exactly fits the screen width, because the web page width and
    163 viewport width are the same.</p>
    164 
    165 <p class="note"><strong>Note:</strong> Width values that are greater than 10,000 are ignored and
    166 values less than (or equal to) 320 result in a value equal to the device-width (discussed below).
    167 Height values that are greater then 10,000 or less than 200 are also ignored.</p>
    168 
    169 <p>To demonstrate how this property affects the size of
    170 your web page, figure 2 shows a web page that contains an image that's 320 pixels
    171 wide, but with the viewport width set to 400.</p>
    172 
    173 
    174 <p class="note"><strong>Note:</strong> If you set the viewport width to match your web page width
    175 and the device's screen width does <em>not</em> match those dimensions, then the web page
    176 still fits the screen even if the device has a high or low-density screen, because the
    177 Android Browser and {@link android.webkit.WebView} scale web pages to match the perceived size on a
    178 medium-density screen, by default (as you can see in figure 2, when comparing the hdpi device to the
    179 mdpi device). Screen densities are discussed more in <a href="#ViewportDensity">Defining the
    180 viewport target density</a>.</p>
    181 
    182 
    183 <h4>Automatic sizing</h4>
    184 
    185 <p>As an alternative to specifying the viewport dimensions with exact pixels, you can set the
    186 viewport size to always match the dimensions of the device screen, by defining the
    187 viewport properties {@code height}
    188 and {@code width} with the values {@code device-height} and {@code device-width}, respectively. This
    189 is appropriate when you're developing a web application that has a fluid width (not fixed width),
    190 but you want it to appear as if it's fixed (to perfectly fit every screen as
    191 if the web page width is set to match each screen). For example:</p>
    192 
    193 <pre>
    194 &lt;meta name="viewport" content="width=device-width" /&gt;
    195 </pre>
    196 
    197 <p>This results in the viewport width matching whatever the current screen width is, as shown in
    198 figure 3. It's important to notice that, this results in images being scaled to fit the screen
    199 when the current device does not match the <a href="#ViewportDensity">target
    200 density</a>, which is medium-density if you don't specify otherwise. As a result, the image
    201 displayed on the high-density device in figure 3 is scaled up in order to match the width
    202 of a screen with a medium-density screen.</p>
    203 
    204 <div class="figure" style="width:300px">
    205   <img src="{@docRoot}images/webapps/compare-initialscale.png" alt="" height="300" />
    206   <p class="img-caption"><strong>Figure 3.</strong> A web page with viewport {@code
    207 width=device-width} <em>or</em> {@code initial-scale=1.0}.</p>
    208 </div>
    209 
    210 <p class="note"><strong>Note:</strong> If you instead want {@code
    211 device-width} and {@code device-height} to match the physical screen pixels for every device,
    212 instead of scaling your web page to match the target density, then you must also include
    213 the {@code target-densitydpi} property with a value of {@code device-dpi}. This is discussed more in
    214 the section about <a href="#ViewportDensity">Defining the viewport density</a>. Otherwise, simply
    215 using {@code device-height} and {@code device-width} to define the viewport size makes your web page
    216 fit every device screen, but scaling occurs on your images in order to adjust for different screen
    217 densities.</p>
    218 
    219 
    220 
    221 <h3 id="ViewportScale">Defining the viewport scale</h3>
    222 
    223 <p>The scale of the viewport defines the level of zoom applied to the web page. Viewport
    224 properties allow you to specify the scale of your web page in the following ways:</p>
    225 <dl>
    226   <dt>{@code initial-scale}</dt>
    227   <dd>The initial scale of the page. The value is a float that indicates a multiplier for your web
    228 page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the
    229 web page is displayed to match the resolution of the <a href="#ViewportDensity">target
    230 density</a> 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2.
    231     <p>The default initial scale is calculated to fit the web page in the viewport size.
    232 Because the default viewport width is 800 pixels, if the device screen resolution is less than
    233 800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the
    234 800-pixel-wide page on the screen.</p></dd>
    235 
    236   <dt>{@code minimum-scale}</dt>
    237   <dd>The minimum scale to allow. The value is a float that indicates the minimum multiplier for
    238 your web page size, relative to the screen size. For example, if you set this to "1.0", then the
    239 page can't zoom out because the minimum size is 1-to-1 with the <a href="#ViewportDensity">target
    240 density</a>.</dd>
    241 
    242   <dt>{@code maximum-scale}</dt>
    243   <dd>The maximum scale to allow for the page. The value is a float that indicates the
    244 maximum multiplier for your web page size,
    245 relative to the screen size. For example, if you set this to "2.0", then the page can't
    246 zoom in more than 2 times the target size.</dd>
    247 
    248   <dt>{@code user-scalable}</dt>
    249   <dd>Whether the user can change the scale of the page at all (zoom in and out). Set to {@code yes}
    250 to allow scaling and {@code no} to disallow scaling. The default is {@code yes}. If you set
    251 this to {@code no}, then the {@code minimum-scale} and {@code maximum-scale} are ignored,
    252 because scaling is not possible.</dd>
    253 </dl>
    254 
    255 <p>All scale values must be within the range 0.01&ndash;10.</p>
    256 
    257 <p>For example:</p>
    258 
    259 <pre>
    260 &lt;meta name="viewport" content="initial-scale=1.0" /&gt;
    261 </pre>
    262 
    263 <p>This metadata sets the initial scale to be full sized, relative to the viewport's target
    264 density.</p>
    265 
    266 
    267 
    268 
    269 <h3 id="ViewportDensity">Defining the viewport target density</h3>
    270 
    271 <p>The density of a device's screen is based on the screen resolution, as defined by the number of
    272 dots per inch (dpi). There are three screen
    273 density categories supported by Android: low (ldpi), medium (mdpi), and high (mdpi). A screen
    274 with low density has fewer available pixels per inch, whereas a screen with high density has more
    275 pixels per inch (compared to a medium density screen). The Android Browser and {@link
    276 android.webkit.WebView} target a medium density screen by default.</p>
    277 
    278 
    279 <div class="figure" style="width:300px">
    280   <img src="{@docRoot}images/webapps/compare-initialscale-devicedpi.png" alt="" height="300" />
    281   <p class="img-caption"><strong>Figure 4.</strong> A web page with viewport {@code
    282 width=device-width} and {@code target-densitydpi=device-dpi}.</p>
    283 </div>
    284 
    285 
    286 <p>Because the default target density is medium, when users have a device with a low or high density
    287 screen, the Android Browser and {@link android.webkit.WebView} scale web pages (effectively zoom
    288 the pages) so they display at a
    289 size that matches the perceived appearance on a medium density screen. More specifically, the
    290 Android Browser and {@link android.webkit.WebView} apply approximately 1.5x scaling to web pages
    291 on a high density screen (because its screen pixels are smaller) and approximately 0.75x scaling to
    292 pages on a low density screen (because its screen pixels are bigger).</p>
    293 
    294 <p>Due to this default scaling, figures 1, 2, and 3 show the example web page at the same physical
    295 size on both the high and medium density device (the high-density device shows the
    296 web page with a default scale factor that is 1.5 times larger than the actual pixel resolution, to
    297 match the target density). This can introduce some undesirable artifacts in your images.
    298 For example, although an image appears the same size on a medium and high-density device, the image
    299 on the high-density device appears more blurry, because the image is designed to be 320 pixels
    300 wide, but is drawn with 480 pixels.</p>
    301 
    302 <p>You can change the target screen density for your web page using the {@code target-densitydpi}
    303 viewport property. It accepts the following values:</p>
    304 
    305 <ul>
    306 <li><code>device-dpi</code> - Use the device's native dpi as the target dpi. Default scaling never
    307 occurs.</li>
    308 <li><code>high-dpi</code> - Use hdpi as the target dpi. Medium and low density screens scale down
    309 as appropriate.</li>
    310 <li><code>medium-dpi</code> - Use mdpi as the target dpi. High density screens scale up and low
    311 density screens scale down. This is the default target density.</li>
    312 <li><code>low-dpi</code> - Use ldpi as the target dpi. Medium and high density screens scale up
    313 as appropriate.</li>
    314 <li><em><code>&lt;value&gt;</code></em> - Specify a dpi value to use as the target dpi. Values must
    315 be within the range 70&ndash;400.</li>
    316 </ul></p>
    317 
    318 <p>For example, to prevent the Android Browser and {@link android.webkit.WebView} from scaling
    319 your web page for different screen densities, set
    320 the {@code target-densitydpi} viewport property to {@code device-dpi}. When you do, the page is
    321 not scaled. Instead, the page is displayed at a size that matches the current screen's
    322 density. In this case, you should also define the viewport width to match the device width, so your
    323 web page naturally fits the screen size. For example:</p>
    324 
    325 <pre>
    326 &lt;meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /&gt;
    327 </pre>
    328 
    329 <p>Figure 4 shows a web page using these viewport settings&mdash;the high-density device
    330 now displays the page smaller because its physical pixels are smaller than those on the
    331 medium-density device, so no scaling occurs and the 320-pixel-wide image is drawn using exactly 320
    332 pixels on both screens. (This is how you should define your viewport if
    333 you want to customize your web page based on screen density and provide different image assets for
    334 different densities, <a href="#DensityCSS">with CSS</a> or
    335 <a href="#DensityJS">with JavaScript</a>.)</p>
    336 
    337 
    338 <h2 id="DensityCSS">Targeting Device Density with CSS</h2>
    339 
    340 <p>The Android Browser and {@link android.webkit.WebView} support a CSS media feature that allows
    341 you to create styles for specific
    342 screen densities&mdash;the <code>-webkit-device-pixel-ratio</code> CSS media feature. The
    343 value you apply to this feature should be either
    344 "0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium density,
    345 or high density screens, respectively.</p>
    346 
    347 <p>For example, you can create separate stylesheets for each density:</p>
    348 
    349 <pre>
    350 &lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" /&gt;
    351 &lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" /&gt;
    352 &lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" /&gt;
    353 </pre>
    354 
    355 
    356 <div class="figure" style="width:300px">
    357   <img src="{@docRoot}images/webapps/compare-width-devicedpi-css.png" alt="" height="300" />
    358   <p class="img-caption"><strong>Figure 5.</strong> A web page with CSS that's targetted to
    359 specific screen densities using the {@code -webkit-device-pixel-ratio} media feature. Notice
    360 that the hdpi device shows a different image that's applied in CSS.</p>
    361 </div>
    362 
    363 <p>Or, specify the different styles in one stylesheet:</p>
    364 
    365 <pre class="no-pretty-print">
    366 #header {
    367     background:url(medium-density-image.png);
    368 }
    369 
    370 &#64;media screen and (-webkit-device-pixel-ratio: 1.5) {
    371     /* CSS for high-density screens */
    372     #header {
    373         background:url(high-density-image.png);
    374     }
    375 }
    376 
    377 &#64;media screen and (-webkit-device-pixel-ratio: 0.75) {
    378     /* CSS for low-density screens */
    379     #header {
    380         background:url(low-density-image.png);
    381     }
    382 }
    383 </pre>
    384 
    385 <p class="note"><strong>Note:</strong> The default style for {@code #header} applies the image
    386 designed for medium-density devices in order to support devices running a version of Android less
    387 than 2.0, which do not support the {@code -webkit-device-pixel-ratio} media feature.</p>
    388 
    389 <p>The types of styles you might want to adjust based on the screen density depend on how you've
    390 defined your viewport properties. To provide fully-customized styles that tailor your web page for
    391 each of the supported densities, you should set your viewport properties so the viewport width and
    392 density match the device. That is:</p>
    393 
    394 <pre>
    395 &lt;meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /&gt;
    396 </pre>
    397 
    398 <p>This way, the Android Browser and {@link android.webkit.WebView} do not perform scaling on your
    399 web page and the viewport width
    400 matches the screen width exactly. On their own, these viewport properties create results shown in
    401 figure 4. However, by adding some custom CSS using the {@code -webkit-device-pixel-ratio} media
    402 feature, you can apply different styles. For example, figure 5 shows a web page with these viewport
    403 properties and also some CSS added that applies a high-resolution image for high-density
    404 screens.</p>
    405 
    406 
    407 
    408 <h2 id="DensityJS">Targeting Device Density with JavaScript</h2>
    409 
    410 <p>The Android Browser and {@link android.webkit.WebView} support a DOM property that allows you to
    411 query the density of the current
    412 device&mdash;the <code>window.devicePixelRatio</code> DOM property. The value of this property
    413 specifies the scaling factor used for the current device. For example, if the value
    414 of <code>window.devicePixelRatio</code> is "1.0", then the device is considered a medium density
    415 device and no scaling is applied by default; if the value is "1.5", then the device is
    416 considered a high density device and the page is scaled 1.5x by default; if the value
    417 is "0.75", then the device is considered a low density device and the page is scaled
    418 0.75x by default. Of course, the scaling that the Android Browser and {@link android.webkit.WebView}
    419 apply is based on the web page's
    420 target density&mdash;as described in the section about <a href="#ViewportDensity">Defining the
    421 viewport target density</a>, the default target is medium-density, but you can change the
    422 target to affect how your web page is scaled for different screen densities.</p>
    423 
    424 <p>For example, here's how you can query the device density with JavaScript:</p>
    425 
    426 <pre>
    427 if (window.devicePixelRatio == 1.5) {
    428   alert("This is a high-density screen");
    429 } else if (window.devicePixelRatio == 0.75) {
    430   alert("This is a low-density screen");
    431 }
    432 </pre>
    433 
    434 
    435 
    436 
    437 
    438 
    439 
    440