Best HTML5 Mobile App Frameworks: Onsen UI

Written by on April 7, 2015

Best HTML5 Mobile App Frameworks: Onsen UI

Welcome to my blog, if there’s something I didn’t cover, feel free to leave me a comment below and I will respond as soon as humanly possible. The topic of today’s article is an in-depth review of Onsen UI Framework.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to Thanks and have a nice day!

Getting Started
GitHub Repo

In recent months, I have written a series of tutorials covering OnsenUI, find them below:

[spoiler title=” Click here if you want to see OnsenUI tutorials.”]



This is Part 5 in a multipart series called: “Best HTML5 Mobile App Frameworks”

Note: I have no intention of stopping writing after I review Kendo UI. If you want me to review a framework you like or know about just write me a comment below.

What Is Onsen UI?

Onsen UI is relatively new addition to mobile framework market. It was released almost one year ago which puts it around the same timeline like Ionic and frameworks. It name was taken from the Japanese language (温泉) and it is a term for hot springs or spa.

Just like Ionic and, it was built around AnguarJS framework (for the future reference we will call it Angular), but latest changes made it possible to work with other frameworks (like jQuery).

For those of you who are not familiar, AngularJS, commonly referred to as Angular, is an open-source web application framework maintained by Google and a community of individual developers and corporations to address many of the challenges encountered in developing single-page applications.

Unlike Ionic, Onsen UI CSS framework is built around Topcoat. It is an open source CSS library designed with speed in mind. Because it doesn’t contain any JavaScript, Topcoat was choosen as a perfect UI building block.

Onsen UI helps you develop both hybrid and web apps. If developing hybrid apps, you can use it with the Cordova / PhoneGap command line, or with Monaca IDE – cloud-based IDE for Cordova. Monaca IDE is a cloud HTML5 development platform that offers programmers the option to develop hybrid mobile applications and deploy them across multiple platforms.

What Onsen UI is not?

Onsen UI suffers from the same problem like jQuery Mobile. It can be used for classic web development but, it looks out of the place when viewed on larger screens. This is somewhat solved with multi-screen support, but you will need to decide if this is good enough for you.

If you like HTML5 markup based frameworks then this is not a framework for you. It’s somewhere between Sencha Touch and jQuery Mobile.

Onsen UI is not a replacement for Ionic framework. While both frameworks can be used for mobile app development, Onsen UI went even further with classic web app support.

Main features

  • Free and Open Source
  • Simple to Use
  • Built around AngularJS, Topcoat, and HammerJS
  • Lates changes makes it possible to work with jQuery
  • Built-in Theme Roller
  • Supports Cordova, PhoneGap, or native app packaging with Monaca IDE
  • Usable for mobile and classic web development
  • Multi-screen Support
  • Font Awesome support

Code example



  <script src=""></script>
  <script src=""></script>
  <link rel="stylesheet" href="" />
  <link rel="stylesheet" href="" />

<body ng-controller="ListCtrl">

  <ons-navigator animation="slide" var="app.navi">
      <ons-toolbar class="toolbar-black">
        <div class="center">Search the Movie Database</div>
      <input type="search" class="search-input search-movies-input" placeholder="Search..." style="width: 100%;height: 45px;" ng-model="" ng-change="searchMovieDB()">
        <ons-list-item modifier="chevron" class="list-item-container" ng-repeat="movie in movies" ng-click="showDetail(">
            <ons-col width="95px">
              <img ng-src="{{movie.poster_path}}" onerror="this.src = '';" class="thumbnail">
              <div class="name">{{movie.original_title}}</div>
              <div class="desc">{{movie.release_date}}</div>
            <ons-col width="40px"></ons-col>

  <ons-template id="view.html">
    <ons-page ng-controller="ViewCtrl">
        <div class="left" style="line-height: 44px">
        <div class="center">Second Page</div>
      <div class="columns">
          <div class="pin">
              <div class="pin-header">
                <img src="">
              <img ng-src="{{movie.poster_path}}" width="200px" />
                Average Vote: <strong>{{movie.vote_average}}</strong> (Votes: {{movie.vote_count}})


var module = ons.bootstrap('my-app', ['onsen']);

module.factory('Movies', function($http) {
  var cachedData;
  function getData(moviename, callback) {
    var url = '',
      mode = 'search/movie?query=',
      name = '&query=' + encodeURI(moviename),
      key = '&api_key=470fd2ec8853e25d2f8d86f685d2270e';
    $http.get(url + mode + key + name).success(function(data) {
      cachedData = data.results;
  return {
    list: getData,
    find: function(name, callback) {
      var movie = cachedData.filter(function(entry) {
        return == name;

module.controller('ListCtrl', function($scope, Movies) {
  $ = {
    name: 'Batman'
  $scope.searchMovieDB = function() {
    Movies.list($, function(movies) {
      $scope.movies = movies;
  $scope.showDetail = function(id){ // 3
    app.navi.pushPage("view.html", { animation: "lift", movieid: id });

module.controller('ViewCtrl', function($scope, Movies) {
  var page = app.navi.getCurrentPage();
  Movies.find(page.options.movieid, function(movie) {
    $ = movie;


.toolbar-black {
  border-color: #111 !important;
  background-color: #444444 !important;

.toolbar-black .center {
  color: #fff !important;  
.search-movies-input {
  border-width: 0px !important;
  background-color: #fff !important;

.list-item-container {
  line-height: 1;
  padding: 15px 0px 0 15px !important;

.thumbnail {
  width: 80px;
  height: 120px;

.name {
  font-weight: 700;
  line-height: 16px;
  font-size: 15px;
  margin-bottom: 6px;

.desc {
  line-height: 1.2;
  font-size: 11px;

.columns {
  -webkit-column-count: 1;
  -webkit-column-gap: 10px;
  -webkit-column-fill: auto;
  -moz-column-count: 1;
  -moz-column-gap: 10px;
  -moz-column-fill: auto;
  column-count: 1;
  column-gap: 15px;
  column-fill: auto;

.pin {
  width: 96%;
  margin: 1%;
  display: inline-block;
  background: #FEFEFE;
  border: 2px solid #FAFAFA;
  box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);
  -webkit-column-break-inside: avoid;
  -moz-column-break-inside: avoid;
  column-break-inside: avoid;
  padding: 15px;
  padding-bottom: 5px;
  background: -webkit-linear-gradient(45deg, #FFF, #F9F9F9);
  opacity: 1;	
  -webkit-transition: all .2s ease;
  -moz-transition: all .2s ease;
  -o-transition: all .2s ease;
   transition: all .2s ease;

.pin img {
  width: 100%;
  border-bottom: 1px solid #ccc;
  padding-bottom: 15px;
  margin-bottom: 5px;

.pin-header {
  padding-left: 72px;
  min-height: 72px;
  border-color: #ddd;
  background-color: #fff;
  color: #444;
  position: relative;
  z-index: 2;
  display: block;
  margin: -1px;
  padding: 16px;
  border-width: 1px;
  border-style: solid;
  font-size: 16px;  

.pin-header img {
position: absolute;
  top: 16px;
  left: 16px;
  max-width: 40px;
  max-height: 40px;
  width: 100%;
  height: 100%;
  border-radius: 50%;  
  margin: 0;
  padding: 0;
  border: 0;
  vertical-align: baseline;
  font: inherit;
  font-size: 100%;  

.pin-header h2, .pin-header p {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin: 0 0 2px 80px !important;
  font-size: 16px;
  font-weight: normal;
  color: #000;
  font-weight: 500;
  font-family: "Helvetica Neue", "Roboto", sans-serif;
  line-height: 1.2;
  display: block;
  font-size: 1em;

.pin p {
  font: 12px/18px Arial, sans-serif;
  color: #333;
  margin: 0;

#columns:hover .pin:not(:hover) {
  opacity: 0.4;

Working example:


Embedded working example:

OnsenUI Navigation Pattern

Continue Reading


3 thoughts on “Best HTML5 Mobile App Frameworks: Onsen UI”

  1. The previous commenter was saying that the framework does not support right-to-left (needed for middle eastern languages like Arabic, Persian, Hebrew) and some others.

    I am not sure whether it’s true or not though.

Leave a Reply