Flashy FAQs Using MooTools Sliders

By  on  

I often qualify a great website by one that pay attention to detail and makes all of the "little things" seem as though much time was spent on them. Let's face it -- FAQs are as boring as they come. That is, until you go the extra mile and use MooTools sliders.

Step 1: The XHTML

<div class="question" rel="a1-1">Question 1</div>
<div class="answer" id="a1-1">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla nunc justo, lacinia eu, elementum nec, faucibus blandit, massa. Pellentesque nec leo in urna accumsan sodales. Proin nec ligula. Vivamus vestibulum vestibulum neque. Mauris pede. Vivamus ac tortor id mauris hendrerit tincidunt.</div>
<div class="question" rel="a1-2">Question 2</div>
<div class="answer" id="a1-2">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla nunc justo, lacinia eu, elementum nec, faucibus blandit, massa. Pellentesque nec leo in urna accumsan sodales. Proin nec ligula. Vivamus vestibulum vestibulum neque. Mauris pede. Vivamus ac tortor id mauris hendrerit tincidunt.</div>
<div class="question" rel="a1-3">Question 3</div>
<div class="answer" id="a1-3">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla nunc justo, lacinia eu, elementum nec, faucibus blandit, massa. Pellentesque nec leo in urna accumsan sodales. Proin nec ligula. Vivamus vestibulum vestibulum neque. Mauris pede. Vivamus ac tortor id mauris hendrerit tincidunt.</div>

Predictably, I add a question class to every question, and an answer class to every answer DIV. Note, however, the rel attribute. The question's rel attribute matches the answer's ID element.

Step 2: The CSS

h2						{ margin:0 0 8px 0; }
.answer				{ line-height:18px; padding:0 0 20px 30px; }
.question			{ font-weight:bold; cursor:pointer; line-height:25px; padding:4px 30px; background:url(https://davidwalsh.name/demo/help.gif) 2px 7px no-repeat; }
.question:hover	{ background-color:lightblue; }

Nothing special here. I used a pointer cursor for the question's container though.

Step 3: The MooTools JavaScript

//once the dom is ready
window.addEvent('domready', function() {
	//hide all answers
	$$('.answer').each(function(el) {
		el.set('display','none');
	});
	//for every question div
	$$('.question').each(function(el) {
		//create a slider
		var slyder = new Fx.Slide(el.get('rel')).hide();
		//click event
		el.addEvent('click', function(e) {
			//toggle!
			e = new Event(e); slyder.toggle(); e.stop();
		});
	});
	//"show" all answers
	$$('.answer').each(function(el) {
		el.set('display','block');
	});
});

Once the DOM is ready I hide all answer DIVs. Why didn't I just do this in the CSS? Because if Moo didn't load correctly or the user didn't have JavaScript enabled, I don't want the answers hidden on the page.

Now that the answers are hidden, I create a slider for each question. This is where it's important that the question's rel matches the answer's id. We then add a click event to the question to toggle (open or close) the answer DIV.

Lastly, we "show" (in CSS) each answer DIV.

Recent Features

  • By
    5 More HTML5 APIs You Didn&#8217;t Know Existed

    The HTML5 revolution has provided us some awesome JavaScript and HTML APIs.  Some are APIs we knew we've needed for years, others are cutting edge mobile and desktop helpers.  Regardless of API strength or purpose, anything to help us better do our job is a...

  • By
    Responsive and Infinitely Scalable JS Animations

    Back in late 2012 it was not easy to find open source projects using requestAnimationFrame() - this is the hook that allows Javascript code to synchronize with a web browser's native paint loop. Animations using this method can run at 60 fps and deliver fantastic...

Incredible Demos

  • By
    Animated AJAX Record Deletion Using MooTools

    I'm a huge fan of WordPress' method of individual article deletion. You click the delete link, the menu item animates red, and the item disappears. Here's how to achieve that functionality with MooTools JavaScript. The PHP - Content & Header The following snippet goes at the...

  • By
    Pure CSS Slide Up and Slide Down

    If I can avoid using JavaScript for element animations, I'm incredibly happy and driven to do so.  They're more efficient, don't require a JavaScript framework to manage steps, and they're more elegant.  One effect that is difficult to nail down with pure CSS is sliding up...

Discussion

  1. I’ve had this discussion prior in regards to FAQs, accordions and real world scenarios, and it’s broken down like this:

    It doesn’t work very well (in the user perspective). I seldom see FAQs that have short, succinct answers – there’s always one that takes up too much room, and the scrolling gets annoying (especially when there are multiple “answers” like this).

    I’ll try to find an example of what I think qualifies as “good” stylized FAQs.

  2. David

    Two things i think that are improvements

    – developing : instead of using rel and id to identify the question-answer pair you could use a dl list where in the dt element is the question and in the dd element the answer. if you don’t want to use the dl tags you could use a hx tag for the question and a div or p tag for the answer. Let javascript identify the next element when clicking on or hovering over the question

    – visual : instead of clicking you could use hovering over the answer as a trigger. It is easier on the clicking finger.

  3. @David: I wouldn’t recommend using hover for the effect — I would see that getting really annoying. I used DIVs because they’re highly configurable and it’s something everyone uses already. Thank you for posting!

  4. I am going to implement this on one of my sites right away. Great timing! :)

  5. David

    True it would get annoying if the hover effect kicks in when the cursor enters the question area. If you work with a few seconds delay I think it would not get annoying.

    I think you are adding more than necessary using divs. The class, id and rel attributes fatten up html only to add some javascript effect.

  6. Adam

    Might also note that the js is using MooTools 1.2 (beta). 1.1 doesn’t seem to work – at least for me.

  7. @Adam: Correct, this is Moo 1.2. To make it work in 1.1, you simply need to change “el.set” to “el.setStyle” and “el.get” to “el.getAttribute”

  8. One thing that drives me crazy is that, as far as I can tell, you can’t use block-level elements inside those divs that you’re sliding. I’ve been working on something like this for a site where the sliding content includes <ul> and <p> tags… in IE 7, it refuses to slide!

    It was easy enough to work around the p tags but I’m still trying to find a good alternative to the uls… by setting their style to display: inline I’m able to get this to work in IE 7 but the formatting in that case isn’t desirable.

    So, let this be a warning for people… afaik, you may not be able to use <ul>, <p>, and other block-level tags in your sliders if you want them to work in IE!

  9. EVula

    I recently did up an FAQ using the accordion trick. In my opinion, in works better (though this is an excellent tutorial; please don’t think I’m slamming the lesson, David!).

    Specifically, I handled it as a definition list, as different-David mentioned; that allows for the multiple block-level tags that Mike mentions above (just a single dd tag with however many paragraph tags as you need; the script borked on multiple dd tags in the same grouping), and is very forgiving of very lengthy answers (which partly addresses keif’s concerns). And because the dt tag is block-level itself, it greatly increases the clicking area without having to manually change its display or width or anything like that.

    It also degrades very, very gracefully if the user turns off JavaScript.

  10. steffy

    Greetings David,

    I’m trying to use your dam cool script for a faq part too, it works very good but since some of the answers are quite long I would like to add a close button at the end of the slided part. I have tried, without success to implement some stuff in the js like a

    $('faq_close').addEvent('click', function(e){
            e.stop();
            askaproSlide.slideOut();
        });

    where I put a close link within a span with the class of faq_close

    but no chance

    would you have a tip for a dummy like me, thank you in advance

    Steffy

  11. Matt

    I have a quick question… excuse me if this is at a very noobie level but I just wanted to know what the double $$ <– means? or what is it telling it to do?

    Also where did you get the el in this section –> .each(function(el) is that something you just made up to give it a unique identifier?

    Thanks!

  12. Matt

    Guys,

    I’m having trouble with the questions being hidden upon entering the page in IE… works fine in firefox. Any suggestions?

    Is anyone having this same problem?

  13. Matt

    Okay Okay… I found out what the $$ does and means… please excuse that question.

    But still having trouble with IE7 and the faq’s working correctly.

  14. This is great, thanks!

    One question though — the “slide” action is really jerky and jumpy in Firefox, but nice and smooth in IE. Any ideas?

  15. Matt

    still having trouble with IE7 and the faq’s working correctly.

  16. jay

    Hi…

    thanks for your brillant snippets, but this code is not xhtml. you are not allowed to set a
    “rel” into a div tag. “rel” is only allowed for

    Jay

  17. Alex

    Hi all.
    This is just what I’m looking for, but it doesn’t seem to work with the mootools 1.2.3 version I’m using (including the v1.2.3-more.js file). Has there been a small change in syntax since the version referenced on this page?

    Cheers!

  18. Hi,
    I’ve added an faq to this site, not from your tutorial but from the mootools website, and everything works fine except the link to an outside website that I have in one of the answers. Any idea how this can be resolved?

    Your help would be much appreciated.

    Regards

    Paul

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!