Skip to content

Building Scalable Mobile Widgets – With Examples

July 29, 2010

This is the first in a series of posts that will attempt to address building mobile widgets that will scale properly between multiple devices. We will look at how we can deal with multiple screen resolutions, varying screen PPI (pixel per inch) densities, as well as gracefully switching between portrait and landscape modes.

This article is going to build on the concepts that were introduced in the “How to really cope with varying screen sizes and pixel resolutions in Vodafone Widgets”. Here we will actually build a sample widget that scales dynamically.

This post is going to set the stage by addressing the layout issue. Future posts will dive into more advanced topics and customizations.

The Goal

Our goal is to create a widget that will scale properly, no matter what mobile device it’s loaded on. Here are our objectives:

  • Allow for dynamic resizing when switching between portrait and landscape modes
  • Render properly on different screen sizes
  • Render properly on screen sizes with different PPI (Pixel Per Inch) densities (using CSS media queries)

It is said that a picture is worth a thousand words. Here are two mocks showing our end result in both portrait and landscape modes.

Portrait mock:

landscape mock

Landscape mock:

landscape mock

The Markup

Since this article is meant for developers, let’s just jump into the markup. Since we’re building a basic widget here, a foundation if you would, the markup is quite simple and self explanatory.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Header Footer Sample Layout Widget</title>
        <link rel="stylesheet" type="text/css" href="css/layout.css"/>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" />
    </head>
    <body>

    <div id="layout">
        <div class="header">
            <div class="header-left">
                <button class="button">home</button>
            </div>
            <div class="header-right">
                <button class="button">options</button>
            </div>
        </div>

        <div id="containerWrapper">
            <div id="container">
                Your content goes here...<br/><br/>
                And will grow vertically (with scrolling) as needed.
            </div>
        </div>

        <div class="footer">
            <div class="footer-text">
                Footer Options
            </div>
        </div>

    </div>

    </body>
</html>

The CSS

Below is the CSS we’ve used to get this layout. Notice the use of media queries to deal with various screen PPI densities.

/* resets and font sizing */
html, body{
    margin: 0;
    padding: 0;
    border: 0;
    width: 100%;
    height: 100%;
}

body {
    background-color: #FFFFFF;
    font-size: 1em;
}

@media all and (min-resolution: 50dpi) {
    body {
        font-size: 0.88em;
    }
}

/* Added Media-Query support for Low resolution Nokia (I.E N95,E65…) */
@media all and (min-resolution: 96dpi) {
    /* Here you can specify your own classes and attributes */
    body {
        font-size: 1.0em;
    }
}

@media all and (min-resolution: 145dpi) {
    body {
        font-size: 1.13em;
    }
}

/* Added Media-Query support for Medium resolution Nokia (I.E N97,Nokia 5800…) */
@media all and (min-resolution: 200dpi) {
    body {
        font-size: 1.25em;
    }
}

/* includes Nexus One (JIL reports ~240dpi vs 252 to spec) */
@media all and (min-resolution: 240dpi) {
    body {
        font-size: 1.5em;
    }
}

/* Main Layout */
#layout{
    background-color: #FFFFFF;
    color: #000000;
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
}

#container{
    padding: 1em;
    text-align: center;
    background-color: #FFFFFF;
}

#containerWrapper{
    height: 76%;
    background-color: #DDDDDD;
    overflow: auto;
}

/* Header */
.header{
    background-color: #444444;
    color: #FFFFFF;
    height: 12%;
    position: relative;
    display: table;
    width: 100%;
}

.header-left{
    height: 100%;
    margin-left: 3em;
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.header-right{
    height: 100%;
    margin-right: 3em;
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.button {
    width: 5em;
}

/* Footer */
.footer{
    background-color: #444444;
    color: #FFFFFF;
    height: 12%;
    position: absolute;
    bottom: 0;
    width: 100%;
    display: table;
}

.footer-text{
    text-align: center;
    display: table-cell;
    vertical-align: middle;
}

Notice that we have set the header and footer sections to be 12% of the total available height. We did this so that we can maintain as much space for content when switching between portrait and landscape modes. You can also define the height in pixels so that you’ll always have fixed height. The choice is yours 🙂

The Results

So what does it actually look like? We use the Ripple Mobile Environment Emulator (FREE for use while in beta) for most of our testing, so here are a couple of screen shots showing off our dynamic widget in portrait and landscape modes.

Now we must also always test on real devices. Here are a couple of screen shots of our widget loaded on different phones using the Perfecto Mobile service. Access the Perfecto Mobile service for FREE, details here in the testing section.

perfect screen shot

Resources

If you’d like to get the full source code for this widgets, we invite you to visit the open source repository.

Repo: http://github.com/tinyhippos/MobileWidgets

The sample widget: http://github.com/tinyhippos/MobileWidgets/tree/master/sampleWidgets/HeaderFooterLayout/

Stay tuned for more posts in this series where we will get into more advanced topics. We will continue to enhance this widget with features like route based navigation, using the Accelerometer, GPS, as well as explore other parts of the JIL API .

Happy coding!

Dan Silivestru – CTO at http://tinyhippos.com

Advertisements
4 Comments leave one →
  1. Barry Lennon permalink
    July 29, 2010 1:44 pm

    This is perfect for the kind of questions a newbie like me comes up with.

    It covers the basics, is well-written and is accessible.

    I commented on the recent post that asked for feedback that I thought some “beginner” help wouldn’t go amiss, and this fits the bill exactly.

    Keep up the good work, Dan!

  2. July 30, 2010 3:46 pm

    Good tutorial. The problem of diferent screen sizes and resolution is hard to manage and your css proposal is a very good approach. Nice work

  3. August 10, 2010 7:38 am

    Nice Article Dan, this is a evry good basis from where to start from :))

  4. August 23, 2010 10:22 am

    Very nice and informative. Good work.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: