On Github trongthanh / mobile-web-app-howto
Presented by Tran Trong Thanh / @trongthanh
This presentation is supposed to run on an iPad Retina for all demonstrations to work.* not include proxy browsers
Note on proxy browsers: browsers which rely on proxy servers to compress response data for bandwith and normally complex JS is stripped off.One Must Know
Make use of built-in inputs and interactive elements.Your custom JS components can't beat the native one.
<input type="date"> <input type="time"> <input type="month"> <input type="range"> <select> <option value="">Jump To Section:</option> <optgroup label="Introduction"> <option value="about">About</option> </optgroup> ... </select>
Link: all built-in iOS Safari inputs * Range input is customized with CSS for better interaction.
New HTML5 form inputs cut down the effort to customise component and interaction All built-in iOS Safari inputs: https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/InputTypes.html/* Disable text selection for all */ * { -webkit-user-select: none; } /* Enable back text selection on text inputs */ input, textarea { -webkit-user-select: text; }
And use :active instead
/* disable tap highlight color */ * { -webkit-tap-highlight-color: rgba(0,0,0,0); } /* use pseudo class :active instead */ .tappable:active { transform: translateY(2px); /* browser prefix needed */ }The tap highlight is there but very hard to observe on iOS7 Safari.
HWA rendering through CSS3's 3D transform
/* Enable HWA on a particular element */ .hwa { -webkit-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); }
Note: only use HWA rendering when needed.Overuse may cause GPU memory shortage and result in crash/hang.
Source: Why Moving Elements With Translate() Is Better Than Pos:abs Top/left
if ('geolocation' in navigator) { /* geolocation is available */ navigator.geolocation.getCurrentPosition(function(position) { alert('Your position: ' + position.coords.latitude + ' - ' + position.coords.longitude); }); //second param is fail handler } else { alert('Your browser doesn\'t support Geolocation API'); }
Is A Must
<head> ... <!-- Allow the app to runs in fullscreen mode --> <meta name="apple-mobile-web-app-capable" content="yes"/> <!-- Control the status bar appearance in fullscreen mode (new in iOS7) --> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!-- Control viewport sizes, scaling... behaviors --> <meta name="viewport" content="width=device-width,height=728, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"> <!-- Disable/enable telephone number detection --> <meta name="format-detection" content="telephone=no"> <!-- Place favicon.ico and apple-touch-icon.png in the root directory --> ... </head>
Link: iOS Safari supported meta tags Link: Mobile Boilerplate
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { /* Retina-specific stuff here */ }
*Link: Responsive image solution
Retina Display Query Media snippets: http://css-tricks.com/snippets/css/retina-display-media-query/You Must Embrace
Mouse Events
(desktops)
Touch Events
(mobile webkit and the like)
Pointer Events
(IE Mobile*)
* In IE10 Mobile, it is MSPointerDown, MSPointerUp...
$('#foo').on('click', function() { //stuff }); $('#foo').on('mouseup touchend MSPointerUp pointerup', function(event) { //stuff }); var POINTER_END = 'mouseup'; if ('ontouchend' in window) { POINTER_END = 'touchend'; } else if ('onmspointerup' in window) { POINTER_END = 'MSPointerUp'; } else if ('onpointerup' in window) { POINTER_END = 'pointerup'; } document.getElementById('foo').addEventListener(POINTER_END, function() { //stuff });PointerEvents shim: http://handjs.codeplex.com/
document.addEventListener('DOMContentLoaded', function() { //enable FastClick FastClick.attach(document.body); document.getElementById('fastclick-btn').addEventListener('click', function(e) { clickNote.textContent += 'Click! '; }); });
Link: FastClick library Update: New workarounds for 300ms delay on major mobile browsers
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
.scroll-box { width: 200px; height: 200px; overflow-y: scroll; /* has to be scroll, not auto */ } .touch { -webkit-overflow-scrolling: touch; }
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
var output = document.getElementById('scroll-output'); var scrollBox = document.getElementById('scroll-box'); scrollBox.addEventListener('scroll', function() { output.value = scrollBox.scrollTop; });
Work around: use iScroll library
.submenu { position: absolute; overflow: hidden; height: 0; opacity: 0; transition: height 0.5s, opacity 0.5s; /* browser prefix needed */ } .menu:hover .submenu { height: 400%; /* there are 4 items */ opacity: 1; }
Push
To The Next Level
It's website optimization but with extreme approach.* A good animation library like GSAP will help using the best approach
Shadows, gradients are known to cause performance and UI janks. HWA tricks will overcome but GPU memory is limited.Demo
Demo
iOS Safari with OSX Safari developer tool demo
Android Chrome with desktop Chrome devtool demo
This presentation was first presented in June 2014 by Thanh Tran for Nau Studio team. Revised first time on January 2016
The slides is powered by RevealJS presentation framework with a modified Beige theme. Source code of the slides is available on github.
© 2016 Nau Studio. All rights reserved.