I recently redesigned my business site, Monzilla Media. The new design features a clean and simple single-page, fixed-sidebar layout. Visitors use the various links in the fixed sidebar to quickly and automatically scroll through to any section. In the Portfolio section, each item contains a “Details” link that loads more content into the fixed sidebar. As the site is mostly static, I wanted this bit of functionality to really shine, and after much testing and tweaking, ended up with a cross-browser slide & fade technique for loading content via Ajax and jQuery.
How it works
This technique uses jQuery to load HTML/content into a target element, such as a <div>. The nifty part is how the content is loaded/replaced with a cool slide-open, fade-in effect as the user clicks the designated links. Here is the order of events:
- User clicks on one of the menu links
- The target
<div>slides open - HTML/content is loaded with a fade-in effect
- Optional: content is highlighted with color after fade-in
- User clicks on another menu link
- Target
<div>slides up and content fades out - Target
<div>slides open and new content is loaded with a fade-in effect - Optional: content is highlighted with color after fade-in
- User clicks another link, etc.
Here is a demo of this technique to see it action. Surprisingly, this functionality is achieved using a small slice of jQuery and an optional loading.gif file that’s displayed before content loads.
Quick Overview
This technique employs the following assets:
- JavaScript Library: jQuery
- jQuery Plugin: highlightFade (optional)
- A slice of jQuery code
- Some HTML/content to load
- A small animated
loading.gifimage (optional) - A slice of CSS for the loading image (optional)
The highlightFade plugin is optional and is used to highlight the ajax content after it fades into view. It’s a sizable script, but it really adds a nice effect that helps the user to better focus on the loaded content. Without that optional effect, this technique is accomplished using a few lines of jQuery. The CSS is also optional and is used to center the loading.gif. You can download all of the assets for this technique, or grab the code as it’s presented in the tutorial.
Step 1: jQuery
The first step is to add the JavaScript/jQuery to the <head> section:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="http://example.com/slide-fade-content/slide-fade-content.js"></script>
<script type="text/javascript">
$(document).ready(function(){
// Ajax Slide & Fade Content with jQuery @ http://perishablepress.com/slide-fade-content/
$('.more').live('click',function(){
var href = $(this).attr('href');
if ($('#ajax').is(':visible')) {
$('#ajax').css('display','block').animate({height:'1px'}).empty();
}
$('#ajax').css('display','block').animate({height:'200px'},function(){
$('#ajax').html('<img class="loader" src="http://example.com/slide-fade-content/loader.gif" alt="">');
$('#ajax').load('http://example.com/slide-fade-content/slide-fade-content.html #'+href,function(){
$('#ajax').hide().fadeIn().highlightFade({color:'rgb(253,253,175)'});
});
});
return true;
});
});
</script>
Code breakdown:
- Include jQuery Library
- Include highlightFade plugin (optional, edit file path as needed)
- When the web page is ready, execute the function upon click of any
.morelink - For each link click, store the
hrefattribute as a variable - If the target
<div>contains loaded content, slide shut and empty - For first clicked link, slide open the
#ajax<div>to200px(adjust as needed) - After sliding open, display
loading.gif(optional, edit file path as needed) - Load content from external HTML file using a nice fade-in effect (edit path as needed)
- After fading in, highlight the new content with a yellow background color (
rgb(253,253,175)=#fdfcad) (also optional) - Complete the function with
return trueto allow the#targetto appear in the URL
So to sum up, after including this code into your <head> section, edit the file path for the highlightFade plugin, the loading.gif image, and the HTML file. Also remember to adjust the height:'200px' value according to your design. Also, there are two optional items; here is how to remove/omit either of them:
- Omit the loading.gif file – remove the 12th line
- Omit the highlightFade plugin – remove the second line and “
.highlightFade({color:'rgb(253,253,175)'})” from the 14th line
One improvement I would like to make with this technique is to eliminate the need for the height calculation. I’ve tried using jQuery’s .slideUp/.slideDown functionality, but couldn’t get it to work. If you have any ideas for this, please share in the Comments.
Step 2: HTML
There are two things we need for the HTML. The first is the content that you want to load. For this tutorial, we’ll just use some boring old Lorem Ipsum text to keep things simple. In your blank HTML file, include the following markup:
<div id="load">
<div id="first-item">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</p>
</div>
<div id="second-item">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</p>
</div>
<div id="third-item">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.</p>
</div>
</div>
Each click menu link will load one of these content sections into the ajax <div> on your web page. You may add this <div> to the location in your page where you want the loaded content to appear:
<div id="ajax"></div>
The last thing we need to do for the HTML part of the tutorial is to include some links to trigger the loading of your new content. Here is a basic example to place anywhere in your web page:
<ul>
<li><a class="more" href="#first-item">First Item</a></li>
<li><a class="more" href="#second-item">Second Item</a></li>
<li><a class="more" href="#third-item">Third Item</a></li>
</ul>
These links each contain a more class, so when clicked, the script will use the href value to load the corresponding section of content from the external HTML file. So you can use any link(s) you want to trigger the loading of new content. Just slap a class="more" on there and make sure the href value matches the content’s id attribute in your content file.
Step 3: CSS + loading image
At this point, the slide-&-fade functionality should be working great. The last step is to upload the loading.gif file and style it with a little CSS:
<style type="text/css">
.loader { border: 0 none; float: left; clear: both; margin: 100px 0 0 200px; }
</style>
This style snippet attempts to position the loading image more toward the center of the ajax <div>. You may need to tweak the left margin (200px) depending on how wide the ajax <div> displays in your design.
Troubleshooting
Here are some things to check if the technique isn’t isn’t working:
- Double-check that the assets are in place
- Double-check the file paths to the different assets
- Make sure jQuery is included only once on the page
- Make sure jQuery is included before the slide/fade code
- Check for any interfering scripts or alternate JavaScript libraries
You may also want to check out the demo or my business site to see it working and maybe help pinpoint any issues.
Using the download pack
The download pack for this tutorial should work great out of the box. Just download, unzip, and edit/modify as-needed to fit your design.
Ajax Slide/Fade Content - version 1.0 - 12KB ZIP
Wrap Up
Once again, here are the resource links for this tutorial:
- Try the demo for this tutorial
- Try the technique on live website
- Download all files for this tutorial
As always, questions, concerns, and suggestions are welcome in the comments!
35 Responses
Chris – March 5, 2011 •
Hi there Jeff
Really like your work and I’m always checking in. i couldn’t find a way to contact you directly, but i have a question over a previous article of yours.
http://perishablepress.com/press/2008/08/04/two-column-horizontal-sequence-wordpress-post-order/
i have used the pure css example listed here. You can see it at snowmenu.com. My question relates to the lack of a gap between my left and right hand columns. Would you know how to add a small gap or perhaps even a verticle line to distinguish the difference. Any help gratefully received. As i said, apologies this is the incorrect post but comments were closed on the original. Cheers. Chris
Mohammad AbuShady – March 6, 2011 •
I like the idea, I’ve done something like this before but i kinda prefer that the slideUp or slideDown is put as a callback function for the ajax call, so it doesn’t do the sliding until the content is ready to be shown, so the scenario becomes
click
slideUp
call ajax and wait for response
when ready slide down
fade in the content
but that’s just me
Daniel – March 7, 2011 •
Mmh.. looks great, but what about accessibility?
I took a look with links (a text-based browser, lynx on windows.. dont know about mac ;) and the only visibile things are the menu links… and they all doesnt work ;)
Is a choice or an oversight?
Mohammad AbuShady – March 7, 2011 •
I don’t think lynx supports javascript does it?
and in an easy way you can add html links to new pages.
Put a normal href on each and add ‘return false’ at the end of the javascript, by this way browsers that support javascript will stop the redirecting by the javascript, and those who dont will be redirected to the new link that is supposed to be also a permalink to the content it self, just an idea i know.
Mohammad AbuShady – March 7, 2011
sry.. didn’t know that the comment box parces html tags, i meant put ‘href’ on each ‘a’ tag, that’s why the rest of the comment turned into a link
daniel – March 7, 2011
youre right – my comment was just a reminder, too often i see websites doing a big usage (maybe overkill) for ajax request, without give a damn about accessibility.
Remember that accessibility doesnt mean only to those whom have js disabled, but even to people that blinded, for example
Manny – March 7, 2011 •
Cool tutorial, is there a way of highlighting the text so that the user knows where there are. nice one thanks for sharing.
Mohammad AbuShady – March 22, 2011 •
What do you mean by highlighting the text? which text?
Lori – March 8, 2011 •
Thanks for this very nice tutorial.
Skye – March 21, 2011 •
no commenting on PHP Tip: Encode & Decode Data URLs?
Jeff Starr – March 21, 2011 •
Yeah that should’ve been an article. I post code snippets in a “Code” category without comments enabled. That post started as a simple snippet but soon grew into a full post. Feel free to drop me a line if you have something to add. I can always update the post with any critical information.
ascetix – March 26, 2011
Your “simple snippet” made me thinking. Then I’ve rearranged my webpage… :) I’m very grateful that you wrote it.
One thing took me a lot of time and thinking- how to put one icon in several places. On my page I’ve put an icon with envelope (directing to contact form) in approx 25 places… When I started with approach
'img src="data:image/png;base64,', I calculated that my page is growing more and more and probably I should go back with normal img usage.In this moment I started to work with CSS. I made a style that use base64 image as a background, and then in every place I need to put my envelope- I write ‘& nbsp;’ with that class. I used ‘padding’ to make place for image. Image is on the left of non-breaking space.
I’m not sure if it’s a good and clean method?
anyway- my webpage and CSS goes through validators :), so I believe it works not only on my PC (XP+Ubuntu, FF+IE).
On the other hand- afaik, Base64 works with IE8, on earlier browsers one should think about ‘workarounds’- this is what I’ve read about it. Is it true?
Julian – March 31, 2011 •
i prefer using JQuery Cycle :-)
Joseph – April 8, 2011 •
Very cool tutorial! Any way to have a link to close/collapse the open/expanded items so that all of them return to their original closed/collapsed state?
Mohammad AbuShady – April 9, 2011 •
well, if you want to use the exact same line that was used in demo code use this
$('#ajax').css('display','block').animate({height:'1px'}).empty();you can put it on a link by using
onclick=''or somethingmysty – April 18, 2011 •
thank you it’s a nice tut!
i have a question, i try to put a active navigation like :
<a href="#first-item" rel="nofollow">First Item</a>any idea ?
mysty – April 19, 2011 •
is it possible to know which menu is active via jquery ?
<li class="current"><a class="more" href="#first-item" rel="nofollow">First Item</a></li>Tky
Julian – April 22, 2011 •
i think it can be implemented in easier way using jQuery cycle plugin
Jason – April 27, 2012 •
How would I go about linking to the slide content from another page? I have a link on the home that will link to our showcase but I want to target a specific div# to load.
<a href="/showcase.html#Second-Item" rel="nofollow">Link to second item on showcase page</a>using fade-slide-content.