Difference between revisions of "ARIA Tooltip"

From Level Access Web Labs
Jump to navigation Jump to search
 
(93 intermediate revisions by 6 users not shown)
Line 1: Line 1:
<html>
+
<html lang="en">
<head>
+
<head>
<style type="text/css">
+
<title>ARIA Tooltip Example</title>
div.tooltip {
+
<style type="text/css">
  border: 1px solid #666666;
 
  padding: .25em;
 
  background: #333333;
 
}
 
div.text label {
 
  margin: 0;
 
  padding: 0;
 
  padding-right: .25em;
 
  width: 10em;
 
  text-align: right;
 
  clear: both;
 
  float: left;
 
}
 
div.text {
 
  margin: .5em;
 
}
 
input[type=submit] {
 
  clear: both;
 
  padding: 0;
 
  margin: 0;
 
  margin-top: .5em;
 
  margin-left: 13em;
 
}
 
  </style>
 
<script type="text/javascript">
 
var KEY_ESC = 27;
 
  
$(document).ready(function() {
+
/* Sets the font family of the document */
 +
body {
 +
font-family: Helvetica;
 +
}
  
  var tips = []; // an array of tooltips
+
/* Sets a rounded border around the CSS tooltips and adds padding making them easier to read. Display: none; is set to hide the tooltips by default. */
 +
.css_tooltip {
 +
border: 1px solid;
 +
border-radius: 5px;
 +
width: 300px;
 +
padding: 3px;
 +
display: none;
 +
}
  
  // create a tooltip object for each input
+
/* Sets a rounded border around the JS tooltips and adds padding making them easier to read. Display: none; is set to hide the tooltips by default. */
  $('div.text input').each(function(index) {
+
.js_tooltip {
    tips[index] = new tooltip($(this));
+
border: 1px solid;
  });
+
border-radius: 5px;
   
+
width: 300px;
}); // end ready event
+
padding: 3px;
 +
display: none;
 +
}
  
//
+
/* Sets a bottom margin beneath the input fields for spacing/styling */
// tooltip() is a tooltip widget. It requires the element that has the tooltip to reference
+
.input_field {
// the tooltip via aria-describedby. Normally this is a div that contains text
+
margin-bottom: 5px;
//
+
}
// @param ($id object) $id is the jquery object of the input or other element to bind the widget to
 
//
 
// @return N/A
 
//
 
function tooltip($id) {
 
  
  // define the object properties
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when input fields are in focus */
 +
input:focus + div.css_tooltip {
 +
display: block;
 +
}
  
  this.$id = $id;
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when input fields are hovered */
  this.$tip = $('#' + $id.attr('aria-describedby'));
+
input:hover + div.css_tooltip {
  this.mouseover = false; // set to true of the tooltip was displayed via mouseover. reset on mouseout
+
display: block;
  this.focus = false; // set to true of the input has focus (prevent hide on mouseout)
+
}
  this.dismissed = false; // set to true of the user dismissed the tooltip with the esc key. Reset on blur
 
  
  // hide the tooltip
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when links are in focus */
  this.hideTip();
+
a:focus + div.css_tooltip {
 +
display: block;
 +
}
  
  // bind key handlers
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when links are hovered */
  this.bindHandlers();
+
a:hover + div.css_tooltip {
 +
display: block;
 +
}
  
} // end tooltip() constructor
+
</style>
 +
<script type="text/javascript">
 +
// No JavaScript required for the CSS-only examples
 +
// JavaScript is in-line for the JS examples
 +
</script>
 +
</head>
 +
<body>
 +
<form>
  
//
+
  <p>
// function showTip() is a member function to display the tooltip
+
                          <a href="javascript:void(0)" class="acctCurBal0" aria-describedby="acctCurBal_tip_0" id="">Current Balance</a>
//
+
                    <span class="none fsTip" id="acctCurBal_tip_0" style="display:none;">Your current balance includes accrued interest on new transactions for the current billing cycle. You may not be billed, or have to pay, for this accrued interest in accordance with the "Paying Interest" or "How to Avoid Paying Interest" section of your Credit Card Agreement.</span>               
// @return N/A
+
                        </p>
//
+
--Delete Me--
tooltip.prototype.showTip = function() {
+
<h1>The JS Way</h1>
 +
<div class="input_field">
 +
<label for="js_field1">JS Field 1</label>
 +
<input type="text" id="js_field1" aria-describedby="js_field1_tooltip" onfocus="document.getElementById('js_field1_tooltip').style.display='block';" onmouseover="document.getElementById('js_field1_tooltip').style.display='block';" onblur="document.getElementById('js_field1_tooltip').style.display='none';" onmouseout="document.getElementById('js_field1_tooltip').style.display='none';">
 +
<div role="tooltip" class="js_tooltip" id="js_field1_tooltip">This is the tooltip for JS field 1.</div>
 +
</div>
 +
<div class="input_field">
 +
<label for="field2">JS Field 2</label>
 +
<input type="text" id="field2" aria-describedby="js_field2_tooltip" onfocus="document.getElementById('js_field2_tooltip').style.display='block';" onmouseover="document.getElementById('js_field2_tooltip').style.display='block';" onblur="document.getElementById('js_field2_tooltip').style.display='none';" onmouseout="document.getElementById('js_field2_tooltip').style.display='none';">
 +
<div role="tooltip" class="js_tooltip" id="js_field2_tooltip">This is the tooltip for JS field 2.</div>
 +
</div>
 +
<a href="#" aria-describedby="js_link_tooltip" onfocus="document.getElementById('js_link_tooltip').style.display='block';" onmouseover="document.getElementById('js_link_tooltip').style.display='block';" onblur="document.getElementById('js_link_tooltip').style.display='none';" onmouseout="document.getElementById('js_link_tooltip').style.display='none';">Sample Link that spawns a tooltip using JS</a>
 +
<div role="tooltip" class="js_tooltip" id="js_link_tooltip">This is a sample link tooltip spawned with JavaScript.</div>
 +
</form>
 +
</body>
 +
</html>
 +
Implementation Note: Instances have been identified at time of writing (December 2016) in which minor versions of JAWS 17 prior to 17.0.2727 would selectively fail to announce aria-describedby assigned hint values on numerous types of semantic roles (native or ARIA). Instances in which fully valid ARIA markup was present were observed to not announce the tooltip content, despite valid construction.
 +
<html lang="en">
 +
<head>
 +
<title>ARIA Tooltip Example</title>
 +
<style type="text/css">
 +
/* Sets the font family of the document */
 +
body {
 +
font-family: Helvetica;
 +
}
  
  // display the tooltip
+
/* Sets a rounded border around the CSS tooltips and adds padding making them easier to read. Display: none; is set to hide the tooltips by default. */
  this.$tip.css('display', 'inline');
+
.css_tooltip {
 +
border: 1px solid;
 +
border-radius: 5px;
 +
width: 300px;
 +
padding: 3px;
 +
display: none;
 +
}
  
} // end showtip()
+
/* Sets a rounded border around the JS tooltips and adds padding making them easier to read. Display: none; is set to hide the tooltips by default. */
 +
.js_tooltip {
 +
border: 1px solid;
 +
border-radius: 5px;
 +
width: 300px;
 +
padding: 3px;
 +
display: none;
 +
}
  
//
+
/* Sets a bottom margin beneath the input fields for spacing/styling */
// function hideTip() is a member function to hide the tooltip
+
.input_field {
//
+
margin-bottom: 5px;
// @return N/A
+
}
//
 
tooltip.prototype.hideTip = function() {
 
  
  // hide the tooltip
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when input fields are in focus */
  this.$tip.hide();
+
input:focus + div.css_tooltip {
 +
display: block;
 +
}
  
} // end hidetip()
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when input fields are hovered */
 +
input:hover + div.css_tooltip {
 +
display: block;
 +
}
  
//
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when links are in focus */
// function bindHandlers() is a member function to bind event handlers to the input
+
a:focus + div.css_tooltip {
//
+
display: block;
// @return N/A
+
}
//
 
tooltip.prototype.bindHandlers = function() {
 
  
  var thisObj = this;
+
/* Changes the display value of div elements with a class of 'tooltip' from none to block when links are hovered */
 +
a:hover + div.css_tooltip {
 +
display: block;
 +
}
 +
</style>
 +
<script type="text/javascript">
 +
// No JavaScript required for the CSS-only examples
 +
// JavaScript is in-line for the JS examples
 +
</script>
 +
</head>
 +
<body>
 +
<form>
 +
<h1>The CSS-only Way</h1>
 +
                        <p>(<strong>Note:</strong> Inconsistent IE support - This is only for testing and should not be used)</p>
 +
<div class="input_field">
 +
<label for="css_field1">CSS Field 1</label>
 +
<input type="text" id="css_field1" aria-describedby="css_field1-tooltip">
 +
<div role="tooltip" class="css_tooltip" id="css_field1-tooltip">This is the tooltip for CSS field 1.</div>
 +
</div>
 +
<div class="input_field">
 +
<label for="css_field2">CSS Field 2</label>
 +
<input type="text" id="css_field2" aria-describedby="css_field2-tooltip">
 +
<div role="tooltip" class="css_tooltip" id="css_field2-tooltip">This is the tooltip for CSS field 2.</div>
 +
</div>
 +
<a href="#" aria-describedby="css_link_tooltip">Sample Link that spawns a tooltip using only CSS</a>
 +
<div role="tooltip" class="css_tooltip" id="css_link_tooltip">This is a sample link tooltip spawned using only CSS.</div>
 +
</form>
  
  this.$id.keydown(function(e) {
+
</body>
      return thisObj.handleKeyDown($(this), e);
+
</html>
  });
 
 
 
  this.$id.mouseover(function(e) {
 
      return thisObj.handleMouseOver($(this), e);
 
  });
 
  
  this.$id.mouseout(function(e) {
+
Implementation Note: CSS Pseudo- and Combination-selectors have not had uniform support by browsers and screen readers historically. In theory aria-describedby, per Specifications, is expected to override all methods of hiding content through CSS, including the "display:none". However, older user agent combinations were observed to fail to properly announce referenced content under (admittedly) poorly documented circumstances, with a specific trend toward limited support in earlier versions of IE and JAWS. Developers are advised to consider potential browser support when using these approaches for CSS control of content display
      return thisObj.handleMouseOut($(this), e);
 
  });
 
  
  this.$id.focus(function(e) {
+
Sources for the CSS-only method: <br />
      return thisObj.handleFocus($(this), e);
+
1) [http://www.sitepoint.com/web-foundations/adjacent-sibling-selector-css-selector/ http://www.sitepoint.com/web-foundations/adjacent-sibling-selector-css-selector/]<br />
  });
+
2) [http://heydonworks.com/practical_aria_examples/ http://heydonworks.com/practical_aria_examples/]
  
  this.$id.blur(function(e) {
+
[[Category:ARIA]]
      return thisObj.handleBlur($(this), e);
+
[[Category:Aria-describedby]]
  });
 
 
 
} // end bindHandlers()
 
 
 
//
 
// function handleKeyDown() is a member function to process keydown events for the input
 
//
 
// @param ($id object) $id is the jquery object of the element firing event
 
//
 
// @param (e object) e is the event object associated with the event
 
//
 
// @return (boolean) returns false if processing; true if doing nothing
 
//
 
tooltip.prototype.handleKeyDown = function($id, e) {
 
 
 
  if (e.altKey || e.shiftKey || e.ctrlKey) {
 
    // do nothing
 
    return true;
 
  }
 
 
 
  if (e.keyCode == KEY_ESC) {
 
    this.hideTip();
 
    this.dismissed = true;
 
    e.stopPropagation();
 
    return false;
 
  }
 
 
 
  return true;
 
 
 
} // end handleKeyDown()
 
 
 
//
 
// function handleMouseOver() is a member function to display the tooltip on mouseover
 
//
 
// @param ($id object) $id is the jquery object of the element firing event
 
//
 
// @param (e object) e is the event object associated with the event
 
//
 
// @return (boolean) returns false
 
//
 
tooltip.prototype.handleMouseOver = function($id, e) {
 
 
 
  this.showTip();
 
 
 
  // set the mouseover flag to prevent blur dismissing tooltip
 
  this.mouseover = true;
 
 
 
  e.stopPropagation();
 
  return false;
 
 
 
} // end handleMouseOver()
 
 
 
//
 
// function handleMouseOut() is a member function to hide the tooltip on mouseout. If the
 
// input has focus and the user did not dismiss the tooltip, the tooltip is not hidden.
 
//
 
// @param ($id object) $id is the jquery object of the element firing event
 
//
 
// @param (e object) e is the event object associated with the event
 
//
 
// @return (boolean) returns false
 
//
 
tooltip.prototype.handleMouseOut = function($id, e) {
 
 
 
  if (this.dismissed == true || this.focus == false) {
 
    this.hideTip();
 
  }
 
 
 
  // reset the mouseover flag
 
  this.mouseover = false;
 
 
 
  e.stopPropagation();
 
  return false;
 
 
 
} // end handleMouseOut()
 
 
 
//
 
// function handleFocus() is a member function to display the tooltip on focus
 
//
 
// @param ($id object) $id is the jquery object of the element firing event
 
//
 
// @param (e object) e is the event object associated with the event
 
//
 
// @return (boolean) returns false
 
//
 
tooltip.prototype.handleFocus = function($id, e) {
 
 
 
  this.showTip();
 
 
 
  // set the focus flag to prevent mouseout from hiding the tooltip as long
 
  // as the input has focus
 
  this.focus = true;
 
 
 
  e.stopPropagation();
 
  return false;
 
 
 
} // end handleFocus()
 
 
 
//
 
// function handleBlur() is a member function to hide the tooltip on blur. The tooltip is not
 
// hidden if the mouseover flag is true (i.e. tooltip was displayed via mouseover).
 
//
 
// @param ($id object) $id is the jquery object of the element firing event
 
//
 
// @param (e object) e is the event object associated with the event
 
//
 
// @return (boolean) returns false
 
//
 
tooltip.prototype.handleBlur = function($id, e) {
 
 
 
  if (this.mouseover == false) {
 
    this.hideTip();
 
  }
 
 
 
  // reset the focus and dismissed flags
 
  this.focus = false;
 
  this.dismissed = false;
 
 
 
  e.stopPropagation();
 
  return false;
 
 
 
} // end handleBlur()
 
 
 
  </script>
 
</head>
 
<body>
 
<div role="application">
 
<h2>Create Account</h2>
 
 
 
  <div class="text">
 
    <label id="tp1-label" for="first">First Name:</label>
 
  <input type="text" id="first" name="first" size="20" aria-labelledby="tp1-label" aria-describedby="tp1" aria-required="false" />
 
    <div id="tp1" class="tooltip" role="tooltip">Your first name is a optional</div>
 
  </div>
 
 
 
  <div class="text">
 
    <label id="tp2-label" for="last">Last Name: </label>
 
  <input type="text" id="last" name="last" size="30" aria-labelledby="tp2-label" aria-describedby="tp2" aria-required="false" /> *
 
    <div id="tp2" class="tooltip" role="tooltip">Your last name is a optional</div>
 
  </div>
 
 
 
  <div class="text">
 
    <label id="tp3-label" for="last">E-mail: </label>
 
  <input type="text" id="email" name="email" size="40" aria-labelledby="tp3-label" aria-describedby="tp3" aria-required="true" /> *
 
    <div id="tp3" class="tooltip" role="tooltip">Your e-mail address will be your login name</div>
 
  </div>
 
 
 
  <div class="text">
 
    <label id="tp4-label" for="last">Password: </label>
 
  <input type="password" id="password" name="password" size="20" aria-labelledby="tp4-label" aria-describedby="tp4" aria-required="true" /> *
 
    <div id="tp4" class="tooltip" role="tooltip">Password must be at least 8 character long and contain at least one capitol letter and a number</div>
 
  </div>
 
 
 
  <div class="text">
 
    <label id="tp5-label" for="last">Password Confirm: </label>
 
  <input type="password" id="confirm" name="confirm" size="20" aria-labelledby="tp5-label" aria-describedby="tp5" aria-required="true" /> *
 
 
 
    <div id="tp5" class="tooltip" role="tooltip">Confirmation password must match password</div>
 
  </div>
 
   
 
 
 
  <input type="submit" value="Create Account"/>
 
 
 
 
 
 
 
</div>
 
</body>
 
</html>
 

Latest revision as of 22:20, 18 December 2018

ARIA Tooltip Example

Current Balance

--Delete Me--

The JS Way

Sample Link that spawns a tooltip using JS

Implementation Note: Instances have been identified at time of writing (December 2016) in which minor versions of JAWS 17 prior to 17.0.2727 would selectively fail to announce aria-describedby assigned hint values on numerous types of semantic roles (native or ARIA). Instances in which fully valid ARIA markup was present were observed to not announce the tooltip content, despite valid construction.

ARIA Tooltip Example

The CSS-only Way

(Note: Inconsistent IE support - This is only for testing and should not be used)

Sample Link that spawns a tooltip using only CSS

Implementation Note: CSS Pseudo- and Combination-selectors have not had uniform support by browsers and screen readers historically. In theory aria-describedby, per Specifications, is expected to override all methods of hiding content through CSS, including the "display:none". However, older user agent combinations were observed to fail to properly announce referenced content under (admittedly) poorly documented circumstances, with a specific trend toward limited support in earlier versions of IE and JAWS. Developers are advised to consider potential browser support when using these approaches for CSS control of content display

Sources for the CSS-only method:
1) http://www.sitepoint.com/web-foundations/adjacent-sibling-selector-css-selector/
2) http://heydonworks.com/practical_aria_examples/