Expandable Sections

With a few lines of HTML, a few declarations of CSS, and a couple of jQuery methods, this tutorial will provide a simple system to create expandable sections.

This tutorial assumes the reader has basic knowledge of HTML5, CSS, jQuery, and basic page layout.

Written by Brian Immel

Expandable in action

This tutorial will create a few div elements (two nested in a parent element) with the title section that controls the display state of the content section. This educational document refers to this system as the expandable system.

Here is a preview of what will be built:

Clickable Title

Expandable content can be anything.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac enim vitae sapien consequat imperdiet. Vivamus sodales risus eget nisi lobortis volutpat. Integer auctor augue vitae dapibus feugiat. Sed in molestie mauris. Morbi diam nulla, porttitor nec urna semper, sollicitudin condimentum sapien. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce eu neque erat. Nam in vulputate tellus. Sed blandit vehicula massa nec lacinia. In sit amet orci leo. Sed sit amet mi ligula. Integer tincidunt tortor enim, vel malesuada arcu pretium nec.

Header Link and Scripts

Begin by including a CSS and two JavaScript files in the head of the page.

...
<link rel="stylesheet" href="style.css">
<script src="../../js/jquery-2.1.0.min.js">
<script src="main.js"></script>
...

The style.css file will house all the CSS declarations for this tutorial. Next, jquery-2.1.0.min.js is sourced so the methods and functions can use jQuery version 2.1.0. The last sourced file is main.js where all the functions for this tutorial will be stored.

HTML Components
HTML Components: clickable title and content area nested inside a container element

In the HTML component of this tutorial makes use of just four elements with various classes, ids and one data attribute. The image to the right illustrates the layout of the HTML that will be used in this document.

The outer element is the container for the entire system, the title section will act as the section's caption and clickable area of the expandable, and finally, the content section which contains other elements ultimately receives the show or hide behavior.

As with any typical layout, this one starts off with a container. In this case, div element with the class of expandableContainer that acts as the container for the it's child elements. The children elements are title and content sections.

<div class="expandableContainer">
...
</div>

With the container element ready, it's time to construct the children elements that will contain the title and content sections.

Clickable Title

The first nested div element of div.expandableContainer is the div.expandableTitle. This div element handles the click event to either collapse or expand the div.expandableContent element. The visibility of the content element will be stored in a custom attribute. A relatively new feature of HTML5 is the data attribute. Extensibility is a key feature of HTML5 and here, the code will take advantage of that by utilizing an attribute called status. This attribute will hold the value of either "open" or "hidden" to tell it's jQuery functions to display or collapse the content section.

...
<div class="expandableTitle" id="expandTitle-first" status="hidden">
<span title="Click to expand">Expandable Title</span>
...
</div>
...

The id of this element, along with the content element, uses a specific naming standard. jQuery functions will look for ids that start with expandTitle. The second part of the id (after the hyphen) is an unique name to this particular container of elements. For simplicity's sake, the unique name of first has been assigned to it.

The final attribute of this element is it's class: expandableTitle. This class will handle the display and interactive behavior of this clickable title element.

Nested inside the expandTitle element is a span element. While it is optional to use a span element to wrap around the text of the expandable's title, it can be useful in the future if one wishes to write extra rules to handle the display of this text.

In future uses of the expandable system, one would be advised to using a better and more descriptive identifier (last half of id).

Content Div

The content div element is pretty straight forward with the exception of the specific id naming scheme mentioned earlier. The id isn't necessary for the expandable to work but it is a good habit to get into of providing ids to elements that jQuery work with on some level (now or in future updates of the feature set). The class expandContent is used to handle the layout of the element which the display state will be toggled by the clickable title.

...
<div class="expandableContent" id="expandContent-first">
...Content...
</div>
...
Complete HTML

Here is the complete HTML code:

Complete HTML Code
<div class="expandableContainer">
<div class="expandableTitle" id="expandTitle-first" status="hidden">
<span title="Click to expand">
Expandable Title
</span>
</div>
<div class="expandableContent" id="expandContent-first">
...Content...
</div>
</div>

To have more than one expandable on a page, copy this block as many times as needed and replace the last part of the ids of the title and content sections with any unique name as necessary.

At this point, it would be a good idea to save your HTML file.

CSS Component and Container CSS

Use the style.css file add the following declarations for this tutorial.

Most of the CSS declarations for the div.expandableContainer are cosmetic but there are a few declaration sprinkled in that address layout. The only necessary attribute is the display declaration. This inline-block declaration sets up the container element so that it will be flow with the surrounding content. The border around the entire containing element lets users know that the content herein is a separate entity from the rest of page. The remaining declarations address layout and design.

.expandableContainer {
display: inline-block;
border: solid thin rgba(0,0,25, 0.10);
border-radius: 5px;
padding: 0 5px 0 5px;
margin: 0 15px 0 0;
}

With the container element set, its time to set some declarations for it's children elements.

Title and Content Section's CSS

The div.expandableTitle element should have some simple styling rules even through they aren't 100% necessary. However, like all good UX design, a clickable element should stand out from the rest of the page's content so the user knows that this particular line of text has some function or purpose other than simple text on the screen.

.expandableTitle {
color: #3366CC;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
display: inline-block;
}

Color, font size and weight are purely cosmetic. The cursor declaration tells the browser to change the cursor to a point when the user hovers over the title section. The display declaration is used to display the div element inline it's sibling element.

To add a little more interactive, a pseudo-class is added in to change the color of the text when the user hovers over the title:

.expandableTitle:hover {
color: #FFFFFF;
}

The final bit of CSS code is some simple padding around the content of the expandable's content area. It's always a good thing to have your content pushed away from the walls of it's containing element.

.expandableContent {
padding: 5px;
}

One could add a few more declarations to affect the display of the content like font family and size, indenting, and so forth but it's not necessary at this time.

Final CSS Code

Complete CSS code that has been written for this tutorial:

Complete CSS Code
.expandableTitle {
color: #3366CC;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
display: inline-block;
}
.expandableTitle:hover {
color: #FFFFFF;
}
.expandableContainer {
display: inline-block;
border: solid thin rgba(0,0,25, 0.10);
border-radius: 5px;
padding: 0 5px 0 5px;
margin: 0 15px 0 0;
}
.expandableContent {
padding: 5px;
}

Now would be a good time to save the style.css file. At this point, the page can be tested for visual layout and the hover interactivity but not the expanding or collapsing behaviors. The next section on jQuery will add that functionality to this little system.

jQuery Component and Closing All Expandables By Default

The final component of this tutorials ends with jQuery. The following steps show how to write a straightforward event handler that listens for a click on any div element that an id starting with expandTitle. From there, the clicked element's id will look for it's sibling element, toggle it's display state, and set a value to the custom attribute status.

Te begin, all expandables should be collapsed when the page is first opened. By applying a slideUp method to all elements who's ids start with expandContent, every expandable will start off appearing collapsed.

$(document).ready(function() {
$("div[id^='expandContent']").slideUp(0);
...
});

It should be noted that the value passed in the slideUp method is set to zero. This is used to hide the content element instantly instead of animated effect over a set period of time.

One may wonder why CSS wasn't used to hide the content elements by default.

That is a valid question but using CSS to hide the content element wouldn't necessary have the same initial reveal and hide behavior that the jQuery function provides. Using jQuery to handle all visual appearances of the content element lends an uniform user experience.

Click Event on Expandable's Title

With all the expandables closed up, the next thing to work out is creating an event handler that looks for the user's click on the expandable's title section.

As mentioned in the HTML component section, the title and content sections were given specific ids. The last part of the id (after the hyphen) is what made the id unique while the first half will be used in a selector so jQuery can grab it. In this case, the method used to select these ids will look something like this: div[attribute^='value']. Then we attach the click method to that selector.

...
$("div[id^='expandTitle']").click(function() {
...
});
...

This bit of code looks for all div elements that have an id that starts with expandTitle. Once the user clicks an element with this id, the next thing that needs to happen is the collection of it's id and status values.

Collecting Ids and Status Values

When the title div element is clicked, a jQuery function needs to grab the clicked element's sibling id and status values. To get this information, the function could use the preceded selector method: element1 ~ element2. The preceded selector method works something like this: Select element2 that is preceded by element1. In the fore mentioned HTML code, the expandTitle element precedes the expandContent element. With that in mind, here is what the code should look like:

var titleId = $(this).attr("id");
var siblingId = $("#" + titleId + " ~ div").attr("id");

Breakdown of this variable: First, the id of the clicked element is collected and stored in the variable titleId via the attribute method. Then the id of the sibling element is obtained via the same method once it has figured out the id of it's sibling by way of the preceded selector method of the titleId + " ~ div" selector.

With the ids stored, the function should now find the value for attribute of status. The sibling element contains an attribute called status which this function need to grab it's value. This value will be used to make a decision with this value later on. To obtain this value, use the same method as before: attribute but point it at the status attribute.

var status = $(this).attr("status");
Toggling Expandable's Content Section

The last thing this function needs to do is determine whether to show or hide the content element based on the value found in the status attribute. The function starts off by checking if the status is to hidden (by default it should be) or open and then issue a slideDown or slideUp method on the expandable's content section and follow up with changing the status' value to the opposite to reflect the display state change.

if (status == "hidden") {
$("#" + siblingId).slideDown("fast");
$(this).attr("status","open");
} else {
$("#" + siblingId).slideUp("fast");
$(this).attr("status","hidden");
}

With this last bit of code, when the user clicks the title section, the content section will slide in and out of view depending on the value stored in status.

Now the expandable will show or hide the content section whenever the user clicks on it. However, this feature doesn't remember which expandables were open from page visit to page visit. Another feature can be added to the expandable system to remember the status of each expandable via cookies. At this time, my next tutorial isn't complete yet. Please stay tuned!

Complete jQuery Code

That's it! With a little more than a dozen lines of jQuery, the expandable system is complete! Here is the complete jQuery script for the expandable:

Complete jQuery Code
$(document).ready(function() {
$("div[id^='expandContent']").slideUp(0);

$("div[id^='expandTitle']").click(function() {
var titleId = $(this).attr("id");
var siblingId = $("#" + titleId + " ~ div").attr("id");
var status = $(this).attr("status");
if (status == "hidden") {
$("#" + siblingId).slideDown("fast");
$(this).attr("status","open");
} else {
$("#" + siblingId).slideUp("fast");
$(this).attr("status","hidden");
}
});
});

Please save your JavaScript in the file called main.js and test it out.

Conclusion

Congratulation! With the completion of these three components (a few lines of HTML, a handful of declarations of CSS, and four jQuery methods), the expandable system should work nicely.

One Last Expandable

Congrats! Stay tuned for the continuation of this mini-series!

Enjoy!

If you have any questions or comments, please contact me at Brian@jawa9000.com.

Resources