Zoom-on-rotate fix for WebKit mobile browsers (Mobilizing websites with responsive design and HTML5 part 8)

This blog post is a part of Mobilizing websites with responsive design and HTML5 tutorial. For all posts please see the Introduction post.

After adding meta viewport tag for your mobile site its width is properly formatted for mobile browsers. However, there exists a common glitch you should be aware of.

On iOS devices, and on some Android devices, the mobile browser re-zooms the web page when the device orientation changes. The browser applies heuristics and try to determine a new zoom level after the rotation, but sometimes the result is not desirable. When you rotate from the portrait mode to the landscape mode, the page zooms in too much.

In our case, the project client specifically requested to disable this little feature if possible, as it was irritating the test users on iPad devices.

This can be worked around by resetting the viewport with Javascript after the orientation changes.

An example code going into HTML <head> section:

  <!--

    Don't break scale on iPad rotate.

    By default iPad re-zooms the page when the device orientation changes.
    The heuristics here do not work always; our page got zoomed in
    though it should be max zoomed out.

    This snippet fixes the situation so that you can still zoom in, but when
    the device is rotated the scale is restored.

   -->
<script type="text/javascript">
(function(doc) {

    var addEvent = 'addEventListener',
        type = 'gesturestart',
        qsa = 'querySelectorAll',
        scales = [1, 1],
        meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : [];

    function fix() {
        meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1];
        doc.removeEventListener(type, fix, true);
    }

    if ((meta = meta[meta.length - 1]) && addEvent in doc) {
        fix();
        scales = [.25, 1.6];
        doc[addEvent](type, fix, true);
    }

}(document));
</script>

Please edit the scales part of the code for the desired min and max scaling level.

Note: Dynamic viewport manipulation is badly supported on older Android devices and contains many pitfalls.

1. More info

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

Resizing images in responsive mobile design (Mobilizing websites with responsive design and HTML5 part 6)

This blog post is a part of Mobilizing websites with responsive design and HTML5 tutorial. For all posts please see the Introduction post.

When you change your layout dynamically you need to re-fit media elements to match the new layout dimensions. There exist three basic techniques dealing with images in responsive designs

  • Resizing images using CSS only  – in this case the clients download the full image payload regardless of the image size and image visible sizes are adjusted using CSS styles
  • Co-operative image resizer on the front end web server: when HTML is written from a template the image tags are written in such a way that <img src> attribute points to a resized image. The resizer rewrites image to match the vrowser screen dimensions. This is done e.g. in Web and Mobile for Plone CMS.
  • Independent image resizer on the front end web server: Javascript + server-side stub component is used to resize the images. The server-side component does not depend on the rest of the front-end server system, thus making the front end code less complex. A client-side Javascript scans HTML DOM tree for <img> tags and rewrites <img src> to go through the resizer. For example Adaptive Images (below) is this kind of a solution. Alternatively, an independent image resizer can be a part of the middleware stack (e.g. WSGI in Python)

In this blog post we mostly discuss about the simplest approach: resizing images using CSS only.

1. Resizing images using pure CSS

If your responsive layout includes images, as contentish or style elements, they might not work well with small screens as is. You can fix the situation by resizing the images dynamically with CSS.

In our example case the page has only one image: the site logo. If viewed in a mobile browser using desktop CSS the logo might be too small or too large. Thus

  • We remove any hard-coded width and height values for the <img> in HTML
  • We apply CSS style for the image width where the image takes width from the screen width as percents, but still has max-width set in pixels so that tablet devices with more screen estate don’t scale the image too much

Related CSS:

/* Logo must not appear too large on mobile */
#portal-logo img {
   width: 33%;
   max-width: 180px;
}

Before fix:

Image

After fix:

Image

2. Server-side image resizing solutions

You can also resize images dynamically on the server-side, so that mobile browsers load the reduced size version, saving the precious mobile bandwidth. However, this adds additional server-side component to the mix, increasing the complexity of the solution and especially when dealing with legacy sites consider whether the improved user experience is enough to balance this trade-off.

Also, the dynamic image resizer component is easily subject to denial of service attack because the HTTP responses it serve are usually slow and computationally intensive. If you decide to use one of these components be sure you are aware of these implications.

You don’t need to change the server-side generated HTML to achieve the dynamic images sizes. There exist a technology neutral solutions relying on the client-side Javascript and additional serve-side proxy component.

Adaptive Images is one of server-side image resizing solutions based on Javascript and minimal server-side PHP script. It operates in independent manner and adheres the contemporary best practices of HTML5 and responsive web designs.

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

Mobile site CSS with CSS3 media queries (Mobilizing websites with responsive design and HTML5 part 5)

This blog post is a part of Mobilizing websites with responsive design and HTML5 tutorial. For all posts please see the Introduction post.

To mobilize the legacy website, we create a responsive design with two layout steps: desktop and mobile. We use a separate mobile.css stylesheet which will override legacy desktop styles for mobile browsers with more suitable variations for small screens.

CSS3 Media queries are a method of selectively loading CSS stylesheets based on various criteria like screen size and orientation. They are supported by all state-of-the-art mobile and desktop browsers.

mobile.css stylesheet

  • is loaded for mobile devices only using CSS3 media queries
  • when developing, we force the file to be loaded on our development browser (Firefox + Firebug) simply by removing the media query condition in the stylesheet HTML tag

1. Defining the media query to discriminate mobile devices

The media query uses simple screen pixel count to determine whether the screen is “small” or not. Though CSS3 has rapidly advanced, it still cannot answer the basic question “what is the diameter of the screen in physical inches”, the only information which we would be interested in. Thus, some heuristics are required to guess whether the screen is actually small or not… hopefully we’ll see some kind of pixel size + DPI or diameter in inches selectors in the future CSS media queries to make hacks unnecessary.

Note: In the case related to this tutorial, the client wanted the tablet browsers to receive mobile styling also. This improved touch screen accessibility, though the tablet browsers usually work well with desktop layouts too.

Note: Media queries determine the screen width by the device orientation and you can have different CSS loaded depending whether the device is in portrait or landscape orientation mode.

Note: Browsers report their screen width in heterogeneous manner. Whether reported widths are the virtual screen width in virtual pixels or the real pixel width may vary browser by browser. See notes below.

Note: WebKit has a WebKit specific media query selector called -webkit-device-pixel-ratio which tells ratio between physical and virtual pixels. It is designed to discriminate high DPI mobile screens, which are wider than 640 pixels but still in small form factor.

CSS3 media query linking code for loading the mobile.css stylesheet in HTML <head>:

   <!--
     Detect mobile devices + iPad.

     High DPI smart phones report "virtual" pixels here which is usually 1/2 x normal pixels.
     E.g. iPhone 4 with 960 px wide screen reports 480 pixels.
     We use 500 px as the threshold.

     We cut out devices at 900 pixels wide, so 1024 px desktop screens are not included.

   -->

   <link rel="stylesheet" media="screen and (max-device-width: 900px)" href="css/mobile.css" />

   <!--

     This is for Android.

     Android Browser HPDI screens uses actual pixels max-device-width and
     they are indistinguishable from iPad. The screen can have max-device-width=768
     which is also the value for tablets.

     Here we simply use WebKit HDPI screen "virtual pixel" aspect ratio detector
     to see if we are using virtual pixels. If we are then assume a mobile screen.

   -->

   <link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="css/mobile.css" />

To test the mobile styles in a deskto browser simply remove media condition from <link> code.

The project page before mobile CSS was applied:

Image

The page after mobile CSS has been applied:

Image

Much better!

Note: Older mobile browsers might not support CSS3 media queries. They will simply fallback to the desktop version of the site CSS, no harm done.

Resetting desktop styles

The most important task for the mobile.css to do is to reset the website width and main content wrapping from the hardcoded centered column to something spreading across the whole mobile screen width.

Here are some example styles we applied in mobile.css to drop hardcoded width values and adjust margins to more suitable values. As you can see we use !important CSS directive to override many desktop styles – if your site is using several CSS files or complex style hierarchies this switch might be needed to make sure styles are overridden properly.

/* Disable background image */
body {
    background: white !important;
}

/* Fill entire mobile viewport width - don't force hard pixel widths*/
#visual-portal-wrapper {
    width: 100% !important; /* Was width: 960px */
    margin: 0;
}

#main-margin {
     margin: 0;
}

/* Mobile footer cannot be fixed height as it may layout as many rows
   instead of one */
#footer2 {
    width: 100% !important;
    margin: 0;
    padding: 0;
    height: auto; /* Was 60px */
}

/* Fix footer margins */
#footer-wrapper {
    padding: 10px 20px 0 20px;
}

/* Make two footer elements reactive and lay from top to bottom on too narrow screen */
#footer-wrapper > div {
   display: block;
   float; left;
}

#footer-wrapper > a {
   width: 120px;
}

2. More information

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

Mobilizing websites with responsive design and HTML5 tutorial

This is a blog post series tutorial for adapting your existing websites for mobile devices without building a separate mobile site. It shows, with examples, how with little changes in your HTML, CSS and Javascript code you can deliver much nicer user experience for small screen and mobile devices. You can make existing HTML designs more mobile friendly with selective CSS loading and HTML5 tags. Selective CSS loading with CSS3 media queries allow you to change layout depending on the browser screen size: this kind of layout is called responsive design.

The tutorial is divided to several, functionality specific, blog posts, each with screenshot examples, explanations and links for more in-depth information.

The tutorial was written in a conjunction with a consulting project for a Finnish public sector organization. As the one of the funding sources is Finnish tax money, including some of my very own pennies, it was a common interest to get the information born in the consultation project published.

Below is an example what one can accomplish.

The site landing page before any mobilization was done; the site is using the default desktop styles on mobile devices:

Image

The site after HTML and CSS adjustments:

Image

1. Prerequisites

Prerequisites for understanding this tutorial are

2. Table of contents

The tutorial contents is outlined below. I’ll keep linking to new blog posts as I finish writing them. Stay tuned, by following the RSS feed or Twitter.

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+