Announcing jQuery Mobile 1.1.0 RC1

The jQuery Mobile team is excited to announce the first release candidate of 1.1.0. This release has been a real labor of love, with hundreds of commits and tons of improvements, big and small, to make jQuery Mobile feel faster, smoother and more polished across the board. We encourage the community to help us test and shake out any final bugs before we release the final version in the upcoming weeks. Try it now!

When we first started developing the library, CSS support for position:fixed in mobile platforms was pretty much non-existent so our “fixed” toolbar solution dynamically re-positioned the toolbars each time you scrolled the page. Although it was a decent stopgap, the way mobile browsers would freeze the DOM during scroll would result in the toolbars briefly scrolling with the document which was impossible to completely fix. Alternate approaches use JavaScript-based momentum scrollers to achieve true fixed toolbars, but these only work on a small subset of platforms, have non-native scrolling physics, and can introduce performance and usability issues in less capable devices. None of this was an acceptable option for this project.

We now have a solid re-write that provides true fixed toolbars on the a lot of popular platforms and safely falls back to static toolbar positioning in other browsers.

The coolest part about this approach is that, unlike JS-based solutions that impose the unnatural scrolling physics across all platforms, our scrolling feels 100% native because it *is*. This means that scrolling feels right everywhere and works with touch, mousewheel and keyboard user input. As a bonus, our CSS-based solution is super lightweight and doesn’t impact compatibility or accessibility.

Since we’re removing the 1.0-era fixed toolbar re-positioning script, some platforms like iOS 4 will now fall back to static positioning where the toolbars simply scroll with the page but we feel it’s better to have a crisp divide: it either works perfectly or falls back to a safe and usable solution.

The new fixed toolbars also have a robust set of options and methods you can tap into to customize the behavior such as whether toolbars are visible on page load, whether the tap to toggle toolbar feature is enabled, toggle transition (defaults to slide up/down)

Improved transitions: Smoother, faster

Our AJAX navigation system is one of the best things about jQuery Mobile because it makes page navigation faster and adds animated page transitions. We did a ton of work leading up to 1.0 to make our transitions as smooth as possible, but there were two significant things that turned out to very difficult: the need to scroll the page between transitions and Android’s poor animation performance.

First, we have a hard constraint that both the page you’re on and the page you’re animating to are both sitting on the same viewport — we animate and scroll the viewport to achieve the transition effect. This means that if you are scrolled down on a page and click a link, we need to first scroll to the top of the page, then begin the transition (yeah, we tried every CSS trick to avoid scrolling, none work well on longer pages or Android). Since we also restore your scroll position if you go back, we may need to scroll up, transition, then scroll down to restore your scroll position. On mobile devices, scrolling is pretty slow so you’d see the page scroll by then stop at the top which can make things feel jumpy.

Because we don’t have widespread CSS support for overflow:auto on mobile browsers and aren’t satisfied with the limitation of JS-based scrollers, we had to think creatively. For 1.1, we embraced the scroll jump constraint and shuffled the sequence of the page transition JS handler to first fade out the current page, then scroll the page into position before transitioning in the new page. Since we’re scrolling a blank page, it scrolls faster and the scroll jump is invisible so things feel much more controlled and smooth. As a bonus, the fade out/in animation is impressively smooth and blink-free on every platform. This does mean that every transition has a place where we need to fade out a screen to accomodate the scroll jump, but we think this still looks pretty sharp.

On the second topic, I won’t mince words here: Android as a whole has abysmal performance rendering CSS keyframe animations. Regardless of version or device, Android devices stutter, drop frames and blink when performing any page page animation other than a simple fade.

Post-1.0, we went back to the drawing board to investigate exactly what combination of CSS properties caused the most issues so we could re-vamp our transitions to be as easy on Android as possible. We found that most common things we wanted to do like animating size or position along with opacity would cause blinks, missing animations and odd opacity rendering on box-shadows. With this in mind, we spent weeks testing on a wide range of Android-based devices to arrive at a set of minimal transitions that would be as non-taxing as possible.

Unfortunately, after a ton of work, we’ve determined that it’s not possible to dumb down page transitions enough to get acceptable performance in Android 2.x, even on a newer device like a Nexus S running 2.3. After a lot of deliberation, we’ve decided to use a feature test for 3D transforms to target transitions: if a browser passes, it will see the full range of transitions. By default, if a browser fails this 3D test, they will fall back to a fade transition, regardless of the transition specified. All Android 1.x-2.x devices fail this test but Android 3.x and 4.x pass. The fallback behavior for each transition is completely configurable if you want to change this behavior.

TL;DR: The default page transition is now be a super fast and smooth fade out/in animation. All the 1.1 page transitions (slide, flip, etc.) have been tweaked to have a place it the animation where we fade out to accomodate the scroll jump, but we think this looks pretty sharp and always in control. On some platforms like Android 2.x that don’t support 3D effects, the simpler fade transition will be the only game in town, regardless of the transition specified. View the new 1.1 page transitions.

Two new transitions in 1.1: Turn and Flow.

In addition to re-vamping all the 1.0 transitions, we’ve added a turn transition that is similar to the WP Metro style page effect and a flow transition that is bit like the iOS tab switching transition where pages zoom in and out. Both look great on platforms such as iOS and Blackberry PlayBook that support 3D.

Firefox support for transitions

Yep, we’ve added -moz prefixed rules for all the page transitions to bring support to newer versions of Firefox desktop and (hopefully) a future build of Firefox mobile. We will continue to add vendor-prefixed rules for Opera, IE, etc. as these browsers gain support prove they have support with acceptable performance. Vendor prefixes add a lot of code when working with CSS keyframe animations so we want to add these only when supported to keep the file sizes down.

New AJAX loader design and options

As we revisited page transitions, we found that a more subtle loader design actually made the navigation feel faster so we re-designed the loader to be as minimal as possible and ended up with a light spinner image with no text to keep things simple. Hoever, we understand that there will be times when you do need to display text along with the loader so we’ve beefed up the loader to be much more flexible. There are now a few new global options that let you set whether you want to see the text, loader or both and set the theme or text at runtime. For example, this will show the loader with theme A and a custom message: $.mobile.showPageLoadingMsg("a", "Loading theme a...");. View a demo of these new loader options in the docs.

Related: TouchOverflow feature to be deprecated in 1.1

We introduced the experimental touchOverflow feature in 1.0 because it made our transitions smoother and brought true fixed toolbars in iOS5. This came at the cost of code complexity and a lot of CSS rendering bugs due to Apple’s buggy implementation. Now with our new fixed header and transitions approach, we don’t see any viable use case for this feature so we’re deprecating it at 1.1.0. Deprecation here simply means no errors are going to be thrown by its removal: we will keep our $.support and $.mobile.touchOverflowEnabled properties defined to avoid throwing issues in custom code that leveraged this feature.

Support for jQuery 1.7.1

jQuery Mobile 1.1.0 now supports both 1.6.4 and 1.7.1 versions of jQuery core. We recommend that you use 1.7.1 to take advantage of all the great improvements in the latest release. If you stick with 1.0.1 for a while, remember that only supports 1.6.4.

Mini form elements

As we worked on fixed toolbars, we started to test the rendering of form controls in headers and footers and in 1.0, things were a bit broken. In 1.1, we’ve spent a lot of time tweaking the form elements so they will render nicely in toolbars but the standard versions seemed a bit big in toolbars.

We had a smaller button style already hard-coded in headers so we used the vertical height of that button as a basis for a new “mini” version of all our form elements (buttons, selects, inputs, sliders, switches, etc.).

By adding the data-mini="true" attribute to these elements, the more compact version will be displayed which is perfect for toolbars. The image on the right compares the standard vs. mini versions of each element.

Flip switch: Improved design

As we started to look at our form elements, the flip switch seemed like it could use a bit of visual cleanup. We looked across popular mobile platforms and they all seemed to use a pretty consistent design that used a smaller handle to maximize horizontal space for the text. In 1.1, we’ve tweaked the design to use a round handle (or square, depending on your theme) for the flip switch and re-vamped the underlying code to make it more robust.

Slider: Highlight feature

We also added a feature to add a track highlight from the left of the track to the slider position. Just activate the highlight feature, add data-highlight="true" attribute to the range input.

Slider: Step attribute support

The step attribute is part of the HTML5 range input spec and allows you to specify the increment the slider handle must move. This defaults to 1, but now you can specify the step to slide by increments (step="25") and the handle will snap to these points. If a value in entered into the numeric input next to the slider that is outside the steps, it will round to the closest one. We borrowed this code from the jQuery UI project so thanks guys.

Zoom fixes: orientation change iOS bug and select/input zoom

If you wanted to avoid the page zooming in oddly when you rotated an iOS device into landscape mode, you needed to disable user zooming via the viewport meta tag. However, we think that it’s nice to keep user zooming enabled if at all possible so after a lot of tinkering, Scott Jehl came up with a clever hack that uses accelerometer data to determine if a device is in the process of being rotated. If it is, we temporary disable zooming to avoid the orientation bug, then quickly restore it. We’ve created a new utility (zoom.iosorientationfix.js) in jQuery Mobile that uses this technique to fix the iOS orientationchange zoom bug.

There is another utility zoom.iosfocusfix.js, which disables zoom as a select or input element is focused, preventing iOS from zooming into that element and cropping the viewport. Zoom is restored just after the focus event fires (a half second timeout).

We added a general utility: $.mobile.zoom, which as 3 members: enabled [bool], disable [function], and enable [function]. This simple utility is used to disable user scaling in devices like iOS. The disable() method disables user-scaling. The enable() method enables user-scaling. The enabled property keeps track of state. This utility is used by the two features above and can be used in custom scripting events as well.

AMD module support

In jQuery Mobile, we’re using AMD to express dependencies between the different modules for the build scripts and to support our in-progress download builder tool. However we strip out all the AMD overhead in the final source files. It will export an anonymous AMD module if an AMD loader is present, the same way jQuery Core does it. Special thanks to James Burke (@jrburke) for jumping in and helping us polish our AMD implementation.

data-enhance=false data attribute

As of jQuery Mobile 1.0, all the markup within a page is scanned for elements to be enhanced. This is problematic for 3rd party widgets/libraries that don’t want anybody enhancing their markup or attaching behavior. We heard requests for a data-* attribute that can be place on an element container to tells the framework not to enhance anything inside it for these situations. In 1.1, we’ve added a new data-enhance=false attribute that can be added to a container to prevent both auto-initialization and link/form hijacking. This is also available via $.fn.jqmEnhanceable. It’s important to note that because of the performance impact incurred by finding a parent element with the data-enhance=false attribute this feature must be turned on explicitly with $.mobile.ignoreContentEnabled=true.

data-ajax=false now works on containers

On a related topic, we’ve always offered the ability to disable the AJAX navigation system from hijacking a link or form submit via the data-ajax="false" attribute, but people have asked for a way to apply this exclusion more efficiently to a grouping of links. In 1.1, this is now possible by simply adding, and setting $.mobile.ignoreContentEnabled=true, the data-ajax attribute to a parent container and it will exclude all the parent link or forms from the AJAX navigation system behavior.

New docs navigation and search

We spend quite a bit of time refining our docs and we think they are pretty solid. However, there are now a lot of pages and it can be hard to find what you need simply by browsing around. For 1.1 we’ve added a button in the upper right corner of every page that opens a searchable sitemap that contains an alphabetized list of pages in a filterable listview. Although this isn’t a true site search, we’ve used the hidden filtertext feature to load up each list item with a rich set of keywords you might be looking for. We plan on making some larger docs changes in future releases, but this seemed like a nice addition to the docs.

Please help us test!

We’re looking for help with testing this release so we can release a final build as soon as possible. Browse the docs or try out the 1.1.0 release in your projects, then report issues in the GitHub tracker. Be sure to specify the device, OS version, browser, steps to reproduce and include a simplified test case that uses the latest build (template here). If all goes well, we hope to release the final build in about 2 weeks.

Platform support in 1.1.0 RC1

jQuery Mobile has broad support for the vast majority of all modern desktop, smartphone, tablet, and e-reader platforms. In addition, feature phones and older browsers are supported because of our progressive enhancement approach. We’re very proud of our commitment to universal accessibility through our broad support for all popular platforms.

We use a 3-level graded platform support system: A (full), B (full minus Ajax), C (basic). The visual fidelity of the experience and smoothness of page transitions are highly dependent on the CSS rendering capabilities of the device and platform so not all A grade experience will be pixel-perfect but that’s the nature of the web.

I need to set the meta content width to a specific value, rather than the default iPad screen width, to view an embedded pdf at full screen width. This works fine on 1.01 but on 1.1 the screen width opens at the default value and so the pdf appears as a small image in the corner. If I rotate the iPad to landscape, the pdf appears full screen and rotating it back to portrait it remains full screen. Any idea as to why this happens and is there a way to force it to open at the specified width first time round?