Introduction
The world has significantly changed after smartphones has been released, especially after the first iPhone. Therefore mobile applications became popular very quickly. Since I own an iPhone, I was excited how people around the world got fascinated for mobile applications, also known as apps. The more frustrating it is as a web developer, not being able to write own mobile apps in a native way.
Many features native apps do support, seem to be impossible to realize only with HTML, CSS and JavaScript. In this blog series you will see, that it is possible to get the native app feeling within a web application!
Although there are many solutions in jQuery – for the obstacles we stumble upon our way in building a web application – I will only use native JavaScript. Not because I don’t like jQuery. Actually I made my first steps in client-side programming with it. Plain JavaScript is more reliable, performant and efficient. And it is a good experience to learn such a powerful and perhaps the most misunderstood language. I set the focus to iOS, since they are still the most used mobile devices. Do not stop reading dear Android users and developers: Since the default browser for the newer Android versions is Google Chrome, and the mobile Safari both use the WebKit rendering engine, there is not much difference.
What do we want to achieve
- Building a web application for the most used mobile phones
- Making that web application able to mimic the user experience and feeling of a “real” app by:
- adding it to the phone’s homescreen and allow it to start like a normal app
- work around browser-given issues with JavaScript
- building a responsive and intuitive UI
Our Goal in this Part
We start by the basics:
- CSS Reset
- setting the canvas for our application
- start the web application from the homescreen
- disable zoom- and scrollability
Problems and their Solutions
CSS Reset
The first thing for every web application is to reset our CSS. This is done quickly as there are already many versions of different CSS Resets. A CSS Reset is necessary to avoid unwanted browser-computed styles such as paddings for the body, default border settings etc. Now everything is cleaned up so we can work on a blank white paper.
I use Eric Meyer’s CSS-reset since years and it still works fine. Of course you can use whatever reset you prefer most:
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; }
Mobile Reset
For our mobile use I extended his reset with some additional statements. These prevents some context menus to show up, the text to be selectable and to remove the highlights when a link is clicked.
* { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } input, textarea { -webkit-touch-callout: text; -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; } html { -webkit-tap-highlight-color: rgba(0,0,0,0); }
Setting the Canvas of our Web Application
The second part for our basic setup is to set the canvas and view of our work. When the content overlaps the actual view of our end devices, the user gets the possibility to scroll and move within our web application, which is mostly unintended. To prevent those issues, we have to use a responsive layout and percentage values instead of pixels in our CSS.
<meta name="viewport" content="user-scalable=0, initial-scale=1.0, width=device-width" /> <meta name="apple-mobile-web-app-capable" content="yes" />
The first line describes the allowed interactions for our users. The above example means that the initial scale is set to 100% and is not allowing a user to zoom. The width of our web application is then set to the devices’ screen width.
The second line describes a simple meta statement which designates our website as a web application. Now we are able to save the website to our homescreen. On iPhone it can then be started without the Safari toolbars, which gives our web-application a juicy native feeling. Insert above two lines to your HTML header.
To enjoy the advantages given by the meta viewport tag, we have to follow one simple rule:
Never exceed the devices’ dimensions!
Otherwise the user will still be able to scroll and zoom (by double tapping or pinching the screen). To avoid these limitations, we create a wrapper element which is exactly as big as the devices’ screen.
HTML:
<div id=”main”> <!-- APPLICATION WRAPPER --> </div>
CSS:
#main { position:absolute; top:0; right:0; bottom:0; left:0; overflow:hidden; }
Disable Scrollability
We have locked the zoom function but we still need to disable the scrolling of our web application. The following JavaScript code will register an event for the document listening to a touchmove gesture. The preventDefault()-method prevents any behaviors of our touch event. That means it will ignore any clicks on links, input or textarea fields, too:
document.ontouchmove = function (event) { event.preventDefault(); };
Disable Scrollability without affecting Links or Textfields
If you want to have a scrollable area, we need to add a more complex logic. I recommend you to wait until part 3 of this blog series comes out, before you use the function below. If you do not want a scrollable area yet, feel free to add this piece of JavaScript to leave the links and input/textarea fields untouched by the preventDefault()-method:
var isClickable = function (elem) { if (elem.nodeName.toLowerCase() === 'a' || elem.nodeName.toLowerCase() === 'input' || elem.nodeName.toLowerCase() === 'textarea') return true; return (elem.parentNode.nodeName.toLowerCase() !== 'body') && isClickable(elem.parentNode); }; document.ontouchmove = function (event) { var target = event.touches[0].target; if (!isClickable(target)) event.preventDefault(); };
With this minimal setup we have created our first web application with a native app feeling. In the next part we dive deeper into touch events and general event management in JavaScript without a library such as jQuery. We also define the startup look-and-feel of our web application by defining an icon and startup screens for iPhone devices.
Thanks for reading so far. If you find it interesting, move on to Part 2 and I would really appreciate your feedback.