Example Start

List of Messages

Example End

Example Description

Type: Best Practice

Simple example of hiding and showing regions using aria-expanded. aria-controls is used to maintain markup associations.’

Keyboard Support

  • Tab: Move between button items and text area.
  • Enter or space: Toggle display of hide/show regions.

Example Markup

Browser Compatibility

HTML Source Code


<h2>List of Messages</h2>

<ul class="msglinks">
  <li>
      <button id="open1" class="buttonControl" aria-controls="m1">
            <span>Show</span>
            Message 1
      </button>
  </li>
  <li>
      <button id="open2" class="buttonControl" aria-controls="m2">
           <span>Show</span>
           Message 2
      </button>
  </li>
  <li>
      <button id="open3" class="buttonControl" aria-controls="m3">
           <span>Show</span>
           Message 3
      </button>
  </li>
  <li>
      <button id="open4" class="buttonControl" aria-controls="m4">
           <span>Show</span>
           Message 4
      </button>
  </li>
</ul>

<div id="m1" class="message" tabindex="-1" role="region" aria-labelledby="m1-label" aria-expanded="false">
    <h2 id="m1-label">Message 1</h2>
    <p>Message 1 is all about being message 1 and has nothing to do with any other messages.</p>
    <p>
        <button id="close1" class="buttonControl" aria-controls="m1">
             Close
             <span class="hidden">Message 1</span>
        </button>
    </p>
</div>

<div id="m2" class="message" role="region" aria-labelledby="m2-label" tabindex="-1" aria-expanded="false">
      <h2 id="m2-label">Message 2</h2>
      <p>Message 2 is all about being message 2 and has nothing to do with any other messages.</p>
      <p>
        <button id="close2" class="buttonControl" aria-controls="m2">
            Close
            <span class="hidden">Message 2</span>
        </button>
    </p>
</div>

<div id="m3" class="message" role="region" aria-labelledby="m3-label" tabindex="-1" aria-expanded="false">
       <h2 id="m3-label">Message 3</h2>
       <p>Message 3 is all about being message 3 and has nothing to do with any other messages.</p>
       <p>
         <button id="close3" class="buttonControl" aria-controls="m3">
            Close
            <span class="hidden">Message 3</span>
         </button>
       </p>
</div>

<div id="m4" class="message" role="region" aria-labelledby="m4-label" tabindex="-1" aria-expanded="false">
       <h2 id="m4-label">Message 4</h2>
       <p>Message 4 is all about being message 4 and has nothing to do with any other messages.</p>
       <p>
         <button id="close4" class="buttonControl" aria-controls="m4">
            Close
            <span class="hidden">Message 4</span>
         </button>
       </p>
</div>

CSS Code


.hidden {
    display: none;
}

ul.msglinks {
   list-style: none;
}
div.message
{
  display: none;
  margin: .5em;
  padding: .5em;
  border: 2px solid #880000;
  width: 40em;
}

div#m1 {
  background-color: #ffefef;
}

div#m2 {
  background-color: #efffef;
}

div#m3 {
  background-color: #efefff;
}

div#m4 {
  background-color: #efffff;
}

a.buttonControl {
  color: #004400;
  text-decoration: none;
  border-bottom: 1px solid #004400;
}

a.buttonControl:hover,
a.buttonControl:active,
a.buttonControl:focus {
  color: #880000;
  border-bottom: 2px solid #880000;
}

Javascript Source Code


$(document).ready(function() {

   var hs1 = new hideShow('open1', 'close1');
   var hs2 = new hideShow('open2', 'close2');
   var hs3 = new hideShow('open3', 'close3');
   var hs4 = new hideShow('open4', 'close4');
  
}); // end ready()

//
// function hideShow() is the constructor for a hideShow widget. It accepts two html IDs:
//
// 1. the button to toggle the region
// 2. A close button within the region to hide it and return focus to the toggle button
//
// The widget moves focus to the region when expanding it, and returns focus to the toggle button
// when closing it.
//
// @param(toggleID string) toggleID is the html ID of the toggle button to attach to
//
// @param(closeID string) closeID is the html ID of the close button to attach to
//
// @return N/A
//
function hideShow(toggleID, closeID) {

   this.$toggle = $('#' + toggleID);
   this.$close = $('#' + closeID);
   this.$region = $('#' + this.$toggle.attr('aria-controls'));

   this.keys = {
               enter: 13,
               space: 32
               };

   this.toggleSpeed = 100;

   // bind handlers
   this.bindHandlers();

} // end hidShow() constructor

//
// Function bindHandlers() is a member function to bind event handlers to the hideShow region
//
// return N/A
//
hideShow.prototype.bindHandlers = function() {

   var thisObj = this;

   this.$toggle.click(function(e) {

      thisObj.toggleRegion();

      e.stopPropagation();
      return false;
   });

   this.$close.click(function(e) {

      thisObj.hideRegion();

      e.stopPropagation();
      return false;
   });
}

// Function hideRegion() is a member function to hide an expanded region and return focus to
// the toggle button
//
// return N/A
//
hideShow.prototype.hideRegion = function() {

   // hide the region and update the aria-expanded attribute
   this.$region.hide().attr('aria-expanded', 'false');

   // update the button label
   this.$toggle.find('span').html('Show');

   // return focus to the toggle button
   this.$toggle.focus();

} // end hideRegion()

//
// Function toggleRegion() is a member function to toggle the display of the hideShow region
//
// return N/A
//
hideShow.prototype.toggleRegion = function() {

      var thisObj = this;

    // toggle the region
    this.$region.slideToggle(this.toggleSpeed, function() {

      if ($(this).attr('aria-expanded') == 'false') { // region is collapsed

        // update the aria-expanded attribute of the region
        $(this).attr('aria-expanded', 'true');

        // move focus to the region
        $(this).focus();

        // update the button label
        thisObj.$toggle.find('span').html('Hide');

      }
      else { // region is expanded

        // update the aria-expanded attribute of the region
        $(this).attr('aria-expanded', 'false');

        // update the button label
        thisObj.$toggle.find('span').html('Show');
      }
    });

} // end toggleRegion()