Advertisement
Javascript

Responsive Design, Retina Images and Debugging for Google Maps API

by

This final part of the Google Maps API For Designers series rounds things up by looking at responsive design, retina images and a range of testing and debugging tools which make life a lot easier.  It gives a whistle-stop tour through a whole range of areas, which you can explore further in your own projects.


Responsive Design and Media Queries

Home page. Left - mobile style. Right - laptop/desktop/tablet style.

Responsive home page. Left - mobile style. Right - laptop/desktop/tablet style.

Unless you've been snoozing under a bush for the past few years, you’ll know that responsive design is all about making a website change and adapt according to the device it's viewed on.

The home page of this demo (above) also uses responsive design to present people with an altered version of the map depending on the device, or more specifically screen width, they are using.

The first step before we do anything else is to make sure the viewport meta tag is set in the head of your page.

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

Note: Precisely which viewport attributes you use to set things up is up to you. Read our guide for more details.

The popular approach to dealing with responsive design that we’ll use here is to apply media queries within the CSS.  Media queries are a way of segmenting up the CSS and applying different styles depending on, for example, the width of the viewport the website is being viewed on.

The code listing below is quite long, but it’s useful to see what’s going on. To see this code in action, take a look at the home page. If you are viewing it on a larger screen, drag the side of the browser to make it narrower. When your browser's width reaches below 640px, the design should change.

<!--Setting up the CSS styles-->
<style type="text/css">

html {
 height: 100%;
 }

 #gears{
 width:50%;
 }

 img {
 border:none;
 }

body {
 height: 100%;
 margin: 0px;
 padding: 0px;
 background: none;
 }

 #overall_wrapper {
 height: 100%;
 width: 100%;
 margin:0px;
 padding:0px;
 border:none;
 background:none;
 }

 #title_box{
 width: 100%;
 background-color:#89cbed;
 text-align:center;
 margin:0px;
 padding-top:5px;
 padding-bottom:10px;
 border:none;
 }

 #yellow_line_and_arrow{
 display:none;
 }

 #button_to_map_standard{
 width: 100%;
 background: none;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top: 2px;
 margin-bottom: 5px;
 padding: 0px;
 display:none;
 }

 #button_to_map_mobile {
 width: 95%;
 background: none;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top: 10px;
 margin-bottom: 10px;
 padding: 0px;
 display:block;
 }

 #blurb_about_demo_wrapper{
 width: 100%;
 background: #09F;
 margin:0px;
 padding:0px;
 border:none;
 }

 #blurb_about_demo_content{
 width: 80%;
 margin-left:auto;
 margin-right:auto;
 margin-top:5px;
 padding-top:5px;
 font-family:Tahoma, Geneva, sans-serif;
 font-size: 1.8em;
 line-height: 2em;
 text-align:center;
 color:#ffffff;
 }

 #footer_box_wrapper{
 width: 100%;
 background-color:#89cbed;
 text-align:center;
 margin:0px;
 padding:0px;
 border:none;
 border-top-width:2px;
 border-top-style:solid;
 border-top-color:#ffffff;
 }

 #footer_box_content{
 width: 80%;
 margin-left:auto;
 margin-right:auto;
 font-family:Tahoma, Geneva, sans-serif;
 font-size: 1.1em;
 line-height: 1.4em;
 color:#ffffff;
 }

/*The media query. This CSS overwrites the corosponding elements (above) when the screen is over 641px in width. */
@media (min-width: 641px) {

 body {
 height: 100%;
 margin: 0px;
 padding: 0px;
 background-image: url('background9.jpg');
 background-color: #B3CDE6;
 background-repeat: no-repeat;
 background-attachment: fixed;
 background-position: right bottom;
 background-size: cover;
 }

 #overall_wrapper {

 height: 100%;
 width: 40%;
 margin-left: auto;
 margin-right: auto;
 margin-top:0px;
 margin-bottom:0px;
 padding-left: 5%;
 padding-right: 5%;
 padding-top: 2%;
 padding-bottom: 2%;
 border-right-width: 2px;
 }

 #title_box{
 width: 400px;
 background-color:#89cbed;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-bottom:2px;
 padding-top:10px;
 padding-bottom:10px;
 border-top-left-radius:20px;
 border-top-right-radius:20px;
 border-bottom-left-radius:0px;
 border-bottom-right-radius:0px;
 }

 #yellow_line_and_arrow{
 width: 400px;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top:2px;
 display:block;
 }

 #button_to_map_standard{
 width: 95%;
 background: none;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top: 2px;
 margin-bottom: 5px;
 padding: 0px;
 display:block;
 }

 #button_to_map_mobile {
 width: 95%;
 background: none;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top: 2px;
 margin-bottom: 5px;
 padding: 0px;
 display:none;
 }

 #blurb_about_demo_wrapper{
 width: 95%;
 background:#ffffff;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top: 10px;
 margin-bottom: 0px;
 padding-top:5px;
 padding-left:5px;
 padding-right:5px;
 padding-bottom:15px;
 border-top-left-radius:20px;
 border-top-right-radius:20px;
 border-bottom-left-radius:0px;
 border-bottom-right-radius:0px;
 }

 #blurb_about_demo_content{
 font-family:Tahoma, Geneva, sans-serif;
 font-size: 1.4em;
 line-height: 1.6em;
 color:#09C;
 }

 #footer_box_wrapper{
 width: 95%;
 background-color:#89cbed;
 text-align:center;
 margin-left:auto;
 margin-right:auto;
 margin-top:0px;
 margin-bottom:30px;
 padding-left: 5px;
 padding-right: 5px;
 padding-top: 1px;
 padding-bottom: 2px;
 border-radius: 20px;
 border-top-left-radius:0px;
 border-top-right-radius:0px;
 border-bottom-left-radius:20px;
 border-bottom-right-radius:20px;
 border-width:0px;
 }

 #footer_box_content{
 font-family:Tahoma, Geneva, sans-serif;
 font-size: 0.9em;
 line-height: 1.3em;
 color:#ffffff;
 }
}

</style>

The media query in this case is the @media (min-width: 641px) code at line 101, and the subsequent CSS within the curly brackets. This media query is checking for the device width.

Mobile First Design

It's good to use a mobile first approach; this is the idea that the default style is aimed at mobile devices, and then exceptions are progressively added using media queries as viewports get bigger.  This approach helps websites load faster on mobile devices. For example, things like the big background image we've used are only loaded for bigger screen devices.

So in the code above, the first part of the code (i.e. above the media query - @media (min-width: 641px) ) will load by default on every device. Then the @media (min-width: 641px) media query loads the styles within the curly brackets for devices whose width is over 641px wide.

Breakpoints

A common question is:

where should the breakpoints in the design be?

The breakpoint in this example is 641px.  This demo only uses one breakpoint, but often you’d want more than one.  This can depend very much on your content, and also on the range of devices you are targeting and the popular screen resolutions on the market.

In this example, the iPhone (width is 640px) will display the default mobile style, whereas the iPad2 (width is 768) will display the desktop version.  Our chosen breakpoint is appropriate for this map, because the graphics are too large for the phone. However, other more text-based websites may find that it's only when you get down to much smaller screen sizes that the style needs to be changed significantly, and so the breakpoints may be lower.

Note: When choosing breakpoints it's often wisest to simply consider the design, observing where it breaks, rather than aiming for specific device resolutions. Screen sizes are so wide and varied, plus they change as time goes on, that there's simply no way of accurately keeping track of them.

Directing Users to the Different Map Versions

It's sometimes appropriate to present users with entirely different versions of content, depending on their viewing circumstances.

In our case, this is done using two div tags (i.e. button_to_map_mobile and button_to_map_standard), each containing a different link and a slightly different green 'visit map' button.  If you are on a laptop or desktop computer, view the home page and drag the side of your browser in until the design changes to the mobile layout. You should notice that the green 'visit map' button changes slightly to include the word ‘mobile’. If you click this button now, you’ll get a mobile version of the map.

The media query is used to alternate which div is currently visible. I.e. if you take a look at the code listing above, you can see that the  button_to_map_standard has the display:none; applied to it when the default mobile style is in use, but when the media query detects the screen is over 641 pixels wide it applies the display:block; to button_to_map_standard. (The media query does the reverse to the button_to_map_mobile div).

If you are following this tutorial making your own web page, take a good look at the source code available from the link at the top of this page. I personally found it easier to get something working initially using the ‘mobile first’ approach and one breakpoint, before expanding it out to a more complex design.

It's worth noting that the choice between alternative content and responsive content is something which you should give real consideration to, when developing websites for multiple devices.


Retina images

Hopefully you've just taken a glimpse at the new mobile version of the map.  We’ll come back to that in just a minute. But first, it’s worth taking a look at how the home page uses images designed for retina screens.

Retina (and other hi-pixel density) screens have so many pixels, so close together, that it’s near impossible for the retina in a human eye to distinguish individual pixels. Retina screens are considered to be the next generation of screens, and an increasing number of devices have them already, such as the iPhones 4 and 5 and some high-spec MacBook Pros.  However, the downside is that graphics which are not prepared with these screens in mind will actually look a little blurry.

Fortunately there are a few ways around this. The approach you go for will depend on the nature of the image itself. This demo uses two approaches; retina.js library and SVG graphics.

Retina.js

Retina.js is a lightweight JavaScript library, which is free to download. You just need to save the JavaScript file adjacent to your website on your server, and add the following line of code just before the closing body tag.

<script type="text/javascript" src="/scripts/retina.js"></script>

You then save two versions of every image;  one twice the size you’d view the image at on a standard screen, and the other at the normal size. The trick to getting this library working is that you need to save your images in the same folder on your server and follow the strict naming convention -

  • emilysypic.jpg = normal resolution version
  • emilyspic@2x.jpg = high resolution version

You then add your image to your page markup as usual, just adding the standard resolution version -

<img src="/images/my_image.png" />

When someone views your website on a retina display, the presence of the retina.js script tells your website to check whether there's a high resolution version available.

Although retina.js has the limitation of the time it takes to save two versions for every image, it can be very useful for photographic or none-vector type images.

The green ‘visit map’ button in the homepage uses the retina.js plugin. To see this in action, try viewing the site on a retina device, e.g. iPhone 4 or 5, and look at how crisp the text on the green button is. If you've downloaded your own copy of the code, remove the retina.js plugin and view the website on the retina device again. You should notice that the quality of the button (e.g. the white lines within the text) is poorer.

I'd recommend using retina.js for key photographic or none-vector type images that do not change often, on your homepage, or built into your template. However, if, for example, you are running a blog with multiple authors, it’s probably unrealistic to expect them to create two versions for every image.

SVGs

Another approach to creating crisp graphics for retina screens is to use SVG images. SVG actually stands for Scalable Vector Graphics. As their name suggests, SVG images are suitable for vector type images (i.e. not photos!)

As vector graphics are enlarged they retain their crispness.

As vector graphics are enlarged, they retain their crispness.

To see an example, take a look at the homepage. The gears and spanner icon is an SVG graphic. Its width is set to 50%. As you resize your browser you should be able to see that it always stays perfectly crisp. It also stays perfectly crisp if you zoom your browser (e.g. on a phone).

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
 <circle cx="100" cy="100" r="90" stroke="red" stroke-width="9" fill="yellow" />
 </svg>

SVG graphics are actually an XML based vector format. This means you can edit them directly, if you wish, using a basic text editor. The code above creates a picture of the yellow circle below.

Simple SVG demo (screetshot).

Simple SVG demo (screenshot).

You can insert SVG images into your web pages in the same way you’d insert a jpg or any other image.

<img src="yellowcircle.svg" width="70" height="70">

SVG are supported by all modern browsers, including those used on retina devices such as the iPhones 4 and 5.  However, it's still important to provide a fall-back for older browsers which do not support them, for example IE 8. If you are using Modernizr (see below) already for the rest of your site, then this is a sensible approach. However, there is also a dedicated JavaScript plugin available, SVGeezy, that will deal with this.

To use this plugin, download the script and store it adjacent to your website on your server. Then add the following line of code before the close body tag.

<script type="text/javascript" src="svgeezy_plugin/svgeezy.js"></script>
<script type="text/javascript">
svgeezy.init(false, 'png'); // this will let the plugin check all images
</script>

Similarly to the retina plugin discussed above, you'll actually be providing two images every time; the SVG file and the fall-back jpeg or png file. These both need to be stored in the same place on your server. When the SVGeezy plugin notices your browser doesn't support SVG files, it will use the alternative version of the image.

If you’ve downloaded the source files for the demo from the link at the top of this page, take a look at the SVG file refresh.svg and how the tutorial4_index.html file uses this image.

When it comes to creating the SVG files, the idea of manually coding an image file is enough to make even the geekest geek run a mile! Fortunately, you can save images as SVG files from Adobe Illustrator (Click File > Save > SVG) or the open source vector image editing software, Inkscape. Saying that, I’d recommend doing a few trial runs at this to make sure your designs appear as expected in the browser.

There are also a lot of websites around that offer free SVG icons to download. The gears icon used in this demo is from Game Icons. Another good website is Icon Finder, which lists available formats alongside all search results. Icon Finder is also quite useful to get a feel for what kind of images can be produced as SVG files.

Although SVG files will only work for some types of images, if exploited carefully can provide a powerful way of delivering pin-sharp graphics to all devices. Before moving on, it's worth mentioning that there are other ways of implementing retina images not implemented in this demo, such as using a server side PHP solution which uses cookies and modified .htacces file, or using icon fonts.


One Data Set: Two Map Versions

This demo has two versions of the map; a laptop/desktop/tablet version and a mobile version.

Both mobile and desktop maps use the same data (i.e. photos) stored on Flickr.

Both mobile and desktop map use the same data (i.e. photos) stored on Flickr.

Creating two versions may appear to be cheating slightly. And, for the vast majority of websites I wouldn't recommend separate mobile and desktop versions due to the obvious maintenance overheads. However, the novel type of Google map we've been building is a case when having two versions is sensible.

Crucially, though, we are not going to duplicate the data. Instead, both versions of the map draw from the same set of data on Flickr.  This means the overhead of having two versions is minimal, and we have the flexibility to customize the appearance of the map depending on the device.

I’ve extended the example from the last tutorial.  The tutorial draws data from this new Flickr account (user id: 99915664@N08). (Reminder - each Flickr has an easy(ish) to remember username, in this case bennett1671, and a user ID number, in this case 99915664@N08.) So if you are following along building on what you did in the last tutorial, you need to point your map to this new Flickr account.

This new Flickr account includes photos for all of the festivals, including both the smaller and main events. The Flickr account used in the previous tutorial only included photos for the smaller festivals. The photos for the main events were not stored on Flickr.

Tagging in Flickr

Tagging your photos in Flickr is the key to getting this to work.  Each photo in Flickr is tagged to indicate whether they are a mainevent or a smallevent (these tags are necessary for the laptop/desktop/tablet version) and whether they are an englandevent, scotlandevent, walesevent or irelandevent (these tags are necessary for the mobile version).

The Flickr API calls

When the orange Smaller Events button is clicked on the  laptop/desktop/tablet version, the following Flickr API call is made.  This calls the 99915664@N08 Flickr account and filters the results by the tag smallevent.

http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=f7095d157adfd78715344ed893a9554b&user_id=99915664@N08&tags=smallevent&has_geo=1&extras=geo&format=json&jsoncallback=?

On the mobile version, I’ve clustered the markers according to country and colored the icons accordingly.  So, for example, when you click on the white England marker, the following Flickr API call is made. This API call is the same as the previous one, except it filters the results based on the tag englandevent.

http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=f7095d157adfd78715344ed893a9554b&user_id=99915664@N08&tags=englandevent&has_geo=1&extras=geo&format=json&json&jsoncallback=?

Please see the previous tutorial for a full description of how the results of these Flickr API calls are processed. They both use the flickr.photos.search method from the Flickr API.

SVG Files and the Mobile Version

All of the map markers on the mobile version are SVG files (see above).  Therefore, although they are a bit simpler than the icons on the laptop/desktop/tablet version, they always remain crisp when viewed on retina screens, such as the iPhone 4 or 5.


Testing and Debugging

To end this tutorial series, I just want to highlight a few tools I find useful when developing maps, or anything else online for that matter.  I know there are huundreds, perhaps thousands, of tools around, and so this isn't meant to be an exhaustive list by any means. Instead, it’s the ‘tool kit’ that I use to test things, and work out why something hasn't gone to plan.

These tools are useful, maybe essential, to avoid the nightmare of getting a website to function perfectly on your own machine, only to discover it does something unexpected on a client or customers’ machine.

Google Chrome Developer Tools

To access the Chrome developer's tools, open Chrome and click the Menu Button in the top right and then Tools, then Developer Tools.

The Elements tab in the Google Chrome Developers' tools lets you click on parts of your web page to reveal information about how it has been rendered by the browser.

The Elements tab in Google Chrome Developers' tools lets you click on parts of your web page to reveal information about how it has been rendered by the browser.

This does an enormous amount of things; enough to fill an entire tutorial on its own! A few bits I use often are:-

  • Elements tab (above) – Lets you click on areas on your webpage and see the underlying code. It also lets you play around with the CSS and see the changes 'live' on your web page. This is useful when experimenting with different designs.
  • Console tab – This will bring up errors. Sometimes they are harmless, other times (especially while building a site!) they need some attention.
  • Network tab (below) – Lets you see all the resources loading up and (on the left) includes a time line (right) with loading speeds so you can identify what may be slowing your site down.
Network tab tells you how long each part of a web page takes to load.

Network tab tells you how long each part of a web page takes to load.

Browser Support

Not all browsers support all HTML and CSS features.  This can be problematic when you want to take advantage of the more interesting features of HTML5 and CSS3, while also making sure people with the most ancient copy of IE can also access your website.

But unless you have an extraordinary memory (I haven't!), it's near impossible to remember which browsers object to which features.  This is where the caniuse website comes in very handy. This website gives a summary of which HTML,  CSS, SVG etc. features are compatible with which versions of which browsers.

Also, if you want to use a new feature but older browsers don't support it, then you can use the Modernizr JavaScript library.  As they explain on their website:

Taking advantage of cool new web technologies is great fun, until you have to support browsers that lag behind. Modernizr makes it easy for you to write conditional JavaScript and CSS to handle each situation, whether a browser supports a feature or not.

If a user's browser doesn't support a particular feature, Modernizr lets you also specify a fall-back feature.  This is very similar to the SVGeezy plugin described above.

Cross-browser Testing

In addition to planning browser support and fall-backs while building your site, it's also important to test it on different browsers.  Browserstack is an efficient way of doing this. It lets you submit a URL and then take a look at how the site works in different browsers. The only disadvantage is that it's involves a subscription fee. Though this is arguably cheaper than having a bank of real machines and devices available for testing. A free trial is also available so you can take a look and see what you think.

Another useful browser testing tool when it comes to the mysteries of getting things working in IE, is the Modern.IE website.  As its name suggests, it's for IE only. But it is free and is still a very useful resource.

Before taking a look at your website in Browserstack or ModernIE, it's important to validate your code to iron out any syntax errors.

Validating the HTML, CSS and Javascript

A validator is a free web app which checks your code against current standards. Standards are important to ensure your website functions in a predictable way across different browsers and devices.

There are also a number of tools around that will help you check your JavaScript syntax.  Closure Compiler is actually a tool for compressing your JavaScript (which you may also want to do if your file size is massive), but it's also useful for checking syntax errors. e.g. pesky missing semi-colons that catch us all! If you copy and paste into your code and hit Compile, any errors will be highlighted under the Errors tab. Another useful site for checking code is JSHint.

Download Speed Testing

Page speed is important because not only will visitors be driven away if it takes a long time for your site to load, Google may take this into account when ordering search results.

Analyzing the loading speed of the website using Google Pagespeed.
Analyzing the loading speed of the website using Google Pagespeed.

There are a number of tools that will let you test this, including -

These tools also come up with suggestions of performance improvements you can make.  For example, a common improvement you can make is to compress your images further.  You can use these tools in connection with the Network tab on Google Chrome Developers Tools (above) to investigate potential problems.


Conclusion

OK – that’s it!  As I said at the start of this tutorial, it'd be a whistle-stop tour!  Hopefully after this tutorial series you’re now equipped to make your own Google maps creations. Have fun!

Image Credits

The credits for most of the images (e.g. the festival photos) can be found at the end of the previous tutorials 1 and 3.  These are the new bits for this tutorial:

Refresh icon - Iconfinder

Map marker icon - Iconfinder

Gear icon - Game Icons

Arrow icon - Iconfinder

Laptop icon  - Iconfinder

Mobile icon - Iconfinder

Related Posts
  • Web Design
    HTML & CSS
    A “Readability First” Approach to Media Queries and LayoutReadability first thumb
    In this article I'll be talking about a methodology that is a mixture of many approaches to Responsive Web Design, with a few extras stirred in. It's both "Content First" and "Device Agnostic", and was originally inspired by the typography focused em based "Goldilocks Approach". I like to think of it as a "Readability First" approach.Read More…
  • Web Design
    Complete Websites
    Building the Responsive Timeline Portfolio PagePortfolio thumb
    During this tutorial we will be building the fantastic Timeline Portfolio as seen in an earlier tutorial by Tomas Laurinavicius. We will be using some responsive techniques as well as CSS3 animations, Sass and a little bit of jQuery.Read More…
  • Web Design
    HTML/CSS
    Finishing Off the Merry Christmas Web App InterfaceXmas build 1 retina
    In this tutorial we will finish off our web app front-end so it all looks perfect and functions nicely on all screen sizes. Last time, we rounded off by styling the message boxes, leaving just the content left to do. Shall we dive right in? Ok!Read More…
  • Web Design
    HTML/CSS
    Building the Merry Christmas Web App InterfaceXmas build 2 retina
    Today we're going to build the Merry Christmas Web App Interface; a Photoshop layout from an earlier tutorial by Tomas Laurinavicius.Read More…
  • Design & Illustration
    Web Design
    SVG Files: From Illustrator to the WebSvg thumb retina
    Scalable Vector Graphics (SVG) is a vector image format which began life back in 1998. It was always developed with the web in mind, but only now has the web actually started to catch up. There's no denying its relevance today, so let's have a look at the basics of taking SVG from Illustrator to the web browser.Read More…
  • Web Design
    CMS
    Uber Aesthetics and ResponsivenessGhost rwd retina
    Welcome to the final part of our Ghost theme design tutorial series! In the previous two parts of this series we worked on the first half of styling our theme and laid the groundwork for responsive behavior. This fifth and final part finalizes our styling and completes the task of making our theme fully responsive.Read More…