diff --git a/aria-practices.html b/aria-practices.html index 6a1f88bab8..ff39739861 100644 --- a/aria-practices.html +++ b/aria-practices.html @@ -1227,7 +1227,7 @@

Disclosure (Show/Hide)

Examples

@@ -159,19 +169,15 @@

Role, Property, State, and Tabindex Attributes

- aria-controls="IDREF" + aria-controls="ID_REFERENCE" - - button - - - The disclosure button controls visibility of the container identified by the IDREF value. - + button + Identifies the element controlled by the disclosure button. - aria-expanded="false" + aria-expanded="false" button @@ -182,7 +188,7 @@

Role, Property, State, and Tabindex Attributes

Indicates that the container controlled by the disclosure button is hidden.
  • - CSS attribute selectors (e.g. [aria-expanded="false"]) are + CSS attribute selectors (e.g. [aria-expanded="false"]) are used to synchronize the visual states with the value of the aria-expanded attribute.
  • @@ -196,7 +202,7 @@

    Role, Property, State, and Tabindex Attributes

    - aria-expanded="true" + aria-expanded="true" button @@ -207,7 +213,7 @@

    Role, Property, State, and Tabindex Attributes

    Indicates that the container controlled by the disclosure button is visible.
  • - CSS attribute selectors (e.g. [aria-expanded="true"]) are + CSS attribute selectors (e.g. [aria-expanded="true"]) are used to synchronize the visual states with the value of the aria-expanded attribute.
  • @@ -232,7 +238,7 @@

    Javascript and CSS Source Code

  • Javascript: - disclosureButton.js + disclosureButton.js
  • diff --git a/examples/disclosure/disclosure-img-long-description.html b/examples/disclosure/disclosure-image-description.html similarity index 81% rename from examples/disclosure/disclosure-img-long-description.html rename to examples/disclosure/disclosure-image-description.html index fbf5a456a0..967d18cdd5 100644 --- a/examples/disclosure/disclosure-img-long-description.html +++ b/examples/disclosure/disclosure-image-description.html @@ -11,8 +11,8 @@ - - + + @@ -68,8 +68,10 @@

    Example

    In order to facilitate the judgement of the eye regarding the diminution of the army, I supposed that the troops under Prince Jèrôme and under Marshal Davoust, who were sent to Minsk and Mobilow and who rejoined near Orscha and Witebsk, had always marched with the army.

    Note: A French translation from Wikipedia.

    - -
    + +

    Data for Charles Minard's Chart of Napoleon's Invasion of Russia

    @@ -246,15 +248,24 @@

    Data for Charles Minard's Chart of Napoleon's Invasion of

    Accessibility Features

    -
      -
    1. The visual indication of expanded and collapsed states is synchronized with the value of aria-expanded using a CSS attribute selector and :before pseudo element that generates an image with the content property.
    2. -
    3. The interactivity of the disclosure button is visually indicated on focus and hover: -
        -
      • The CSS :focus pseudo class is used to change the background and border colors.
      • -
      • The CSS :hover pseudo class is used to change the background color and underline the text.
      • -
      +
        +
      • + To help people with visual impairments identify the disclosure as interactive and make it easier to perceive that clicking either the disclosure button or its label changes the expanded state, when a pointer hovers over the button or its label, the background color changes, a border appears, and the cursor changes to a pointer. +
      • +
      • + Because transparent borders are visible on some systems with operating system high contrast settings enabled, transparency cannot be used to create a visual difference between the element that is focused an other elements. + Instead of using transparency, the focused element has a thicker border and less padding. + When an element receives focus, its border changes from 0 to 2 pixels and padding is reduced by 2 pixels. + When an element loses focus, its border changes from 2 pixels to 0 and padding is increased by 2 pixels.
      • -
    +
  • + To ensure the inline SVG arrow graphics in the CSS have sufficient contrast with the background when high contrast settings invert colors, the color of the arrows are synchronized with the color of the text content. + For example, the color of the arrow is set to match the foreground color of high contrast mode text by specifying the CSS currentColor value for the stroke and fill properties of the polygon elements used to draw the arrows. + If specific colors were instead used to specify the polygon properties, those colors would remain the same in high contrast mode, which could lead to insufficient contrast between the arrows and the background or even make the arrows invisible if the color matched the high contrast mode background.
    + Note: The SVG element needs to have the CSS forced-color-adjust property set to auto for the currentColor value to be updated in high contrast mode. + Some browsers do not use auto for the default value. +
  • +
    @@ -304,21 +315,15 @@

    Role, Property, State, and Tabindex Attributes

    - - + +
    - aria-controls="IDREF" + aria-controls="ID_REFERENCE" - button - -
      -
    • The disclosure button controls visibility of the container identified by the IDREF value.
    • -
    -
    buttonIdentifies the element controlled by the disclosure button.
    - aria-expanded="false" + aria-expanded="false" button @@ -329,7 +334,7 @@

    Role, Property, State, and Tabindex Attributes

    Indicates that the container controlled by the disclosure button is hidden .
  • - CSS attribute selectors (e.g. [aria-expanded="false"]) + CSS attribute selectors (e.g. [aria-expanded="false"]) synchronize the visual states with the value of the aria-expanded attribute.
  • @@ -343,7 +348,7 @@

    Role, Property, State, and Tabindex Attributes

    - aria-expanded="true" + aria-expanded="true" button @@ -354,7 +359,7 @@

    Role, Property, State, and Tabindex Attributes

    Indicates that the container controlled by the disclosure button is visible.
  • - CSS attribute selectors (e.g. [aria-expanded="true"]) + CSS attribute selectors (e.g. [aria-expanded="true"]) synchronize the visual states with the value of the aria-expanded attribute.
  • @@ -374,11 +379,11 @@

    Javascript and CSS Source Code

    diff --git a/examples/disclosure/disclosure-navigation-hybrid.html b/examples/disclosure/disclosure-navigation-hybrid.html index 55a92343a2..ee4172dc68 100644 --- a/examples/disclosure/disclosure-navigation-hybrid.html +++ b/examples/disclosure/disclosure-navigation-hybrid.html @@ -44,7 +44,7 @@

    Example Disclosure Navigation Menu with Top-Level Links

    diff --git a/examples/disclosure/disclosure-navigation.html b/examples/disclosure/disclosure-navigation.html index f74a74ba39..3daec401a5 100644 --- a/examples/disclosure/disclosure-navigation.html +++ b/examples/disclosure/disclosure-navigation.html @@ -42,7 +42,7 @@

    Example Disclosure Navigation Menu

    Similar examples include:

    diff --git a/examples/disclosure/js/disclosure-button.js b/examples/disclosure/js/disclosure-button.js new file mode 100644 index 0000000000..5621777ed9 --- /dev/null +++ b/examples/disclosure/js/disclosure-button.js @@ -0,0 +1,87 @@ +/* + * This content is licensed according to the W3C Software License at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * + * File: disclosure-button.js + * + * Desc: Disclosure button widget that implements ARIA Authoring Best Practices + */ + +'use strict'; + +/* + * @constructorDisclosureButton + * + * + */ +class DisclosureButton { + constructor(buttonNode) { + this.buttonNode = buttonNode; + this.controlledNode = false; + + var id = this.buttonNode.getAttribute('aria-controls'); + + if (id) { + this.controlledNode = document.getElementById(id); + } + + this.buttonNode.setAttribute('aria-expanded', 'false'); + this.hideContent(); + + this.buttonNode.addEventListener('click', this.onClick.bind(this)); + this.buttonNode.addEventListener('focus', this.onFocus.bind(this)); + this.buttonNode.addEventListener('blur', this.onBlur.bind(this)); + } + + showContent() { + if (this.controlledNode) { + this.controlledNode.style.display = 'block'; + } + } + + hideContent() { + if (this.controlledNode) { + this.controlledNode.style.display = 'none'; + } + } + + toggleExpand() { + if (this.buttonNode.getAttribute('aria-expanded') === 'true') { + this.buttonNode.setAttribute('aria-expanded', 'false'); + this.hideContent(); + } else { + this.buttonNode.setAttribute('aria-expanded', 'true'); + this.showContent(); + } + } + + /* EVENT HANDLERS */ + + onClick() { + this.toggleExpand(); + } + + onFocus() { + this.buttonNode.classList.add('focus'); + } + + onBlur() { + this.buttonNode.classList.remove('focus'); + } +} + +/* Initialize Hide/Show Buttons */ + +window.addEventListener( + 'load', + function () { + var buttons = document.querySelectorAll( + 'button[aria-expanded][aria-controls]' + ); + + for (var i = 0; i < buttons.length; i++) { + new DisclosureButton(buttons[i]); + } + }, + false +); diff --git a/examples/disclosure/js/disclosureButton.js b/examples/disclosure/js/disclosureButton.js deleted file mode 100644 index 9532095da8..0000000000 --- a/examples/disclosure/js/disclosureButton.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This content is licensed according to the W3C Software License at - * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document - * - * File: ButtonExpand.js - * - * Desc: Checkbox widget that implements ARIA Authoring Practices - * for a menu of links - */ - -'use strict'; - -/* - * @constructor ButtonExpand - * - * - */ -var ButtonExpand = function (domNode) { - this.domNode = domNode; - - this.keyCode = Object.freeze({ - RETURN: 13, - }); -}; - -ButtonExpand.prototype.init = function () { - this.controlledNode = false; - - var id = this.domNode.getAttribute('aria-controls'); - - if (id) { - this.controlledNode = document.getElementById(id); - } - - this.domNode.setAttribute('aria-expanded', 'false'); - this.hideContent(); - - this.domNode.addEventListener('keydown', this.handleKeydown.bind(this)); - this.domNode.addEventListener('click', this.handleClick.bind(this)); - this.domNode.addEventListener('focus', this.handleFocus.bind(this)); - this.domNode.addEventListener('blur', this.handleBlur.bind(this)); -}; - -ButtonExpand.prototype.showContent = function () { - if (this.controlledNode) { - this.controlledNode.style.display = 'block'; - } -}; - -ButtonExpand.prototype.hideContent = function () { - if (this.controlledNode) { - this.controlledNode.style.display = 'none'; - } -}; - -ButtonExpand.prototype.toggleExpand = function () { - if (this.domNode.getAttribute('aria-expanded') === 'true') { - this.domNode.setAttribute('aria-expanded', 'false'); - this.hideContent(); - } else { - this.domNode.setAttribute('aria-expanded', 'true'); - this.showContent(); - } -}; - -/* EVENT HANDLERS */ - -ButtonExpand.prototype.handleKeydown = function (event) { - switch (event.keyCode) { - case this.keyCode.RETURN: - this.toggleExpand(); - - event.stopPropagation(); - event.preventDefault(); - break; - - default: - break; - } -}; - -ButtonExpand.prototype.handleClick = function () { - this.toggleExpand(); -}; - -ButtonExpand.prototype.handleFocus = function () { - this.domNode.classList.add('focus'); -}; - -ButtonExpand.prototype.handleBlur = function () { - this.domNode.classList.remove('focus'); -}; - -/* Initialize Hide/Show Buttons */ - -window.addEventListener( - 'load', - function () { - var buttons = document.querySelectorAll( - 'button[aria-expanded][aria-controls]' - ); - - for (var i = 0; i < buttons.length; i++) { - var be = new ButtonExpand(buttons[i]); - be.init(); - } - }, - false -); diff --git a/examples/index.html b/examples/index.html index ff03274da3..7e6f27f50e 100644 --- a/examples/index.html +++ b/examples/index.html @@ -522,7 +522,7 @@

    Examples By Properties and States

  • Select-Only Combobox
  • Editable Combobox with Grid Popup
  • Disclosure (Show/Hide) for Answers to Frequently Asked Questions (HC)
  • -
  • Disclosure (Show/Hide) for Image Description (HC)
  • +
  • Disclosure (Show/Hide) for Image Description (HC)
  • Disclosure Navigation Menu with Top-Level Links
  • Disclosure Navigation Menu (HC)
  • Actions Menu Button Using aria-activedescendant (HC)
  • @@ -579,7 +579,7 @@

    Examples By Properties and States

  • Select-Only Combobox
  • Editable Combobox with Grid Popup
  • Disclosure (Show/Hide) for Answers to Frequently Asked Questions (HC)
  • -
  • Disclosure (Show/Hide) for Image Description (HC)
  • +
  • Disclosure (Show/Hide) for Image Description (HC)
  • Disclosure Navigation Menu with Top-Level Links
  • Disclosure Navigation Menu (HC)
  • (Deprecated) Collapsible Dropdown Listbox
  • diff --git a/test/tests/disclosure_faq.js b/test/tests/disclosure_faq.js index d695e1535a..f22f3bac25 100644 --- a/test/tests/disclosure_faq.js +++ b/test/tests/disclosure_faq.js @@ -3,12 +3,10 @@ const { By, Key } = require('selenium-webdriver'); const assertAriaControls = require('../util/assertAriaControls'); const assertAttributeValues = require('../util/assertAttributeValues'); const assertTabOrder = require('../util/assertTabOrder'); - const exampleFile = 'disclosure/disclosure-faq.html'; const ex = { buttonSelector: '#ex1 button', - answerSelector: '#ex1 p.desc', buttonSelectors: [ '#ex1 dt:nth-of-type(1) button', '#ex1 dt:nth-of-type(2) button', diff --git a/test/tests/disclosure_img-long-description.js b/test/tests/disclosure_image-description.js similarity index 98% rename from test/tests/disclosure_img-long-description.js rename to test/tests/disclosure_image-description.js index 37b9ecb016..c77ff8ce0c 100644 --- a/test/tests/disclosure_img-long-description.js +++ b/test/tests/disclosure_image-description.js @@ -3,7 +3,7 @@ const { By, Key } = require('selenium-webdriver'); const assertAriaControls = require('../util/assertAriaControls'); const assertAttributeValues = require('../util/assertAttributeValues'); -const exampleFile = 'disclosure/disclosure-img-long-description.html'; +const exampleFile = 'disclosure/disclosure-image-description.html'; const ex = { buttonSelector: '#ex1 button',