jQuery Snippet: Slideout Tab
A day or so ago someone asked me how to make one of these, so instead of just telling them I thought I’d post it here as a snippet of code that everyone can use. What you use it for is entirely up to you, but most people use it for social networking such as Twitter.
Before we get started here is a small demo to show how the slide out tab works. Obviously you would fill it with something a lot more useful than I have, but it’s just to show you how it could look and that it does actually work.
Now that you’ve seen the demo let’s get started. Here we go.
1 2 3 4 5 6 7 |
$(function() { $('#slideout').hover(function() { $(this).animate({left:'0px'}, {queue:false, duration: 500}); }, function() { $(this).animate({left:'-280px'}, {queue:false, duration: 500}); }); }); |
However that might get a little annoying for the user as it will slide out every time they hover their mouse over it. It would probably be better to slide on click. So to do that you would just need to change hover to toggle. However since jQuery 1.8 the toggle event (not method) was deprecated & removed as of 1.9 so it is no longer that easy. However there is some snazzy (did I really just use that word?) code that can help replicated it. Instead of making your whole div clickable though you’ll want to make a box and float or position the box that will be clickable, or the user will not be able to interact with the box once it slides out. Your HTML could look something like this.
1 2 3 4 5 6 7 8 |
<div id="slideout"> <div id="slidecontent"> Your Content! </div> <div id="clickme"> </div> </div> |
With some CSS like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#slideout { background:#666; position:absolute; width:300px; height:80px; top:45%; left:-280px; } #clickme { float:right; height:80px; width:20px; background:#ff0000; } #slidecontent { float:left; } |
Now because of the toggle event being removed the jQuery gets a little more trickier than normal.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$('#slideClick').click(function() { var it = $(this).data('it') || 1; switch ( it ) { case 1 : $(this).parent().animate({left:'0px'}, {queue:false, duration: 500}); break; case 2 : $(this).parent().animate({left:'-290px'}, {queue: false, duration: 500}); break; } it++; if(it > 2) it = 1; $(this).data('it', it); }) |
Basically what we are doing here is creating an iterator that is changed every time the button is clicked. This works because the value is stored on the element’s data object. We retrieve that value, or set it to 1 if it hasn’t been set yet. Then we use a switch to match the case. 1 is equivalent to show the tab, 2 is hide the tab. We increment the iterator, check it hasn’t gone over 2 & if it has reset it to 1, then save the value again. This process repeats each time the button is pressed & is a fairly nice way to replace the toggle (I think it is anyway). It can even be made into a jQuery function so you don’t have to keep writing it. I’ll leave that one as homework though. *wink*
Now I never claimed to be a great designer so my CSS is correct, but the coloring is awful. 😆 The point is that it works & you can spruce it up until you are happy with it. That’s it. Have fun. 🙂
If any regular readers are wondering, these little snippets are just so that the site isn’t left with no new posts for a long period of time. Sometimes I just don’t have any inspiration for new full tutorials, or I might not have enough time to write a massive post. So rather than have a huge gap between posts I’ve decided to post these little tips & snippets. I hope they help new readers & regulars alike.
57 Comments
Mouad
Hello Paul.
Please allow me to comment not on this specific topic, but on the overall design of your blog, its neatness and cleaness, very comfortable for the eye.
I would like to ask you, how do you make that image you use as a background stretch?
I noticed that you use the image named “box-bgr.gif” everywhere in your blog, in the sidebar, in the content area, in the “about the author”, in the related posts, and here in the comments area. Given that they all use the same one-size background (box-bgr.gif), what css did you use to make the image automatically stretch to fill the whole space horizontally and vertically?
I have been trying to do that for a long time, but to no avail !
I would be thankful if you tell me how
(btw, I tried to copy the css properties you assigned to the background here and apply them to the image on my blog, but that didnt help!).
Paul Robinson
Hi there Mouad,
Thank you for you kind comments about the design of my site. I wish I could say I designed it, but I didn’t. Artist & illustrator Lisa-Marie (who is a guest author here) did. However I think I can explain what it is you want to know. 😉
The image “box-bgr.gif” is a gradient image that is used in most (if not all) of the content boxes. The CSS is just:
the class
.box
is then used in all of the content boxes along with any other classes needed.The big background (behind the header) is just a fairly large compressed jpeg. It reaches about 493 pixels downward & then merges into the background color. The CSS looks like this:
I hope that has answered your question. If not, drop another comment with what it is I haven’t explained properly & I’ll see if I can get Lisa-Marie to come & drop a comment as she might be able the explain it a bit better. 😉
Mouad
Thank you very much for replying.
You surely noticed, that almost every element in your blog uses the box-bgr.gif file as a background. Yet, you do surely notice that the same image is displayed perfectly in the “advertise here” box in the sidebar, and in the Archives box in the sidebar too, this, although they have different heights, and yet, the image is automatically strethced/expanded, not sure what you call it, to fill the whole space that the widget uses. That is my question, how do you make it automatically stretch ? I am sure it is not a different image suited for each box. I can see it is the same image, and yet it is displayed differently to match the box it sets behind.
Please see this page of my blog, and browse down to the blue box which holds the social icons.
http://cinema.al-rasid.com/2010/02/19/understand_movie_rating/
This is the image I use as bg: (please highlight it to see its edge).
http://cinema.al-rasid.com/wp-content/themes/mobipress-theme/images/blue_white_bg.JPG
Notice that the background image is not fully displayed, it is displayed down till the box’s edge only, so if the height of the box happens to be bigger than the width of the image, there will be an empty space in the lower part of the box, after the image’s bottom limit.
I doubt you understood what I wrote 😀
in simple words, I want the background image to fit in every box or element I use it with, by autoamtically stretching.. just like Windows XP autmatically resizes the wallpaper you choose to fill the whole screen when you set it to “stretch” the wallpaper…
I really wish I clarified what I want
Paul Robinson
I understand what you mean now. It’s actually an illusion the image in the background is like yours, it is always a set height (239 pixels). The color of it is a gradient that is only slightly off the background color of the boxes anyway. This creates the illusion of it finishing at the right time for every box, it also helps that nearly all of the boxes it is used in are above 239 pixels in height meaning the image does merge into the background.
It currently isn’t possible to do what you are looking for with CSS without making another image… Well it is possible using CSS 3 but it won’t show in every browser, I believe only Safari 4(?) has support for the
background-size
property.There is a cheats way of doing it in most modern browsers by specifying the
min-height
property to be the height of your background image, but that just makes sure that the box is that height regardless of the content while still allowing it to increase in height. That’s as opposed to the height property which actually fixes an element to the height specified.I hope that helps & hasn’t just confused things further. In summary though I have just made sure that the gradient isn’t too high & that nearly all boxes are bigger than that height.
Mouad
Thank you. The min-height actually stretches the box itself, not the image, and not the box till it reaches the edge of the image.
I understand that there is no way to make a background stretch to fill the whole box, and to fit itself to it’s height?
This means I cannot use a normal background (not tileable one) to be the background of comments for instance, because comments might exceed the height of the image, and that will repeat the image vertically, revealing its edges, which will surely ruin the display..
Paul Robinson
Yes as I said using
min-height
is kind of a horrible cheats way of doing it & only applies in certain circumstances.There is a way, but it isn’t available in all the browsers on the web yet as it belongs to the CSS 3 spec.
That’s right, but you can use the gradient method as long as you try to make sure that the height of the gradient is not lower than that which will be the minimum height of the elements it will be used in.
That’s how my elements work, I know that no element the gradient is used in will be lower in height than 293 pixels. The background is also the same color as the bottom of the gradient & so it looks as if the image stretches when it doesn’t.
Mouad
I see. Thank you very much for the time you took to answer my queries.
Paul Robinson
No problem, hope I helped. 🙂
Man and Van Richmond
I don’t have enough knowledge about jquery but because of this kind of blogs.I’m learning it little by little. Thanks a lot.
Chicago Limousine Service
What a great information. I really thankful that I have landed here in this blog. There really lot of things I can learn here.
Website design
Hi Paul,
It is great that you have decided to post this information. I have save this one on my computer for future reference. Thanks a lot.
russell hrachovec
Hello: Thanks for your very helpful tutorial. I’ve used it to create a drop-down navigation for a new site i’m building. The only ‘issue’ is that, once the page loads, I have to click the yellow ‘menu’ button (my version of the #clickme div) twice to get the drawer to slide down.
Any thoughts about how this could be improved?
Thanks again for the great site.
russell hrachovec
Woops, I thought the site would be published in my comment. It is: http://testing003.compoundeyedesign.com
Thanks! Russell
Paul Robinson
Hi Russell,
It did publish the web address, it’s made so the hyperlink around your name goes to the address you enter. 😉
I think it’s because you have the top numbers around the wrong way. The first part of the toggle function should be 0px and the second -200px so that when you click the first time it opens, and the second time shuts.
Russell Hrachovec
Hi Paul:
Okay, I will try this again when I’m back at work (clocking off for the night) but thanks so much for getting back to me quickly. I’ll let you know how it goes. Much appreciated!
Cheers, R
Paul Robinson
No worries.
Let me know if you need any further help. 😉
Russell Hrachovec
Hey Paul:
Just wanted to say thanks. I took your advice, flipped the numbers around and it worked perfectly. Thank you very much! I hope your week goes well. Thanks again!
Take care, R
Paul Robinson
Not a problem Russell, glad it worked. 🙂
Matthew
Hi. Just wanted to add to the gratitude for your simple tab slider code. It’s the best I’ve found so far and I am also very new to JQuery.
Would it be a headache to add an Onload function so that, when the page loads, the tabs are already out?
As I say I am new to this but from what I am seeing, allowing the tabs to be open on page load shouldn’t be too difficult, should it?
Thanks for reading.
Paul Robinson
Hi Matthew,
You are right it isn’t that difficult. You can do it one of two ways. One is to reverse everything, so the first click in the jQuery slides it shut and the second opens it, then alter the CSS so it is visible when the page loads.
The other is to add:
after the toggle code. The only problem with this one is that it won’t trigger until (most) of the page has finished loading, but sometimes that is the desired effect, so I leave it up to you which to choose.
Hope that helps, let me know if you have any further questions.
Matthew
Thanks Paul! I couldn’t get the Javascript you posted to work but it was much easier to change the #slideout tag css “left” property to 0 as opposed to the previously negative DIV width value. My next aim is to allow the tab to slide in after a timeout. So, they are visibly open on page load but automatically close after a period of say 2000ms. Thanks again.
Paul Robinson
No problem. Not sure why the JS wouldn’t work, but glad the other way worked okay.
To do the delayed close you would need to use
setTimeout()
and the trigger code. Something like:Just remember to change
#clickme
to the id of the element you need to click to open or close the tab.Matthew
Thanks for the super fast responses 😉 Not having much luck with the JS. If it helps, here is the code I am using. The actual tab slider in question slides on hover. There are 2 sliders hence what you see in the code:
Matthew
Sorry, just to clarify that it is just the timeout function that isn’t working.
Matthew
Sorry, and the timeout function also doesn’t work here:
Paul Robinson
Ahh, I see what’s wrong.
The trigger code should be inside the:
but not inside the hover or toggle events. Inside those it will only trigger when the event is triggered rather than on DOM load as it should be.
Hope that makes sense.
Matthew
Thanks Paul.
I have tried it for events that slide on click and it does indeed work, but not on events that use hover for the tab to slide in or out. For some reason it’s just click biased…. Oh well.
Paul Robinson
Hmmm. I’m not sure if you can use the trigger command to trigger a hover event. I can’t see why you can’t, but I guess the fact it doesn’t seem to work answers that. Sorry. 🙁
Matthew
Sorted it out. It’s a mouseout event without an argument:
Paul Robinson
Awesome sauce. 🙂 Glad you figured it out. Must store that in my head somewhere so I don’t forget. I’ve always wondered how you trigger a hover event when trigger doesn’t work, lol.
Greg
I’ve been looking for this solution for 2 days. There are so many wrong ways to do this its shocking. And even when a correct way is presented, it’s not often done as well as you’ve done here, with clarity and simplicity, for all the non-super-hero coders out here trying to get by. You’ve done it right!
Paul Robinson
Hi Greg,
Thanks I’m glad you found my tutorial helpful. I’m always worried that my tutorials are sometimes too complicated so I’m glad to hear it is understandable.
Andrew Spackman
Is there a way to have the tab on the right hand side of the screen, when i change it to float right it works ok apart from when the content is off the screen you can scroll and view it, not really ideal. Is there a way around this. Very helpful blog though!!
Thanks
Andy
Paul Robinson
Hi Andrew,
I’m not sure if it would work since I’ve never thought about putting it on the right of the browser, but you could try positioning it fixed instead of absolute. That is if you haven’t tried that already.
Let me know if that doesn’t work & I’ll see if I can help you out some more.
Thanks.
Marc Oldham
Thanks for the great toot, it was very clear and easy to implement into a site that I am developing in WordPress.
I also wanted to place the tab on the right side of the browser and had the same issue as Andrew. I took your suggestion of using a fixed position instead of absolute and it fixed the scrolling issue.
Many thanks!
Paul Robinson
Hi Marc,
Thank you. It’s always nice to hear that my tutorials are understandable. 🙂
Glad that fixed the problem with trying to position the tab on the right hand side.
Thanks for visiting & have a great Christmas/Holiday season. 😉
Erica Gilbert
Is there a setTimein function so that the slideout tab only pops up after the user is on the site for a certain time? Also, could you show a demo version? I can’t seem to get it working after copying the code onto a separate page. Thanks ever so much!
Paul Robinson
Hi Erica,
The function I think you are after is
setTimeout()
it sets a function to run after a certain amount of time has elapsed. So for example:would trigger the function
mySuperFunction()
after 30 seconds, or 30,000 milliseconds since thesetTimeout()
function accepts it’s second parameter in milliseconds.I’ll see if I can get a demo up for you first thing tomorrow.
Paul Robinson
Erica,
Just a quick update to let you know I’ve added the demo to the top of the post. If you would like to set a timeout it might be something like this:
You would place that inside the main DOM ready block, but underneath the other code. It would trigger after 10 seconds of the page loading.
If you need any further help, please let me know & I’ll try to help out however I can.
Moe
Just Brilliant 🙂
So simple, yet powerfull.
Im very new to jquery & I have gained alot of nowledge with your script. THANK YOU.
However following ordinary logic Im trying to place the tab on the right side of the screen, I just turned every ‘left’ to ‘right’ and vice versa. I thought that would place my tab on the right side.
Am I missing something?
Moe
Hi Paul,
Got it working on the right side. But when placed on the right side of the screen, the horizontal scrollbar becomes visible & content of tab is viewable if one uses the scroll.
I tried with
overflow:hidden;
with no luck.
Is there a way to fix this without forcing the horizontal scrollbar to show?
Moe
GOT IT 😀
css > body
overflow-x: hidden;
Paul Robinson
Hi Moe,
Yep. That’s what I would have suggested but looks like you figured it out. Nice job. 🙂
Roy
Hi Paul
Love your tutorial, I was wondering is it possible to have some text on tab itself?
Thanks in advance
Paul Robinson
Hi,
Do you mean on the tab you click? If so you would just put the text inside the
.click-me
element.