We wrote about PWA vs. native app development for a more general overview of the advantages of each. Hint - PWAs are cool for most cases, React Native is an excellent cross platform choice that compiles to native code, and if you are building an app that relies on all the sensors and needs to be super small and optimal, native code is the way to go (though you can combine it with React Native UI).
This article will look into the details of building and optimizing a progressive web applications (PWA) for native-like look and feel.
Apps should be installed and sit on the home screen
When a user lands on the web page, they should be aware that there’s an option to add the app to their device’s home screen. Android provides a way for web developers to “install” the app for the user so that the experience is seamless.
Unfortunately, iOS still doesn’t provide this option but it supports PWAs and users can add the app to the home screen with some manual work. If we detect that a user is accessing the app from mobile, we display instructions for adding the app to their device home screen.
With an active service worker, when added to the homescreen the PWA loads faster and works offline and on low quality networks.
App name and icon
Web manifest is where you define icons and app name (for most platforms - desktop, Android, but not iOS). iOS requires icons to be defined in the head section of the app, more in the Safari Web Content Guide.
Keep in mind that you will need to generate icons for all resolutions. Fortunately, there are many resources online to help you generate all the app icons you’ll need ( hint - Google app icon generator).
Don’t forget to set short name - this is what will be shown below the app icon. Try to keep it under 12 characters to avoid truncation.
Hide the web browser’s UI, like URL and status bar
Web manifest specifies display property where you can control the browser UI. There are a few options available: fullscreen, standalone, minimal-ui and browser.
And add to web manifest file:
iOS Safari is not respecting web manifest, but provides another option to indicate that the browser UI should be hidden. Add to the html head section the following:
Avoid flashing background while the app loads
By setting the
theme-color it would indicate to the browser to render background color of the app while it loads so that the user doesn’t see flashing app from the white background.
Having different color of the app background from the status bar might not be the most visually appealing option. There are a few options here - choose the one you want (black, black-translucent and default).
If you would like to follow the background of the app, use the following in the head section:
Add splash screen
This is super important because it will completely change the experience of the app. When mobile OS starts your app it needs to initialize web renderer which takes some time and user can experience screen flashing. This is where splash screen image comes in to hide the loading in the background and let the user directly into the app experience.
Android has built in mechanism to generate the splash screen, but iOS requires all the resolutions (portrait and landscape for all the different form factors your app would run on). It can be specified in the head section of the html:
Did you notice how landscape splash screens need to be specified as well, and that device width and device height are the same just orientation:landscape is added?
Play around, try it out on all of the devices you would like your web app to run to achieve desired results.
Native-like touch experience
Tapping links in the mobile browser renders a gray highlight - common for web pages but odd for mobile apps. In order to disable it use the following css:
Instead of relying on the highlight effect, add custom touch effect using CSS. There is a trick to keep the links display :hover and :active effects when tapped - include empty “ontouchstart” attribute on the body element and voila - pure native button effects.
Text selection - only where appropriate
Native apps do not provide text selection as the web browsers do, e.g. buttons labels should not be selectable, etc.
-webkit-user-select property allows control of the selection behaviour. Probably you want this only on mobile, so put it under media query.
Disable callouts and link highlighting
Doing a long press on the link in iOS would open up the callout menu and we do not want that in the mobile app for every link. If links need to be copied or shared, good practice here is to implement custom dialog
To disable it add the following CSS
iOS overscroll and bounce effect
It is expected that the mobile app covers the whole screen and that touch scrolling should scroll only the content of the app and not it’s headers. However default behaviour for mobile web is to allow overscroll - inside the web browser, this is fine, but for the app this is not expected.
The behaviour comes from the default scrolling effect for touch screens on Safari. In order to avoid it set webkit CSS property
-webkit-overflow-scrolling to auto.
This will prevent ios bounce effect but may introduce side scrollbar. Here is a trick to hide it:
Mobile app optimized components
However, this is just a start as you should design the entire app with mobile support in mind so that the UI is responsive or adapts and uses mobile-optimized views (e.g. listview instead of a table etc.). Here are a few examples:
Search for cross platform mobile development solution
If you are building for the web, you’re probably aware of the PWA (Progressive Web Apps) hype. For years developers have been trying to find the best cross-platform framework that would allow them to distribute apps from a single code base.
Mobile devices CPUs progressed a lot over the years and rendering web is not a big issue anymore. This was good timing for progressive web applications to be released as a way to provide native-like mobile experience for web applications.