Collapsing HTML at Runtime

This technique uses a combination of Javascript and CSS to selectively hide or show a block of text. The javascript file includes several variants useful for different types of expansion.

Examples:

Expansion With Image: Why did the chicken cross the road? click to expand/collapse section
Expansion With Text: Why was six afraid of seven? Show Answer...

Only Hide Overflow With Image:
click to expand/collapse section There once was a man from Nantucket
Who kept all his cash in a bucket.
But his daughter, named Nan,
Ran away with a man
And as for the bucket, Nantucket.

There was an Old Man in a tree,
Who was horribly bored by a Bee;
When they said, 'Does it buzz?'
He replied, 'Yes, it does!'
'It's a regular brute of a Bee!'
Only Hide Overflow With Text: Show More...
One, two, buckle my shoe
Three, four, shut the door
Five, six, pick up sticks
Seven, eight, lay them straight
Nine, ten, a big fat hen
Eleven, twelve, dig and delve
Thirteen, fourteen, maids a'courting
Fifteen, sixteen, maids in the kitchen
Seventeen, eighteen, maids a'waiting
Nineteen, twenty, my platter's empty

Usage:

  1. Save expander.js, expand.gif (), and collapse.gif () in the folder with your html page.

    expander.js contents:

    
    // --------------------- Variables --------------------------
    // Default values for image names of the images/text to expand and collapse the hidden text.
    // ----------------------------------------------------------
    var expandImage = "expand.gif"; 
    var collapseImage = "collapse.gif"; 
    var defaultExpandText = "Show More...";
    var defaultCollapseText = "Show Less....";
    
    // ---------------- setDefaultExpanderImages(...) ------------------
    // Call this method to change the names of the images used for the "expand" and "collapse" buttons
    // The parameters should be the actual image URLS for the images, which may be relative or absolute
    // ----------------------------------------------------------
    function setDefaultExpanderImages(expandImgName, collapseImgName) {
        expandImage = expandImgName;
    		collapseImage = collapseImgName;
    }
    
    // ---------------- setDefaultExpanderText(...) ------------------
    // Call this method to change the strings used for the "expand" and "collapse" links
    // expandText = "Expand" or "Show More" or "Reveal Answer" etc.
    // collapseText = "Hide" or "Show Less" or "Hide Answer" etc.
    // ----------------------------------------------------------
    function setDefaultExpanderText(expandText, collapseText) {
        defaultExpandText = expandText;
    		defaultCollapseText = collapseText;
    }
    
    // ------------------- toggleBlock(...) ---------------------
    // Method to Collapse/Expand a block of text, using default image names
    // hiddenDivId - the ID of div or span to show/hide
    // expander - pass in a reference to the image tag for the expender
    //     usually this will just be "this" (without any quotes)
    // ----------------------------------------------------------
    //function toggleBlockImage (hiddenDivId, expander) {
    //	alert(collapseImage);
    //		toggleBlockImage(hiddenDivId, expander, expandImage, collapseImage);
    //}
    
    // ------------------- toggleBlockImage(...) ---------------------
    // Method to Collapse/Expand a block of text, using custom image names
    // hiddenDivId - the ID of div or span to show/hide
    // expander - pass in a reference to the image tag for the expender
    //     usually this will just be "this" (without any quotes)
    // expandImageName & collapseImageName are optional parameters
    // ----------------------------------------------------------
    function toggleBlockImage (hiddenDivId, expander, expandImageName, collapseImageName) {
        if (document.getElementById) {
            if (document.getElementById(hiddenDivId).style.display == "none") {
                document.getElementById(hiddenDivId).style.display = "";
    						expander.src = (collapseImageName)?collapseImageName:collapseImage;
            } else {
                document.getElementById(hiddenDivId).style.display = "none";
                expander.src = (expandImageName)?expandImageName:expandImage;
            } 
        }
    }
    
    
    // ----------------- toggleBlockText(...) -------------------
    // Method to show or hide a paragraph or other block or span of text. 
    // Use this version for text links to show/hide, and custom link text
    // Parameters:
    // hiddenDivId - the ID attribute of div to show or hide
    // expander - pass in a reference to the image tag for the expender
    //     usually this will just be "this" (without any quotes)
    // expandText - the text to show when the block of text is hidden (to show the text) OPTIONAL
    // collapseText - the text to show when the block of text is showing (to hide the text) OPTIONAL
    // ----------------------------------------------------------
    function toggleBlockText (hiddenDivId, expander, expandText, collapseText) {
        if (document.getElementById) {
            if (document.getElementById(hiddenDivId).style.display == "none") {
                document.getElementById(hiddenDivId).style.display = "";
    						expander.innerHTML = collapseText?collapseText:defaultCollapseText;
            } else {
                document.getElementById(hiddenDivId).style.display = "none";
    						expander.innerHTML = expandText?expandText:defaultExpandText;
            }  
        }
    }
    
    // ----------------------------------------------------------
    // another different way to toggle how much is shown...scrollbars
    // collapseHeight - eg: "200px"
    // ----------------------------------------------------------
    function toggleOverflowImage (hiddenDivId, expander, expandImageName, collapseImageName, collapseHeight) {
        if (document.getElementById) {
            if (document.getElementById(hiddenDivId).style.overflow == "scroll") {
                document.getElementById(hiddenDivId).style.overflow = "auto";
    						document.getElementById(hiddenDivId).style.height = "";
    						expander.src = (collapseImageName)?collapseImageName:collapseImage;
    				} else {
                document.getElementById(hiddenDivId).style.overflow = "scroll";
    						document.getElementById(hiddenDivId).style.height = collapseHeight;
                expander.src = (expandImageName)?expandImageName:expandImage;
    				}  
        }
    }
    
    // ----------------------------------------------------------
    // another different way to toggle how much is shown...scrollbars
    // collapseHeight - eg: "200px"
    // ----------------------------------------------------------
    function toggleOverflowText (hiddenDivId, expander, expandText, collapseText, collapseHeight) {
        if (document.getElementById) {
            if (document.getElementById(hiddenDivId).style.overflow == "scroll") {
                document.getElementById(hiddenDivId).style.overflow = "auto";
    						document.getElementById(hiddenDivId).style.height = "";
    					  expander.innerHTML = collapseText?collapseText:defaultHideText;
    				} else {
                document.getElementById(hiddenDivId).style.overflow = "scroll";
    						document.getElementById(hiddenDivId).style.height = collapseHeight;
    						expander.innerHTML = expandText?expandText:defaultExpandText;
    				}  
        }
    }
  2. Add to the <head> section of your html page a script tag to include the javascript:
    <script language=javascript src="expander.js" type=text/javascript></script>
  3. (Optional) To override the default image names add the following to the <body> tag:
    <body onload="setExpanderImages('expand.gif', 'collapse.gif')">
  4. Add to the <body> of your document a div or span with hidden text. Make sure to set the style attribute to display:none to hide the text initially, and set the id attribute to something unique so the expander can find this block of text later.
    For Most Cases:
    <span style="display:none;" id="hiddenText1">Some Text to Hide</span>

    If using "Only Hide Overflow with Image" or "Only Hide Overflow with Text":
    <div style="height: 200px; overflow: scroll;" id="hiddenText1">Some Text to Partially Hide</div>
  5. Add to the <body> of your document an image or text link to show/hide the hidden text with an onClick handler:
    Expansion with image:
    <img src="expand.gif" width="70" height="15" align="absbottom" alt="click to expand/collapse section" style="cursor: pointer;" onClick="toggleBlockImage('hiddenText1', this, 'expand.gif', 'collapse.gif');" />

    Expansion with text:
    <span style="color: #0000FF; text-decoration: underline; cursor: pointer;" onClick="toggleBlockText('hiddenText1', this, 'Show Answer...', 'Hide Answer...');">Show Answer...</span>

    Only Hide Overflow with Image:
    <img src="expand.gif" width="70" height="15" align="absbottom" alt="click to expand/collapse section" style="cursor: pointer;" onClick="toggleOverflowImage('hiddenText1', this, 'expand.gif', 'collapse.gif', '200px');" />

    Only Hide Overflow with Text:
    <span style="color: #0000FF; text-decoration: underline; cursor: pointer;" onClick="toggleOverflowText('hiddenText1', this, 'Show More...', 'Show Less...', '200px');">Show More...</span>
  6. Rename hiddenText1 to a unique name in each place you use the expander (id attributes aren't allowed to have duplicates). Also rename the text shown in green if you prefer different text.

Troubleshooting: “That wasn't supposed to change like that?”

  1. Recycled DIV IDs: HTML's spec says div's shouldn't have duplicate IDs, each ID attribute should be different. If you copy and paste an expandable block make sure you rename the div id AND the expander id to prevent unpredictable results.
  2. Mis-matching HTML Tags: Every opening tag should have a matching closing tag. If you start a <div> or <span> you should finish the </div> or <span>. Check your HTML for tags that don't "pair up" evenly, or aren't nested in the order you meant. Running your page through an HTML validator may help you find the offending tag.

This script was has been tested and should work both with IE7 and FF2.


More Web-Programming Resources