Show/Hide Content with CSS and JavaScript

There are plenty of reasons why you might feel the urge to wax verbose on your website’s front page: to prevent your users from having to click through to a new page to find your information, to avoid having to reload the page, or even to improve your front page’s SEO. But just because your front page is text-heavy doesn’t mean it all needs to be visible at once.

Today’s tutorial will show you how to hide away extra bits of content using CSS and JavaScript, to be revealed at the click of a button. This is a great technique, because displaying the additional content doesn’t require a refresh or navigation to a new page and all your content is still visible to search engine bots that don’t pay any attention to CSS or JavaScript.

We’ll start with structuring our XHTML appropriately:

<p>...This is all visible content...
<a href="#" id="example-show" class="showLink"
onclick="showHide('example');return false;">See more.</a>
</p>
<div id="example" class="more">
	<p>...This content is hidden by default...</p>
	<p><a href="#" id="example-hide" class="hideLink"
	onclick="showHide('example');return false;">Hide this content.</a></p>
</div>

There are three things of importance here: the “show” anchor, the “hide” anchor, and our “hidden” div. Each has been given an ID and a class. The IDs are used by our JavaScript to locate and style the items appropriately. I’m then using the classes to set our “default” CSS. Technically you could just use the IDs the set that CSS as well, but if you wanted more than one hidden section on your page, that could get messy.

You’ll notice in the code above that all of our IDs are fairly similar. This is a trick I’m using to simplify our JavaScript, as you’ll see later on down the road, so I suggest doing something similar. The class names have no relationship to the JavaScript whatsoever, and could really be whatever you wanted them to be.

It’s also important to note that we’re calling our JavaScript using the “onclick” call, and passing it the name of our hidden div. Our JavaScript will use that single variable to do the rest of the work.

Now that we have our XHTML in place, let’s put together our default CSS:

.more {
	display: none;
	border-top: 1px solid #666;
	border-bottom: 1px solid #666; }
a.showLink, a.hideLink {
	text-decoration: none;
	color: #36f;
	padding-left: 8px;
	background: transparent url('down.gif') no-repeat left; }
a.hideLink {
	background: transparent url('up.gif') no-repeat left; }
a.showLink:hover, a.hideLink:hover {
	border-bottom: 1px dotted #36f; }

I’m technically doing far more styling than is necessary here, mostly for aesthetic purposes. The only truly important style is the “display: none;” rule on our .more class. This hides our extra content by default. The rest of the CSS simply adds a border to our div (the border is hidden by the display rule, but becomes visible later) and fancied up our show/hide anchors by putting down/up arrows next to them and replacing the standard underline with a dotted border. You could style these yourself however you like, and everything would still work just fine.

Next comes the JavaScript, which looks far more complicated than it is:

function showHide(shID) {
	if (document.getElementById(shID)) {
		if (document.getElementById(shID+'-show').style.display != 'none') {
			document.getElementById(shID+'-show').style.display = 'none';
			document.getElementById(shID).style.display = 'block';
		}
		else {
			document.getElementById(shID+'-show').style.display = 'inline';
			document.getElementById(shID).style.display = 'none';
		}
	}
}

Our JavaScript is doing four things here:

  1. It checks to see if it can find an element with an ID that matches the variable we passed it.
  2. If so, it checks to see if our “show” link is visible (this is where the ID naming convention starts to matter).
  3. If the “show” link is visible, that means our content is still hidden. The JavaScript then hides the link and displays our hidden content.
  4. If the “show” link is hidden, that means our extra content is currently visible. So it just reverses course, displaying our link again and hiding our extra content.

And that’s it! You can see a working example in action here.

Our job has been made much simpler by a few tricksy tricks. First off, we’re using the same function to show and hide our content, which saves us a bit of coding time. Our function simply checks on the state of things: if things are hidden, it shows them, and vice-versa.

Second, by using a defined schema for our element IDs (“example,” “example-show,” and “example-hide,” in our example above), we only need to pass our JavaScript a single variable. It then uses that variable to find all of our other elements and style them appropriately.

And finally, we put our “hide this content” anchor inside the hidden div. This means that we never have to set its display property: it’s hidden when the container is hidden, and visible when the container is. That saves us two lines of JavaScript and at least one line of CSS.

This technique could be used in loads of situations. Say for example that you have a Wordpress blog and the front page shows excerpts instead of the full article. You could use this technique to have the whole article on the front page for the search engines to find, visible to your users at the click of a button. Or maybe you have a complex form that could use some detailed in-page explanation, but you don’t always want the help content visible, eating up real estate when some users already know what to do. Or… well, anything, really. Let me know if you come up with any creative uses!

25 Comments

  1. On July 09, 2008
    11:43PM

    Shane said:

    I have put this code in place on the homepage of my website with brilliant results. I am using it to help prevent users from getting overwhlemed with too many options when they first land on the page, yet still providing all of the options that may be wanted.

    Check it out in action here: http://www.surebetbookies.com/

    Thanks so much for this great code!

  2. may said:

    Thnx for the codes but I would like to learn how to use this system for more than one content in our web sites. Because when I tried to put the codes inside of more than one content only one of them worked. Thnx

  3. xdf said:

    Thanks a lot!
    working great (:

  4. Danh ba web 2.0 said:

    Thanks you very much !

  5. Randall said:

    this code works great!
    but is there a way to show only one div at a time?

    thanks

  6. alexandre said:

    What if I desire to use the same link to hide/show the hidden div?

  7. alexandre said:

    May,

    If u want to use more than one, u must change the “exemple” word for another. in each hidden div u must use different names at the hidden div and it’s link.

  8. Reece said:

    Rob,

    That code is excellently simply but can you modify it in order to create a slide function in which the content slides to show and hide?

    Can you help modify the code or do you know of any good tutorials like yours to achieve this.

    Reece

  9. pinky said:

    Thanks for this code Rob – I managed to install and get it working with minimal hassle to hide/show tracklists for mixes so folk can download and listen without seeing the tracklist should they so wish.

  10. Jens said:

    Hey!
    This is really a great solution, and I can’t wait to put it on my page! I’m experimenting with it right now, but I have a question:

    If I put at header over the expand-link, a h2-tag for instance, the hidden content reveals it self but jumps down maybe 10 pixels or so. If I on the other hand don’t put a headline over it, it doesn’t.

    I would really like to have a headline over it, and the problem is that I have done the same customization as Shane who wrote the first comment up here did, that the hide-link shows up where the show-link was. The problem is that when the content jumps, also the link jumps, which doesn’t look to good in my opinion. You can check out what I mean at the bottom of this page: http://jensfilipsson.com/spelningar/

    I have left out the 2006 headline so you can see what I mean!

    Any suggestions?

  11. Jens said:

    Hey again,
    I had to take away the example on my page, so for now I’m just leaving the headers out. Maybe you still have an idea on why this happens?

    Happy new year!

    // Jens.

  12. Dan said:

    I’m not a programmer and know very little of javascript. That being said, I modified the code to work with just one link if so desired
    function showHide(shID) {
    if (document.getElementById(shID)) {
    if (document.getElementById(shID).style.display != ‘block’) {
    document.getElementById(shID).style.display = ‘block’;
    }
    else {
    document.getElementById(shID).style.display = ‘none’;
    }
    }
    }
    Instead of looking to see if the link is hidden or not, it simply looks to see if the text is. It works for me, but if there’s something wrong with functionality or programming, I apologize and please let me know. And as stated above, if you want multiple instances of this function, all you need is to label each section with a different id.

  13. -= Cara =- said:

    Thank you very much! I used your approach in one of my sights.

  14. Phil said:

    In response to Dan’s modification…

    This is my first time working with javascript, so I’m learning as I go.

    Thanks for editing the script. It is almost what I’m looking for. Do you know how to modify it further in order to hide the div when you click anywhere outside the div’s location.

    I’m trying to make a few different lists of links appear (in the same space) when you click on the link for the specific list. With the current method, the user has to hide the list before clicking the next link, or the lists appear one after the other until they are manually hidden. Make sense?

    I can supply the code or publish the site temporarily if my explanation is difficult to understand.

    –Phil

  15. On March 04, 2009
    9:06AM

    Allen said:

    Great script. I’ve been looking for something that would do this effect with not a lot of code. Great job!!!

  16. On April 02, 2009
    5:22AM

    Craig Burtenshaw said:

    This is great.

    I was just wondering one thing. If you put content below the box, when you expand the box the content below shifts down.

    I want to have it so the box expands above any content below.

    I know it has something to do with z-index. I have been playing with it but can’t work out how.

    Any ideas?

  17. On April 02, 2009
    8:25AM

    Rob Glazebrook said:

    Hi Craig,

    If you want z-index to work, you’ll need to give the “more” content a position of absolute. Z-index only works with absolutely positioned elements. However, if you just give it an absolute position and don’t specify a new position for the box, it should stay in its original location (though I haven’t tested that).

  18. On April 03, 2009
    9:32AM

    R Barrera said:

    Splendid script … thanks.

  19. On April 04, 2009
    3:26AM

    Craig Burtenshaw said:

    Thanks Rob,

    That’s what I was missing; absolute positioning. I had only just worked that out after some crawling the internet when you replied and confirmed it.

    Although while I was searching;

    Jquery is very popular and I like the animations it can do and there are lot’s of app’s out there that are ubiquitous now. I wanted it to animate when opening. I know nothing about Javascript! But after a bit of reading and some playing around I got it to work.

    I have mocked up a couple of pages for both if you or anyone wants to use it your welcome. It’s probably been done before, but I couldn’t find it when looking for it. So I was just happy I managed to get it working the way I wanted.

  20. On April 22, 2009
    11:01PM

    Ernest Kwan said:

    Hi there, I have set this up on multiple items on one page. I was wondering, is there to make it so that if say I click on List 1 and it shows the rows, then I go to the List 2, and when I click on show, it will automatically hide the List 1? Thanks!

  21. On June 08, 2009
    1:10PM

    Nicole Rankin said:

    Thanks so much for the script! It has helped this newbie fix her website!

  22. Wono Kairun said:

    Thanks you very much !

  23. Ollie said:

    If u want to use more than one show/hide on your page, you must replace the “exemple” word for some thing else. Each hidden div must have different ID names. This also applies to the example-show and example-hide.

    Example for second div: ( I also changed it so the title question is the trigger and close.)

    How much does it cost to create an account?

    How much does it cost to create an account?
    It’s free

    Hope this helps someone if they need it.

    Great file otherwise.

  24. led strips said:

    Splendid script … thanks.

  25. JENNY said:

    Thank you so much!

2 Responses Elsewhere

  1. On May 06, 2008
    5:07PM

    Управление видимостью содержимого с помощью CSS и Javascript | АяксЛайн.ру said:

    [...] CSSNewbies. Категория: CSS, JavaScriptАвтор: Spider Дата: 6 Май 2008 Время: [...]

  2. On May 08, 2008
    5:03AM

    Mohamed Jama » Blog Archive » Show/Hide Content with CSS and JavaScript said:

    [...] anyhow this is how to do it lightwave!! [...]

Leave a Comment