{"id":374,"date":"2018-12-10T17:32:00","date_gmt":"2018-12-10T17:32:00","guid":{"rendered":"https:\/\/pressbooks.library.ryerson.ca\/wafd\/?post_type=chapter&#038;p=374"},"modified":"2022-12-16T17:17:22","modified_gmt":"2022-12-16T17:17:22","slug":"tree-menus","status":"publish","type":"chapter","link":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/chapter\/tree-menus\/","title":{"raw":"Tree Menus","rendered":"Tree Menus"},"content":{"raw":"Tree menus often have the same underlying HTML structure as a menu bar, but rather than being arranged in a horizontal layout, they tend to be arranged vertically.\r\n<div class=\"textbox\">\r\n\r\n<strong>WAI-ARIA roles, states, and properties used in a tree menu<\/strong>\r\n\r\n<code><code><code><\/code><\/code><\/code>\r\n<ul>\r\n \t<li>tabindex = [0 | -1]<\/li>\r\n \t<li>aria-labelledby = [instruction div id | title div id]<\/li>\r\n \t<li>aria-hidden = [true | false]<\/li>\r\n \t<li>role = \"tree\"<\/li>\r\n \t<li>role = \"treeitem\"<\/li>\r\n \t<li>role = \"presentation\"<\/li>\r\n \t<li>aria-level = [number of parent ULs]<\/li>\r\n \t<li>aria-setsize = [number of LIs in a level]<\/li>\r\n \t<li>aria-posinset = [position of each LI in a set]<\/li>\r\n \t<li>aria-expanded = [true | false]<\/li>\r\n \t<li>aria-selected = [true | false]<\/li>\r\n<\/ul>\r\n<code><code><\/code><\/code>\r\n\r\n<\/div>\r\n<div style=\"margin: 1em 0; padding: 1em; border: 1px solid #ddd; border-left: 10px solid #0000ff;\"><strong>Suggested Reading:<\/strong> For more about accessible tree menus, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/treeview\/\">ARIA Authoring Practices Guide: Tree View<\/a><\/div>\r\nThe following JSFiddle presents a typical tree menu widget with a few submenus. Review the JavaScript and HTML markup. Test the tree menu presented under the Result tab with ChromeVox to understand how it functions without any accessibility features added. You can work in JSFiddle itself by clicking \u201cEdit in JSFiddle\u201d\u00a0at the top, right-hand side, copying the accessibility\/WAI-ARIA code described below to fix the accessibility of the tree menu before completing <a href=\"https:\/\/pressbooks.library.torontomu.ca\/wafd\/chapter\/6-5-activity-13-accessible-tree-navigation\/\">Activity 13<\/a> on the page that follows.\r\n<div style=\"height: 600px; overflow: hidden;\">[h5p id=\"91\"]<\/div>\r\n<!--https:\/\/jsfiddle.net\/greggy\/z5d3pt8m\/embedded\/-->\r\n\r\nFirst, define instructions on using the tree menu with a keyboard.\r\n<div style=\"height: 165px; overflow: hidden;\">[h5p id=\"92\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/MpTQfKSH\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function add keyboard focus to the tree container by applying <code>tabindex=\"0\"<\/code> to it, and label the container with the instructions created above, which gets read by screen readers when the menu initially receives focus.\r\n<div style=\"height: 160px; overflow: hidden;\">[h5p id=\"93\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/dJSCJdHT\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function, hide the instructions <code>&lt;div&gt;<\/code> from screen readers by default by setting <code>aria-hidden=\"true\"<\/code> when the tree menu is initialized.\r\n<div style=\"height: 220px; overflow: hidden;\">[h5p id=\"94\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/u2K6J4Yc\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function replace the unordered list semantics with tree menu semantics using <code>role=\"tree\"<\/code>, and give it a title using <code>aria-labelledby<\/code> to reference the title defined in the default options.\r\n<div style=\"height: 175px; overflow: hidden;\">[h5p id=\"95\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/PLUjFAj8\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function, define menu items with <code>role=\"treeitem\"<\/code>, remove all keyboard access by default with <code>tabindex=\"-1\"<\/code>, set the number of levels in the tree based on the number of parent ULs with <code>aria-level=[number of ULs]<\/code>, set the number of tree items on a given level with <code>aria-setsize=\"[number of LIs in a UL]\"<\/code>, and finally define the position of each tree item within a level using <code>aria-posinset=\"[child LI index]\"<\/code>.\r\n<div style=\"height: 225px; overflow: hidden;\">[h5p id=\"96\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/bFp57Zz4\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function, if a tree item has a submenu UL that has been opened, set <code>aria-expanded=\"true\"<\/code>, otherwise set <code>aria-expanded=\"false\"<\/code>.\r\n<div style=\"height: 315px; overflow: hidden;\">[h5p id=\"97\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/S9ATtr2j\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function, for each tree item use the text of the associated <code>span<\/code> element as its label. To ensure both the label and the contents of the <code>span<\/code> element are not both read, assign <code>role=\"presentation\"<\/code> to the <code>span<\/code>.\r\n<div style=\"height: 290px; overflow: hidden;\">[h5p id=\"98\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/Ek1gXu1u\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function, where mouse <code>onclick<\/code> functionality is used, provide equivalent <code>keydown<\/code> functionality, here referencing the <code>onKeyDown<\/code> function, shown below, that defines the keys to operate the menu.\r\n<div style=\"height: 70px; overflow: hidden;\">[h5p id=\"99\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/iFrns2Um\/noheader-->\r\n\r\nWithin the <code>init()<\/code> function, right after adding <code>keydown<\/code> operability, make the first item in the tree menu focusable by adding <code>tabindex=\"0\"<\/code> to the first <code>li<\/code>.\r\n<div style=\"height: 115px; overflow: hidden;\">[h5p id=\"100\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/JAi5989n\/noheader-->\r\n\r\nWithin the <code>selectItem()<\/code> function, set up a roving tabindex, while at the same time applying <code>aria-selected=[true | false]<\/code> when tree items receive or lose focus.\r\n<div style=\"height: 640px; overflow: hidden;\">[h5p id=\"101\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/W9R8UbKq\/noheader-->\r\n\r\nIn the <code>toggleSubmenu()<\/code> function, announce the state of submenus to the screen reader by toggling the <code>aria-expanded=[true | false]<\/code> attribute when a menu is opened or closed.\r\n<div style=\"height: 425px; overflow: hidden;\">[h5p id=\"102\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/9HdKXj82\/noheader-->\r\n<h2>Adding Keyboard Operability<\/h2>\r\nMuch like the menu bar described in the previous activity, keyboard operability for a tree menu can be complex, with various operations using multiple key strokes to perform the same function. W3C describes potential keyboard operation in the <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/treeview\/#keyboard-interaction-24\">ARIA Authoring Practices Guide<\/a>, reproduced below.\r\n<div class=\"textbox\">\r\n<h3>Tree Menu Keyboard Interaction<\/h3>\r\nFor a vertically oriented tree:\r\n<ul>\r\n \t<li>When a single-select tree receives focus:\r\n<ul>\r\n \t<li>If none of the nodes are selected before the tree receives focus, focus is set on the first node.<\/li>\r\n \t<li>If a node is selected before the tree receives focus, focus is set on the selected node.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>When a multi-select tree receives focus:\r\n<ul>\r\n \t<li>If none of the nodes are selected before the tree receives focus, focus is set on the first node.<\/li>\r\n \t<li>If one or more nodes are selected before the tree receives focus, focus is set on the first selected node.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>Right Arrow:\r\n<ul>\r\n \t<li>When focus is on a closed node, opens the node; focus does not move.<\/li>\r\n \t<li>When focus is on a open node, moves focus to the first child node.<\/li>\r\n \t<li>When focus is on an end node, does nothing.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>Left Arrow:\r\n<ul>\r\n \t<li>When focus is on an open node, closes the node.<\/li>\r\n \t<li>When focus is on a child node that is also either an end node or a closed node, moves focus to its parent node.<\/li>\r\n \t<li>When focus is on a root node that is also either an end node or a closed node, does nothing.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>Down Arrow: Moves focus to the next node that is focusable without opening or closing a node.<\/li>\r\n \t<li>Up Arrow: Moves focus to the previous node that is focusable without opening or closing a node.<\/li>\r\n \t<li>Home: Moves focus to the first node in the tree without opening or closing a node.<\/li>\r\n \t<li>End: Moves focus to the last node in the tree that is focusable without opening a node.<\/li>\r\n \t<li>Enter: Activates a node, i.e., performs its default action. For parent nodes, one possible default action is to open or close the node. In single-select trees where selection does not follow focus (see note below), the default action is typically to select the focused node.<\/li>\r\n \t<li>Type-ahead is recommended for all trees, especially for trees with more than 7 root nodes:\r\n<ul>\r\n \t<li>Type a character: focus moves to the next node with a name that starts with the typed character.<\/li>\r\n \t<li>Type multiple characters in rapid succession: focus moves to the next node with a name that starts with the string of characters typed.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>* (Optional): Expands all siblings that are at the same level as the current node.<\/li>\r\n \t<li><strong>Selection in multi-select trees:<\/strong> Authors may implement either of two interaction models to support multiple selection: a recommended model that does not require the user to hold a modifier key, such as Shift or Ctrl, while navigating the list or an alternative model that does require modifier keys to be held while navigating in order to avoid losing selection states.\r\n<ul>\r\n \t<li>Recommended selection model \u2013 holding a modifier key while moving focus is not necessary:\r\n<ul>\r\n \t<li>Space: Toggles the selection state of the focused node.<\/li>\r\n \t<li>Shift + Down Arrow (Optional): Moves focus to and toggles the selection state of the next node.<\/li>\r\n \t<li>Shift + Up Arrow (Optional): Moves focus to and toggles the selection state of the previous node.<\/li>\r\n \t<li>Shift + Space (Optional): Selects contiguous nodes from the last selected node to the current node.<\/li>\r\n \t<li>Ctrl + Shift + Home (Optional): Selects the node with focus and all nodes up to the first node.<\/li>\r\n \t<li>Ctrl + Shift + End (Optional): Selects the node with focus and all nodes down to the last node.<\/li>\r\n \t<li>Ctrl + A (Optional): Selects all nodes in the tree. Optionally, if all nodes are selected, it can also unselect all nodes.<\/li>\r\n<\/ul>\r\n<\/li>\r\n \t<li>Alternative selection model \u2013 moving focus without holding the Shift or Ctrl modifier unselects all selected nodes except for the focused node:\r\n<ul>\r\n \t<li>Shift + Down Arrow: Moves focus to and toggles the selection state of the next node.<\/li>\r\n \t<li>Shift + Up Arrow: Moves focus to and toggles the selection state of the previous node.<\/li>\r\n \t<li>Ctrl + Down Arrow: Without changing the selection state, moves focus to the next node.<\/li>\r\n \t<li>Ctrl + Up Arrow: Without changing the selection state, moves focus to the previous node.<\/li>\r\n \t<li>Ctrl + Space: Toggles the selection state of the focused node.<\/li>\r\n \t<li>Shift + Space (Optional): Selects contiguous nodes from the most recently selected node to the current node.<\/li>\r\n \t<li>Ctrl + Shift + Home (Optional): Selects the node with focus and all nodes up to the first node.<\/li>\r\n \t<li>Ctrl + Shift + End (Optional): Selects the node with focus and all nodes down to the last node.<\/li>\r\n \t<li>Ctrl + A (Optional): Selects all nodes in the tree. Optionally, if all nodes are selected, it can also unselect all nodes.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n<div>\r\n<div style=\"margin: 1em 0; padding: 1em; border: 1px solid #ddd; border-left: 10px solid #3c3;\">\r\n<div id=\"h-note-27\" class=\"note-title marker\" role=\"heading\"><strong>Note:<\/strong><\/div>\r\n<ol class=\"\">\r\n \t<li>DOM focus (the active element) is functionally distinct from the selected state. For more details, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/practices\/keyboard-interface\/#kbd_focus_vs_selection\">this description of differences between focus and selection.<\/a><\/li>\r\n \t<li>The <code>tree<\/code> role supports the <a class=\"property-reference\" href=\"https:\/\/www.w3.org\/TR\/wai-aria-1.1\/#aria-activedescendant\">aria-activedescendant<\/a> property, which provides an alternative to moving DOM focus among <code>treeitem<\/code> elements when implementing keyboard navigation. For details, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/practices\/keyboard-interface\/#kbd_focus_activedescendant\">Managing Focus in Composites Using aria-activedescendant<\/a>.<\/li>\r\n \t<li>In a single-select tree, moving focus may optionally unselect the previously selected node and select the newly focused node. This model of selection is known as \"selection follows focus\". Having selection follow focus can be very helpful in some circumstances and can severely degrade accessibility in others. For additional guidance, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/practices\/keyboard-interface\/#kbd_selection_follows_focus\">Deciding When to Make Selection Automatically Follow Focus<\/a>.<\/li>\r\n \t<li>If selecting or unselecting all nodes is an important function, implementing separate controls for these actions, such as buttons for \"Select All\" and \"Unselect All\", significantly improves accessibility.<\/li>\r\n \t<li>If the nodes in a tree are arranged horizontally:\r\n<ol>\r\n \t<li>Down Arrow performs as Right Arrow is described above and vice versa.<\/li>\r\n \t<li>Up Arrow performs as Left Arrow is described above and vice versa.<\/li>\r\n<\/ol>\r\n<\/li>\r\n<\/ol>\r\n<\/div>\r\n<a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/treeview\/#keyboard-interaction-24\">Source: ARIA Authoring Practices Guide<\/a>\r\n\r\n<\/div>\r\n<\/div>\r\nFor the tree menu created here, we\u2019ve added in basic keyboard operability. Keyboard operation includes: Up and Down, and Left and Right Arrows for navigating within the tree, and the Enter or Space bar keys to toggle submenus open or closed. The Tab key by default enters and exits the tree menu and does not need to be defined as part of the keyboard operability of the tree menu.\r\n<div style=\"height: 1500px; overflow: hidden;\">[h5p id=\"103\"]<\/div>\r\n<!--https:\/\/pastebin.com\/embed_iframe\/fhdx9mtc\/noheader-->\r\n<h2>Accessible Tree Menu in Action<\/h2>\r\nWatch the following video showing ChromeVox interacting with a tree menu. The Tab key is used to navigate into the tree menu, to the first tree item, and to exit the tree menu. The Up and Down arrows are used to move between tree items. The Space bar or Enter key are used to expand and collapse a tree item with a submenu. When a submenu is opened, focus moves to the first tree item in the menu. Aim to have the tree menu you update in\u00a0\u00a0<a href=\"https:\/\/pressbooks.library.ryerson.ca\/wafd\/chapter\/6-5-activity-13-accessible-tree-navigation\/\">Activity 13 <\/a> operate and announce itself like the one in the video.\r\n\r\n<strong>Video: <a href=\"https:\/\/www.youtube.com\/watch?v=YT6a_vp2Es0\" rel=\"noopener\">Accessible Tree Menu<\/a><\/strong>\r\n\r\n[embed]https:\/\/www.youtube.com\/embed\/YT6a_vp2Es0[\/embed]","rendered":"<p>Tree menus often have the same underlying HTML structure as a menu bar, but rather than being arranged in a horizontal layout, they tend to be arranged vertically.<\/p>\n<div class=\"textbox\">\n<p><strong>WAI-ARIA roles, states, and properties used in a tree menu<\/strong><\/p>\n<p><code><code><code><\/code><\/code><\/code><\/p>\n<ul>\n<li>tabindex = [0 | -1]<\/li>\n<li>aria-labelledby = [instruction div id | title div id]<\/li>\n<li>aria-hidden = [true | false]<\/li>\n<li>role = &#8220;tree&#8221;<\/li>\n<li>role = &#8220;treeitem&#8221;<\/li>\n<li>role = &#8220;presentation&#8221;<\/li>\n<li>aria-level = [number of parent ULs]<\/li>\n<li>aria-setsize = [number of LIs in a level]<\/li>\n<li>aria-posinset = [position of each LI in a set]<\/li>\n<li>aria-expanded = [true | false]<\/li>\n<li>aria-selected = [true | false]<\/li>\n<\/ul>\n<p><code><code><\/code><\/code><\/p>\n<\/div>\n<div style=\"margin: 1em 0; padding: 1em; border: 1px solid #ddd; border-left: 10px solid #0000ff;\"><strong>Suggested Reading:<\/strong> For more about accessible tree menus, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/treeview\/\">ARIA Authoring Practices Guide: Tree View<\/a><\/div>\n<p>The following JSFiddle presents a typical tree menu widget with a few submenus. Review the JavaScript and HTML markup. Test the tree menu presented under the Result tab with ChromeVox to understand how it functions without any accessibility features added. You can work in JSFiddle itself by clicking \u201cEdit in JSFiddle\u201d\u00a0at the top, right-hand side, copying the accessibility\/WAI-ARIA code described below to fix the accessibility of the tree menu before completing <a href=\"https:\/\/pressbooks.library.torontomu.ca\/wafd\/chapter\/6-5-activity-13-accessible-tree-navigation\/\">Activity 13<\/a> on the page that follows.<\/p>\n<div style=\"height: 600px; overflow: hidden;\">\n<div id=\"h5p-91\">\n<div class=\"h5p-content\" data-content-id=\"91\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/jsfiddle.net\/greggy\/z5d3pt8m\/embedded\/ --><\/p>\n<p>First, define instructions on using the tree menu with a keyboard.<\/p>\n<div style=\"height: 165px; overflow: hidden;\">\n<div id=\"h5p-92\">\n<div class=\"h5p-content\" data-content-id=\"92\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/MpTQfKSH\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function add keyboard focus to the tree container by applying <code>tabindex=\"0\"<\/code> to it, and label the container with the instructions created above, which gets read by screen readers when the menu initially receives focus.<\/p>\n<div style=\"height: 160px; overflow: hidden;\">\n<div id=\"h5p-93\">\n<div class=\"h5p-content\" data-content-id=\"93\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/dJSCJdHT\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function, hide the instructions <code>&lt;div&gt;<\/code> from screen readers by default by setting <code>aria-hidden=\"true\"<\/code> when the tree menu is initialized.<\/p>\n<div style=\"height: 220px; overflow: hidden;\">\n<div id=\"h5p-94\">\n<div class=\"h5p-content\" data-content-id=\"94\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/u2K6J4Yc\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function replace the unordered list semantics with tree menu semantics using <code>role=\"tree\"<\/code>, and give it a title using <code>aria-labelledby<\/code> to reference the title defined in the default options.<\/p>\n<div style=\"height: 175px; overflow: hidden;\">\n<div id=\"h5p-95\">\n<div class=\"h5p-content\" data-content-id=\"95\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/PLUjFAj8\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function, define menu items with <code>role=\"treeitem\"<\/code>, remove all keyboard access by default with <code>tabindex=\"-1\"<\/code>, set the number of levels in the tree based on the number of parent ULs with <code>aria-level=[number of ULs]<\/code>, set the number of tree items on a given level with <code>aria-setsize=\"[number of LIs in a UL]\"<\/code>, and finally define the position of each tree item within a level using <code>aria-posinset=\"[child LI index]\"<\/code>.<\/p>\n<div style=\"height: 225px; overflow: hidden;\">\n<div id=\"h5p-96\">\n<div class=\"h5p-content\" data-content-id=\"96\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/bFp57Zz4\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function, if a tree item has a submenu UL that has been opened, set <code>aria-expanded=\"true\"<\/code>, otherwise set <code>aria-expanded=\"false\"<\/code>.<\/p>\n<div style=\"height: 315px; overflow: hidden;\">\n<div id=\"h5p-97\">\n<div class=\"h5p-content\" data-content-id=\"97\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/S9ATtr2j\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function, for each tree item use the text of the associated <code>span<\/code> element as its label. To ensure both the label and the contents of the <code>span<\/code> element are not both read, assign <code>role=\"presentation\"<\/code> to the <code>span<\/code>.<\/p>\n<div style=\"height: 290px; overflow: hidden;\">\n<div id=\"h5p-98\">\n<div class=\"h5p-content\" data-content-id=\"98\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/Ek1gXu1u\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function, where mouse <code>onclick<\/code> functionality is used, provide equivalent <code>keydown<\/code> functionality, here referencing the <code>onKeyDown<\/code> function, shown below, that defines the keys to operate the menu.<\/p>\n<div style=\"height: 70px; overflow: hidden;\">\n<div id=\"h5p-99\">\n<div class=\"h5p-content\" data-content-id=\"99\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/iFrns2Um\/noheader --><\/p>\n<p>Within the <code>init()<\/code> function, right after adding <code>keydown<\/code> operability, make the first item in the tree menu focusable by adding <code>tabindex=\"0\"<\/code> to the first <code>li<\/code>.<\/p>\n<div style=\"height: 115px; overflow: hidden;\">\n<div id=\"h5p-100\">\n<div class=\"h5p-content\" data-content-id=\"100\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/JAi5989n\/noheader --><\/p>\n<p>Within the <code>selectItem()<\/code> function, set up a roving tabindex, while at the same time applying <code>aria-selected=[true | false]<\/code> when tree items receive or lose focus.<\/p>\n<div style=\"height: 640px; overflow: hidden;\">\n<div id=\"h5p-101\">\n<div class=\"h5p-content\" data-content-id=\"101\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/W9R8UbKq\/noheader --><\/p>\n<p>In the <code>toggleSubmenu()<\/code> function, announce the state of submenus to the screen reader by toggling the <code>aria-expanded=[true | false]<\/code> attribute when a menu is opened or closed.<\/p>\n<div style=\"height: 425px; overflow: hidden;\">\n<div id=\"h5p-102\">\n<div class=\"h5p-content\" data-content-id=\"102\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/9HdKXj82\/noheader --><\/p>\n<h2>Adding Keyboard Operability<\/h2>\n<p>Much like the menu bar described in the previous activity, keyboard operability for a tree menu can be complex, with various operations using multiple key strokes to perform the same function. W3C describes potential keyboard operation in the <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/treeview\/#keyboard-interaction-24\">ARIA Authoring Practices Guide<\/a>, reproduced below.<\/p>\n<div class=\"textbox\">\n<h3>Tree Menu Keyboard Interaction<\/h3>\n<p>For a vertically oriented tree:<\/p>\n<ul>\n<li>When a single-select tree receives focus:\n<ul>\n<li>If none of the nodes are selected before the tree receives focus, focus is set on the first node.<\/li>\n<li>If a node is selected before the tree receives focus, focus is set on the selected node.<\/li>\n<\/ul>\n<\/li>\n<li>When a multi-select tree receives focus:\n<ul>\n<li>If none of the nodes are selected before the tree receives focus, focus is set on the first node.<\/li>\n<li>If one or more nodes are selected before the tree receives focus, focus is set on the first selected node.<\/li>\n<\/ul>\n<\/li>\n<li>Right Arrow:\n<ul>\n<li>When focus is on a closed node, opens the node; focus does not move.<\/li>\n<li>When focus is on a open node, moves focus to the first child node.<\/li>\n<li>When focus is on an end node, does nothing.<\/li>\n<\/ul>\n<\/li>\n<li>Left Arrow:\n<ul>\n<li>When focus is on an open node, closes the node.<\/li>\n<li>When focus is on a child node that is also either an end node or a closed node, moves focus to its parent node.<\/li>\n<li>When focus is on a root node that is also either an end node or a closed node, does nothing.<\/li>\n<\/ul>\n<\/li>\n<li>Down Arrow: Moves focus to the next node that is focusable without opening or closing a node.<\/li>\n<li>Up Arrow: Moves focus to the previous node that is focusable without opening or closing a node.<\/li>\n<li>Home: Moves focus to the first node in the tree without opening or closing a node.<\/li>\n<li>End: Moves focus to the last node in the tree that is focusable without opening a node.<\/li>\n<li>Enter: Activates a node, i.e., performs its default action. For parent nodes, one possible default action is to open or close the node. In single-select trees where selection does not follow focus (see note below), the default action is typically to select the focused node.<\/li>\n<li>Type-ahead is recommended for all trees, especially for trees with more than 7 root nodes:\n<ul>\n<li>Type a character: focus moves to the next node with a name that starts with the typed character.<\/li>\n<li>Type multiple characters in rapid succession: focus moves to the next node with a name that starts with the string of characters typed.<\/li>\n<\/ul>\n<\/li>\n<li>* (Optional): Expands all siblings that are at the same level as the current node.<\/li>\n<li><strong>Selection in multi-select trees:<\/strong> Authors may implement either of two interaction models to support multiple selection: a recommended model that does not require the user to hold a modifier key, such as Shift or Ctrl, while navigating the list or an alternative model that does require modifier keys to be held while navigating in order to avoid losing selection states.\n<ul>\n<li>Recommended selection model \u2013 holding a modifier key while moving focus is not necessary:\n<ul>\n<li>Space: Toggles the selection state of the focused node.<\/li>\n<li>Shift + Down Arrow (Optional): Moves focus to and toggles the selection state of the next node.<\/li>\n<li>Shift + Up Arrow (Optional): Moves focus to and toggles the selection state of the previous node.<\/li>\n<li>Shift + Space (Optional): Selects contiguous nodes from the last selected node to the current node.<\/li>\n<li>Ctrl + Shift + Home (Optional): Selects the node with focus and all nodes up to the first node.<\/li>\n<li>Ctrl + Shift + End (Optional): Selects the node with focus and all nodes down to the last node.<\/li>\n<li>Ctrl + A (Optional): Selects all nodes in the tree. Optionally, if all nodes are selected, it can also unselect all nodes.<\/li>\n<\/ul>\n<\/li>\n<li>Alternative selection model \u2013 moving focus without holding the Shift or Ctrl modifier unselects all selected nodes except for the focused node:\n<ul>\n<li>Shift + Down Arrow: Moves focus to and toggles the selection state of the next node.<\/li>\n<li>Shift + Up Arrow: Moves focus to and toggles the selection state of the previous node.<\/li>\n<li>Ctrl + Down Arrow: Without changing the selection state, moves focus to the next node.<\/li>\n<li>Ctrl + Up Arrow: Without changing the selection state, moves focus to the previous node.<\/li>\n<li>Ctrl + Space: Toggles the selection state of the focused node.<\/li>\n<li>Shift + Space (Optional): Selects contiguous nodes from the most recently selected node to the current node.<\/li>\n<li>Ctrl + Shift + Home (Optional): Selects the node with focus and all nodes up to the first node.<\/li>\n<li>Ctrl + Shift + End (Optional): Selects the node with focus and all nodes down to the last node.<\/li>\n<li>Ctrl + A (Optional): Selects all nodes in the tree. Optionally, if all nodes are selected, it can also unselect all nodes.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div>\n<div style=\"margin: 1em 0; padding: 1em; border: 1px solid #ddd; border-left: 10px solid #3c3;\">\n<div id=\"h-note-27\" class=\"note-title marker\" role=\"heading\"><strong>Note:<\/strong><\/div>\n<ol class=\"\">\n<li>DOM focus (the active element) is functionally distinct from the selected state. For more details, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/practices\/keyboard-interface\/#kbd_focus_vs_selection\">this description of differences between focus and selection.<\/a><\/li>\n<li>The <code>tree<\/code> role supports the <a class=\"property-reference\" href=\"https:\/\/www.w3.org\/TR\/wai-aria-1.1\/#aria-activedescendant\">aria-activedescendant<\/a> property, which provides an alternative to moving DOM focus among <code>treeitem<\/code> elements when implementing keyboard navigation. For details, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/practices\/keyboard-interface\/#kbd_focus_activedescendant\">Managing Focus in Composites Using aria-activedescendant<\/a>.<\/li>\n<li>In a single-select tree, moving focus may optionally unselect the previously selected node and select the newly focused node. This model of selection is known as &#8220;selection follows focus&#8221;. Having selection follow focus can be very helpful in some circumstances and can severely degrade accessibility in others. For additional guidance, see <a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/practices\/keyboard-interface\/#kbd_selection_follows_focus\">Deciding When to Make Selection Automatically Follow Focus<\/a>.<\/li>\n<li>If selecting or unselecting all nodes is an important function, implementing separate controls for these actions, such as buttons for &#8220;Select All&#8221; and &#8220;Unselect All&#8221;, significantly improves accessibility.<\/li>\n<li>If the nodes in a tree are arranged horizontally:\n<ol>\n<li>Down Arrow performs as Right Arrow is described above and vice versa.<\/li>\n<li>Up Arrow performs as Left Arrow is described above and vice versa.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/div>\n<p><a href=\"https:\/\/www.w3.org\/WAI\/ARIA\/apg\/patterns\/treeview\/#keyboard-interaction-24\">Source: ARIA Authoring Practices Guide<\/a><\/p>\n<\/div>\n<\/div>\n<p>For the tree menu created here, we\u2019ve added in basic keyboard operability. Keyboard operation includes: Up and Down, and Left and Right Arrows for navigating within the tree, and the Enter or Space bar keys to toggle submenus open or closed. The Tab key by default enters and exits the tree menu and does not need to be defined as part of the keyboard operability of the tree menu.<\/p>\n<div style=\"height: 1500px; overflow: hidden;\">\n<div id=\"h5p-103\">\n<div class=\"h5p-content\" data-content-id=\"103\"><\/div>\n<\/div>\n<\/div>\n<p><!--https:\/\/pastebin.com\/embed_iframe\/fhdx9mtc\/noheader --><\/p>\n<h2>Accessible Tree Menu in Action<\/h2>\n<p>Watch the following video showing ChromeVox interacting with a tree menu. The Tab key is used to navigate into the tree menu, to the first tree item, and to exit the tree menu. The Up and Down arrows are used to move between tree items. The Space bar or Enter key are used to expand and collapse a tree item with a submenu. When a submenu is opened, focus moves to the first tree item in the menu. Aim to have the tree menu you update in\u00a0\u00a0<a href=\"https:\/\/pressbooks.library.ryerson.ca\/wafd\/chapter\/6-5-activity-13-accessible-tree-navigation\/\">Activity 13 <\/a> operate and announce itself like the one in the video.<\/p>\n<p><strong>Video: <a href=\"https:\/\/www.youtube.com\/watch?v=YT6a_vp2Es0\" rel=\"noopener\">Accessible Tree Menu<\/a><\/strong><\/p>\n<p><iframe loading=\"lazy\" id=\"oembed-1\" title=\"Accessible Tree Menu\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/YT6a_vp2Es0?feature=oembed&#38;rel=0\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n","protected":false},"author":100,"menu_order":4,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-374","chapter","type-chapter","status-publish","hentry"],"part":37,"_links":{"self":[{"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/chapters\/374","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/wp\/v2\/users\/100"}],"version-history":[{"count":85,"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/chapters\/374\/revisions"}],"predecessor-version":[{"id":2028,"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/chapters\/374\/revisions\/2028"}],"part":[{"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/parts\/37"}],"metadata":[{"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/chapters\/374\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/wp\/v2\/media?parent=374"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/pressbooks\/v2\/chapter-type?post=374"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/wp\/v2\/contributor?post=374"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/pressbooks.library.torontomu.ca\/wafd\/wp-json\/wp\/v2\/license?post=374"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}