Show/Hide Content with CSS and JavaScript

Published May 5, 2008 by CSS Newbies.

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>
<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>

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!

196 Responses

  1. Dan (reply)

    Hi, Im having a slight problem, Ive used images that display “+more” and “-less” instead, but both the images are displayed before clicking “more” but only “less” is shown after clicking, until you click “less” to put it back to normal. Does anyone know where I’m going wrong? Thanks

  2. Chris (reply)

    I am trying to get multiple “show/hide” contents on the same page. Any ones after the first one just open the first content block. How do I get them to each open their own content block? Thanks!

      1. Sadiq (reply)

        I am trying to get multiple “show/hide” contents on the
        same page. Any ones after the first one just open the first content after clicking on any link. How can I make it to each open different content? Thanks!

      2. Angus (reply)

        Hi Chris – yes, how did you figure out renaming the divs so that the first block isn’t the only one to open? i’m struggling trying out various combinations without success… Would appreciate any help! Thanks – Angus

  3. Kristen (reply)

    Thank you thank you thank you. This was exactly! What I needed and I was having such a hard time finding! You are the best!

  4. NThaler (reply)

    Excellent. I like this a lot. I do wonder if it is possible to have this as multiple hidden texts.

    I will have a page something like this:

    Place 1

    Place 2

    Place 3

    All place will have different narratives on the place.

    Is this possible ?

  5. Virecta (reply)

    As for the accumulation of a debase, there is besides a venture of misuse of medical representatives of the imagination. Yes, nearly each companies now use the compartmentalization of doctors, principally a system of ABC or its Notwithstanding, a angelic. Hi Harpin –

  6. pirate appetizers (reply)

    For case in point, exercise routines like push-ups do the job the triceps, biceps, chest,
    back, shoulders and even the abs which provides you a plethora of muscle mass targets to do the job on. After all Cheech and Chong just go
    together, and it will be a great experience to see them share the stage once again. The basic
    nature of this festival is totally commercial and usually experience
    mass attendance with great pomp and show.

  7. andro (reply)

    i need help with this, i have set this up with some changes. but what i get is a reverse i visit the
    article its fully loaded and when i click show article the article is then hidden. I am using
    the genesis frame work with Eleven40 Pro theme any help or guidance would me great.

    this is my edit


    var hidden = false;
    $(‘.read-more’).click(function() {
    if (hidden) {
    hidden = false;
    } else {
    hidden = true;


    .read-more {
    cursor: pointer;
    display: block;
    text-align: center;

    #moreInfo {
    display: none;

    text wrap——

    click here to show article

    i then wrap the hidden content with this…
    content goes here

  8. blah (reply)

    Nice post. I learn something new and challenging on sites I stumbleupon everyday.
    It’s always useful to read articles from other writers and practice a little something from their websites.

  9. imgur (reply)

    Drupal is one of these effective software packages that
    helps people and businesses publish content on their websites.
    You will also need to delegate your domain name to the hosting
    space, details on this are provided by your
    hosting provider. The laws have been changing and many
    portals that offer services are finding it harder and harder to
    get their word out there.

  10. Andreas (reply)

    Great post, thank you! Will this technique also prevent the browser from downloading the hidden content until shown? I have sort of a blog page in my website, and it is filling up with pictures loading all at once. Thanks!

  11. Max Smith (reply)

    Great article. I’m trying to set up something like this on my website and this article really helped me figure it out. Javascript is something entirely new to me and this site will surely be considered an asset for me in the future!


  12. Pingback: Gudrun Camastro

  13. Pingback: Creating an Intuitive and Attractive Design for Your WordPress Blog - Risk Fraud

  14. Pingback: Creating an Intuitive and Attractive Design for Your WordPress Blog - WP Mayor

Leave a Reply

Your email address will not be published. Required fields are marked *