> HW Accelerated Accordion
Accordion on mobile webkit is a bad beast. The accordion effect is usually obtained by reducing/incrementing the elements height. Unfortunately, on mobile, height and width are two not hardware accelerated properties, which means choppy animations. Fear not: I just baked for you a translations-only height-changes-free accordion for all your mobile needs.

Project info
Last code update: 2010.08.20 – v1.0
Device compatibility: iPhone/Ipod touch >=2.0, Android >=1.5, iPad.
QR Code opens demo page.
Support development
If this script saved your day or you wish to support future developments you may consider sending some funds via PayPal.
Overview
Coding this widget has been tricky. The code itself is pretty simple (5kb un-minified), the hard part was to find the right mix of HTML and styles to make the magic happens. Please consider that the code is still rough on the edges but it works and I decided to publish it as is to get the community feedback and suggestions. The script seems now pretty stable and ready for production. I’ll probably add the load-with-opened-panel feature in v1.1.
The script uses just CSS “translate” to open the panels, so we are sure that the hardware acceleration is triggered.
How it works
Using the accordion is a piece of cake.
The HTML structure must be as follow (sorry for the extra mark-up, if you have better solutions, please share):
<div id="accordion"> <div> <div>Title</div> <div>Content</div> </div> ... </div>
All you have to do is to creare a new accordion on DOMReady or on window load:
var myAccordion;
function loaded() {
myAccordion = new accordion('accordion');
}
document.addEventListener('DOMContentLoaded', loaded, false);
'accordion' is the element ID. There’s a bunch of CSS needed by the script, it’s all included in the example.
As an added feature you can have the page to scroll to the opened panel. This can be useful on small screen (ie: everything but iPad), so the clicked panel is always on focus.
Eg:
new accordion('accordion', true); // Force scrolling to the opened panel
Future development
As I said the script is pretty rough. The first thing to add is the possibility to load the accordion with an opened panel. Also having a version that lets you open multiple panels would be nice.
Revisions history
v1.0, 2010.08.20 – Bug fixes
v1.0 beta 1, 2010.08.15 – Initial release
Looking great, Matteo!
Regarding the extra markup, have you considered using definition lists?
yes, initially I used DLs, but each title+description has to be wrapped inside a div and as far as I know dt and dd can’t be wrapped.
Right, gotcha. Bummer.
I am guessing ULs also won’t work?
Same problem. I have to wrap each title/description pair.
Can I ask how GhostTouch is going? It looked great in the video! I like how it doesn’t have a dependency on jQuery, for optimal speed. Although saw your post on supporting jQuery mobile and that could also be great with everyones help.
I don’t know which direction I will take. Jquery mobile is a long way to go I suppose, while the basic ghosttouch is almost ready. I suspect that targeting so many devices will force the dev team to have a “core” as big as desktop jquery (but it seems that nobody cares). Also could be a real pain for plugin developers to make add-ons compatible with –say– windows mobile.
If I’ll like jquerymobile I may just start developing plugins for it, if it becomes bloated I’ll continue my own way.
Matteo,
I’m with you on the jQuery Mobile thing. They say they’re just adding the fixes to the core “desktop” jQuery. Not a tactic I agree with. Keep going with GhostTouch, there’s more than enough space in the market for a good, lightweight, focused framework.
As far as I understand it will be more of a mobile UI than a dedicated framework. Not what I expected/wished.
Trying to use your accordion script inside of an iscroll with some interesting results. Have you played around with this, do you have any pointers?
I’m doing just translations so there shouldn’t be big conflicts with iScroll. If it doesn’t work, maybe a refresh at the end of the accordion animation is needed.
“I’m doing just translations so there shouldn’t be big conflicts with iScroll. If it doesn’t work, maybe a refresh at the end of the accordion animation is needed.”
How do you bind to the accordion animation to initiate a scroll refresh?
Hi Matteo,
thanks for this and iScroll. A version that allows multiple expands and a case where certain fields can start open would be really great.
@justin, I’ve demoed using this and iscroll together – no problems at all. Just add the .js, the initialization code, the css and add the appropriate html in the body and you’re golden.
Plz give me the code if u have as at my end it’s not workin
this is not workin on opera and firefox browsers
anybody can hellp me fixes this ?
Accordion is based around Webkit exclusively – you’ll have to look around for a different solution for Opera and FireFox. Why WebKit only? It’s designed for iPhone / iPad / Android, etc. mobile platforms, not desktop machines.
Because desktop platforms already have accordion solutions. This is a very tricky-hacky way to have it working on mobile
Speeding up HW Accelerated Accordion (Part 1)
I’ve got a project that’s got a lot of sections for the accordion to parse, and inside of each section is quite a bit of extra layout stuff. It was taking as long as four seconds for all the layout stuff to be done and the page to display on an iPad. Hrm.
So, part 1 is for people who are supporting iOS and Android (part 2 breaks Android), particularly when using PhoneGap.
First, in accordion.js, comment out:
/* that.wrappers[i].style.webkitTransitionProperty = ‘-webkit-transform’;
that.wrappers[i].style.webkitTransitionTimingFunction = ‘cubic-bezier(0,0,0.25,1)’;
that.wrappers[i].style.webkitTransitionDuration = ’0′; */ (lines 35 – 37)
And
/* accordions[i].style.webkitTransitionProperty = ‘-webkit-transform’;
accordions[i].style.webkitTransitionTimingFunction = ‘cubic-bezier(0,0,0.25,1)’;
accordions[i].style.webkitTransitionDuration = ’0′; */
In your CSS under #accordian > div add:
-webkit-transition-property: -webkit-transform;
-webkit-transform-duration: 0;
-webkit-Transition-Timing-Function: cubic-bezier(0,0,0.25,1);
and under #accordion > div > div:last-child add the same bit.
You won’t get a HUGE speed burst, but you’ll get a bit extra out of it – it’s 6 extra style assignments in the javascript that doesn’t have to happen (everybit counts). This reduced my load time from about 4 seconds to just over 2 seconds.
Speeding up HW Accelerated Accordion (Part 2)
Now, if you’re not worried about Android, or can do separate compiles for iOS and other platforms (for instance, using PhoneGap rather than loading from a website, or if you can do platform dependent includes), then there’s a second speed boost you can pull off that’s more significant.
And I’ll make sure this is clear
THIS ONLY WORKS ON iOS AND BREAKS ANY NON-3D ACCELERATED WEBKIT PLATFORM. (There, that made me feel better.
First, do everything that’s described in part 1. Then…
Comment out:
// accordions = document.querySelectorAll(‘#’ + el + ‘ > div > div:last-child’); (Line 30)
// that.wrappers[i].style.webkitTransform = translateOpen + ’0,0′ + translateClose; (line 38)
/* for (i=0, l=accordions.length; i div and #accordion > div > div:last-child
Now load time for my complex page goes from just over 2 seconds to instant.
The translate3d bit is what breaks Android – no 3d transform for the webkit version. Sorry. However, if you’re compiling using PhoneGap or similar, you can always make two CSS files and just include the right one in each project, and use the non-3D transform for other platforms besides iOS.
Hope that helps anyone who’s ran into some slowdown before!
Oops – a piece got dropped.
/* for (i=0, l=accordions.length; i div and #accordion > div > div:last-child
Should read as lines 49 – 45 in accordion.js.
Looks like I missed a second piece in my description… sheesh.
In your CSS under #accordion > div and #accordion > div > div:last-child, add:
-webkit-transform = translate3d(0,0,0);
thank you Midnight for your contribution. I think I’ll update this script soon.
Hello
Is it possible to integrate an RSS feed to this script.
What is the method?
Hi,
As you mentioned in ‘Future Development’, it would be nice to open multiple panels. Do you plan it for a very close future ?
Here you have an absolute fan! Congratulation for all of your plugins, really GREAT!
Hi,any update on load the accordion with an opened panel?
Great work!
I’m also eager to see this functionality.
Thanks for this! I’m having one issue though
I’m using this accordion with JQTouch and everything works great if I put the code on the front/welcome div. However, if I put it in another div (JQTouch navigates to divs on one page), it only shows me the last header
Any ideas?
I’m hoping a good solution would be to put this in an external ajax file, but I’m too much of a n00b to go that direction right away. Thanks so much!
Vital request! I need the accordion to close after clicking a link. JQTouch navigates within sections of one page. If an accordion remains open, any time I navigate back to that page, the transition glitches. So, having the option of the accordion collapsing after a link is clicked would be amazing. Hope to hear back from you soon!
First: I really love your work!
But it seems like this accordion is partially broken on Android: if you open and close some of the elements it scrolls automatically down so you have to scroll up again