You are on page 1of 53

Designing Responsive Web

Mobile Mapping Applications
Allan Laframboise

Key Considerations
Web Mobile Design
Mobile Devices
Are different!
! Physical device
! Screen size
! Button size
Are different!
! Touch
! Orientation
! Keyboard
! Voice
Are different!
! App to work like an app
! Websites to work like an app
Design Patterns
Need to be different!
Think mobile first!
Responsive Design
! Designing a single web page/app that works well
across a variety of devices and screen sizes
! Re-use content and software
! Considers
! Device limitations
! User’s behavior
Components of Responsive Design
1. Fluid Grid System
2. Media Queries
3. HTML5, CSS & JS
Fluid Grid System
! Layout adapts to different screen sizes
! Based on percentages
! 12 column / 960px
Media Queries
! Detect device screen size and orientation
! Apply CSS at specific break points
! Typical: 480px, 768px, 1024px, 1280px

@media only screen and (max-device-width:480px) {

/* Custom css styles */
body {
font-size: 0.5em;
display: none;
! Mobile friendly HTML5
! Meta tags
! Input types (text, dates!)
! CSS3
! Selectors, transitions
! JavaScript
! Touch events
! Geolocation, localstorage,
websockets, appcache!.
Custom Framework
Mapping Apps - I


menu-bar with buttons


Typical “full-view” Mapping App
3 Row – 2 Column
Default Behavior
Not scaling, not adapting

Lower resolution

Grid Layouts
Vertical Stacking

Vertical Stacking

No Stacking

Horizontal Stacking

One Design Strategy
Large Devices: 3 Rows - 3 Columns
Wide-screen Monitors (>1280px)
1280px & above

1024px 768px
Screen resolution
Medium Device: 2 Columns
Desktops and Laptops (1024px - 1280px)
1280px 1024px & 768px
Screen resolution
Medium Device: 2 Columns
Desktops and Laptops (1024px - 1280px)
1280px 1024px & 768px
Screen resolution
1280px 1024px 768px &
Screen resolution
Small Device: Single Column
iPads and Slates (768px – 1024px)
1280px 1024px 768px &
Screen resolution
Small Device: Single Column
Smaller iPads and Slates (768px – 1024px)
1280px 1024px < 768px
Screen resolution
Extra Small Device: 1 Column, Minimized
iPhone, Android (< 768px)
! Title
! Full map
! Icon tools
1280px 1024px
Screen resolution
Extra Small Device: Windowing Options
Keyboard input and output
< 768px
1. Full Screen 2. Partial Screen
1280px 1024px
Screen resolution
Fully Responsive HTML5 Application
Adapts to all screen sizes
< 768px
Web Frameworks
Mapping Apps - II
Responsive Web Frameworks
Standardized set of HTML, CSS and JS
! Bootstrap 3
! Foundation 3
! Skeleton
! YAML 4
Fonts, images, media queries, components!
“mobile first”
ArcGIS JavaScript in a responsive web framework
! Bootstrap ver 3 framework
! Responsive map
! Resize and re-center
! Pop-ups, widgets
! Touch
! CSS Styles
Step 1: Get bootstrap-map-js
! \Bootstrap ver 3.0\...
! \src\js\bootstrapmap.js
! \src\css\bootstrapmap.css
! \doc\...
! \templates\..

Step 2: Create a page
<!DOCTYPE html>
<title>Bootstrap 101 Template</title>
<meta name="viewport" content="width=device-width, initial-
<!-- Bootstrap -->
<link href="../assets/css/bootstrap.min.css" rel="stylesheet"

<h1>Hello, world!</h1>

<!-- jQuery (for Bootstrap's JavaScript plugins) -->
<script src="../assets/js/jquery.js"></script>
<!-- Include all plugins or individual files as needed -->
<script src="../assets/js/bootstrap.min.js"></script>
Step 3: Add a responsive map - I
<!– ArcGIS css -->
<link rel="stylesheet" type="text/css" href="

<!-- Bootstrap-map-js css -->
<link rel="stylesheet" type="text/css" href="../src/css/

<style type="text/css”>
#mapDiv {
min-height: 100px;
max-height: 1000px;
Step 3: Add a responsive map - II
<div class="container">
<div id="mapDiv"></div>

<script src=""></script>
<!– Load Bootstrap Map – responsive map -->
function(Map, BootstrapMap) {
<!-- Get a reference to the ArcGIS Map -->
var map = BootstrapMap.create("mapDiv",{
A quick look inside!
Row 1: col-lg-12 = 100%
Row 2: col-lg-9 = 75% + col-lg-3 = 25%
Row 3: col-xs-4 + col-xs-4 + col-xs-4 = 100%

Bootstrap Fluid Grid
CSS to define row and column behavior
<div class="row">
<div class="col-xs-12 col-sm-12 col-lg-12">
<h5>Top 12</h5>
<div class="row">
<div class="col-xs-12 col-sm-8 col-lg-9">
<!-- Bootstrap-map-js -->
<div id="mapDiv1"></div>
<div class="col-xs-12 col-sm-4 col-lg-3">
<h5>Right 3</h5>
<div class="row">
<div class="col-xs-4"><h5>Bottom 4</h5></div>
<div class="col-xs-4"><h5>Bottom 4</h5></div>
<div class="col-xs-4"><h5>Bottom 4</h5></div>
</div> >
Responsive Grid: Dynamic column widths
Sets logical breaks for different screen sizes

<div class="page-header hidden-xs">
<div class="row">
<div class="col-xs-9"><h2>Windows</h2>
<p class="lead">Show modal and responsive pop-ups.</p>
<div class="col-xs-3">
<button id="geosearchNav" type="button" class="btn btn-
primary btn-lg btn-fixed-lg">Show Window</button>
Responsive Grid: Dynamic visibility
CSS Styles
Responsive Map: Viewport behavior
Prevent scaling and enable full screen browser

// Optimize for mobile – prevent scaling on pinch
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no”>

// Safari iOS – apps only
<meta name="apple-mobile-web-app-capable" content="yes”>
<meta name="apple-mobile-web-app-status-bar-style" content="black”>
// Chrome for Android - NEW!
<meta name="mobile-web-app-capable" content="yes">
Responsive Map: Scroll without pan
Separate page and map navigation
// Set touch behavior
createMap: function() {
var options = {smartNavigation:false});
var map = new Map(mapDiv,options);
map.on(‘load’, this.setTouchBehavior);
return map;

setTouchBehavior: function() {
Responsive Map: Auto-resizing
Scale to all devices and windows
// Responsive resize
var resizeWin function() {
var w = window.innerHeight;
if (w != this._w) {
this._w = w;
var b = document.body.clientHeight;
var mh = this._mapDiv.clientHeight;
var ms = this._calcSpace(this._mapDiv);
var mh1 = mh - ms;
var room = w - b;
var mh2 = room + mh1;
style.set(this._mapDivId, {"height": mh2+"px"});

on(window, "resize", lang.hitch(this, resizeWin));
Responsive Map: Auto-recentering
Maintain the geographic center
// Auto-center map
var recenter = function(extent, width, height) {
this._map.__resizeCenter = this._map.extent.getCenter();
var timer = function() {
setTimeout(lang.hitch(this, timer), this._delay);

on(window, "resize", lang.hitch(this, recenter));

Tip: Listen for onTouchStart and onClick
Responsive Popups: Smart touch
Full-view position and fast touch

// Smart-center popup
var updatePopup = function(obj) {
var infoW = obj._map.infoWindow;

on(, "click", lang.hitch(this,
Using Media Queries
Fixed map based on screen size
/* Extra small devices (phones, up to 480px) */
@media (max-width: 480px) {
.map { height: 100px; }

/* Small devices (tablets, 768px and up) */
@media (min-width: 768px) {
.map { height: 200px; }

/* Medium devices (desktops, 992px and up) */
@media (min-width: 992px) {
.map { height: 300px; }

/* Large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {
.map { height: 400px; }
Other Tips and Tricks
! Watch for .container CSS
! Remove all :hover states
! Listen for onTouchStart and click to avoid 300ms
Final Notes
! Write code once
! Write is “responsively”
! Make your maps responsive
! Know your device
! Know you user

Don’t re-invent the wheel!