Is a role="group" valid under a role="tree" - accessibility

Lets say I have an element with role="tree". Under that I have an element role="group" which contains elements with role="treeitem" or role="group" for multilevel tree.
<... role="tree">
<... role="group">
<... role="treeitem">
<... role="treeitem">
<... role="group">
<... role="treeitem">
<... role="treeitem">
The issue here is that that the accessibility test tool is complaining that the element with role="tree" must contain a child element with role="treeitem".
Looked up the spec and it says
Required Owned Elements:
group → treeitem
treeitem
How do I interpret this? Should a tree contain a treeitem directly? could tree have a group which contains tree items but the tree has no direct children with role "treeitem"?
-- EDIT--
Here is the complete html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Tree A11y</title>
</head>
<body>
<div role="main">
<!-- tree contains a group which contains treeitems/group -> treeitems -->
<ul role="tree">
<ul role="group">
<li role="treeitem">Banana</li>
<li role="treeitem">Mango</li>
<ul role="group">
<li role="treeitem">Banana-2</li>
<li role="treeitem">Mango-2</li>
<li role="treeitem">Orange-2</li>
</ul>
</ul>
</ul>
<!-- tree contains a treeitems or groups which contains treeitem -->
<ul role="tree">
<li role="treeitem">Banana</li>
<li role="treeitem">Mango</li>
<ul role="group">
<li role="treeitem">Banana-2</li>
<li role="treeitem">Mango-2</li>
<li role="treeitem">Orange-2</li>
</ul>
</ul>
</div>
</body>
</html>
The question here is
Should an element with a role "tree" must contain one or more "treeitems"?
Can it contain a "group" which contains "treeitems?"
In the first tree
Tree has a group, no direct children of role treeitem
The group has tree items and a group which has other tree items
This is reported as an error WCAG 1.3.1. However, the screen readers seem to be working fine
In the second tree
Tree has a tree items and a group which has other tree items
In the spec, I am not able to find a definite statement that tree must conatin 1 or more DIRECT children with a role treeitem. So I am not certain that the first tree has an actual accessibility issue and if the first tree is violating the spec.
FWIW, there is a control called JSTree which is using the style as shown in first tree, and I am debating if that is a real issue or not. Thanks.

Short Answer
Although it is valid HTML and WAI-ARIA to have a group as the direct descendant of a tree it is not the intended or recommended use if it not associated with a corresponding treeitem.
It is an allowed child of role="tree" due to different ways a tree can be constructed.
Long Answer
Firstly it is perfectly "valid" (it is valid markup) to have a role="group" as the only descendant of a role="tree".
However although valid it is not the recommended way of doing things and may result in unexpected behaviour depending on the screen reader and browser combination in use.
The key point is that in the WAI-ARIA best practices document it states that:
Each root node is contained in the element with role tree or referenced by an aria-owns property set on the tree element.
So the second you put the top level nodes into a role="group" you break this rule unless you give each of the treeitems in your group an id and then use aria-owns on the role="tree". At which point the group becomes pointless anyway as you have bypassed it.
So why allow a role="group" as a descendant of role="tree" if it is not recommended?
Now you could argue that if it wasn't valid to have a group as a top-level item in a role="tree" that it shouldn't be allowed in the first place.
However, the reason that role="group" is allowed at the top level is that you can set a treeitem to open a group and these can be on the same level (siblings).
I think I can explain this best with an example:-
Code Example 1 - valid as the group has a parent treeitem and so does not act as a root node.
<div id="tree1" role="tree" tabindex="-1">
<div role="treeitem" aria-owns="pizzaGroup" aria-expanded="false" tabindex="0">Pizza Toppings</div>
<ul role="group" id="pizzaGroup">
<li role="treeitem">Cheese</li>
<li role="treeitem">Pepperoni</li>
<li role="treeitem">Onion</li>
</ul>
</div>
In the example above the first div acts as the treeitem and the group is controlled by it. The association is made with aria-owns.
The reason it states that it must contain group -> treeitem is because an empty group is not allowed.
The above is a valid example of a role="tree", however I would not recommend that pattern if you can avoid it as support for aria-owns is not great.
The accepted practice is to have the group nested within the treeitem itself and to use <ul> and <li> throughout. Most screen readers will automatically associate the child nodes with the parent node and those that don't still have a way for their users to workout the relationship as nested <ul> and <li> are well supported.
Example 2 - an example of the recommended pattern using <ul> and <li>
<ul role="tree">
<li role="treeitem" aria-expanded="false" tabindex="0">
<span>Pizza Toppings</span>
<ul role="group">
<li role="treeitem">Cheese</li>
<li role="treeitem">Pepperoni</li>
<li role="treeitem">Onion</li>
</ul>
</li>
</ul>
Hopefully that answers why the accessibility tool was complaining about not having a treeitem and why you can have a group as a child of a tree but only if it is controlled by an associated treeitem.
Final Thoughts
In your example you haven't provided a label for your tree. Don't forget to add a label to the main element eith role="tree", either a visible label and aria-labelledby="yourLabelID" (preferable) or with an aria-label="description of tree".
Update after discussions in chat
If only guidance was more clear!
As pointed out my supporting information for a "root node" is still not clear and it is fair to comment it could still interpreted that a group can be a root node from that definition.
However further up in the definition of a treeview, coupled with another of the rules, there is enough clarity to confirm that it is in fact impossible for a group to be counted as a root node at all!
These are the definitions of nodes in a tree:
Node
An item in a tree.
Root Node
Node at the base of the tree; it may have one or more child nodes but does not have a parent node.
Child Node
Node that has a parent; any node that is not a root node is a child node.
Parent Node
Node with one or more child nodes. It can be open (expanded) or closed (collapsed).
Take the following rule:
Each child node is contained in or owned by an element with role group that is contained in or owned by the node that serves as the parent of that child.
You therefore cannot count a group as a root node (or any node) under any circumstances, it cannot have a parent and so contravenes the above rule.
Let me explain why this is the case and why you can never treat a group as a root node:
The second you add a treeitem to a group the following must be true:
it must be a child node as it is not a root node.
each child node must be contained or owned by a role="group" that must be contained or owned by a node that serves as the parent of the newly added treeitem.
A root item can have no parent node and our group requires a parent to be valid.
Example 3 - not valid as the group has no parent node and would have to act as a root node (which it cannot).
<div role="tree">
<!--this group is a root level node and does not have a parent node. -->
<div role="group">
<!--This treeitem must be within a "group" as it is a child node. -->
<!--This means that the "group" above contains it and that means the group above must be owned or controlled by something.-->
<!--This treeitem can never have a parent as root level nodes cannot have a parent node.-->
<div role="treeitem">item</div>
</div>
</div>
Also the following takes all of the ambiguity away as far as I am concerned:
Each element serving as a tree node has role treeitem.
So my original premise was correct for why a group is allowed as a top level item in a tree.
In fact it is even more clear, a group can never be a root node (or a node at all as you cant have role="treeitem group"!) and the only reason a group can appear as a direct descendant of a tree is if it is a sibling with a treeitem that controls it (it's parent) as I originally said.

Required Owned Elements:
group → treeitem
treeitem
The documentation of treeitem will help you understand this subject
Authors MUST ensure elements with role treeitem are contained in, or owned by, an element with the role group or tree.
This means that leaves of a tree item must all be treeitem.
Those treeitem can be directly under the tree item or any level of group items.
You can't have a treeitem under a treeitem

Related

BEM naming convention for nested tiny parts

Just started coding with BEM naming methodology. I wondered how to name nested tiny parts.
I attached sample layout below, please take a look.
There are two spans inside h3 and I want them to have different style.
Then shall I just name them like they belong to their parent:
class="en product-lineup__title-en"
class="non-en product-lineup__title-non-en"
or like they belong to their title (but it looks like BEEM...):
class="en product-lineup__title__en"
class="non-en product-lineup__title__non-en"
or just leave it blank then in CSS
.product-lineup__title span:first-child
.product-lineup__title span:nth-child(2)
Which is the best way or do I misunderstand BEM rule in the first place?
BEM is a methodology about reusable blocks. If you see a visual pattern that is repeated in the UI, then you should consider to see it as a block, not an element. Elements are the block details.
For your wireframe, I suggest two blocks: the lineup block is responsible for the global layout:
<ul class="lineup">
<li class="lineup__item"></li>
<li class="lineup__item"></li>
…
</ul>
In each <li>, there is an instance of a product block:
<article class="product">
<img class="product__img">
<h3 class="product__title">…</h3>
<div class="product__text">…</div>
</article>
If you want to keep your current HTML structure, then you have a mix on <li> markups:
<ul class="lineup">
<li class="lineup__item product">
<img class="product__img">
<h3 class="product__title">…</h3>
<div class="product__text">…</div>
</li>
…
</ul>
Here the lineup__item CSS class is responsible for positioning the child block product in the parent block linup. A block should not position by itself (it wouldn't be reusable).
Then, your element product__title has two children en and non-en. With BEM, an element cannot be parent of other elements. But it can nest brother elements. You can do:
<h3 class="product__title">
<span class="product__title-en"></span>
<span class="product__title-non-en"></span>
</h3>
In the BEM tree, title, title-en, title-non-en are all child elements of the product block. It is the light solution.
But maybe you'll realize that this kind of dual titles is a visual pattern used outside the product block, or maybe just for clarity, you can decide to make a dual-title block for that.
<h3 class="product__title dual-title">
<span class="dual-title__en"></span>
<span class="dual-title__non-en"></span>
</h3>
Here the CSS class product__title is responsible for positioning the child block dual-title in the parent block product.

Must role="tab" be the direct child of a role="tablist"?

I have an accordion which is structured like:
<section... role="tablist">
<div>
<h3 role="tab">Title</h3>
<div role="tabpanel">
...
</div>
</div>
</section>
Does tab have to be a direct child of the tablist to conform to wai aria best practices or is it okay to be wrapped in a div?
Authors MUST ensure elements with role tab are contained in, or owned by, an element with the role tablist.
https://www.w3.org/TR/wai-aria-1.1/#tab
Your example is therefore correct.
I would suggest you read through the spec to ensure you are following best ARIA practice.
For example adding the role on a div as opposed to a section element, as per the best practice example.

Add indentation to lineage in GSP page

I am trying to list a descendancy starting from root and printing its children's children. The domain looks something like
class Node {
String nodeId
String label
Node parent
}
Note I dont have a reference to child instead i have a reference to its parent.
In the GSP page I want to list the entire lineage but I am not able to get proper indentation where each node will have an indent for its child. Basically need some kind of checking condition that if the previous node is the parent of the next node give it an indent otherwise find the parent of next node and put it there accordingly.
<concepts>
<g:each in="${nodes}" var="node">
<concept id="${node.id}" description ="${node.label}">
</concept>
</g:each>
</concepts>
Something like (ignore the text. i need a structure like this
This is related to: Recursion in GSP page
Update the _node.gsp template:
<g:if test="${nodes}">
<ul>
<g:each in="${nodes}" var="node">
<li>
${node}
<g:render template="node" model="[nodes:Node.findAllByParent(node)]" />
</li>
</g:each>
</ul>
</g:if>
And style accordingly.

How create CSS Selector which selects the Xn tag including descendants

Say I have the following DOM tree:
<div class="box">
<ul class="gallery">
<li id="1">text</li>
<li id="2">text</li>
<li id="3">text</li>
<li id="4">text</li>
<li id="5">text</li>
<li id="6">text</li>
<li id="7">text</li>
<li id="8">text</li>
<li id="9">text</li>
</ul>
<div id="random"></div>
<ul class="gallery">
<li id="10">text</li>
<li id="11">text</li>
<li id="12">text</li>
<li id="13">text</li>
<li id="14">text</li>
<li id="15">text</li>
<li id="16">text</li>
<li id="17">text</li>
<li id="18">text</li>
<li id="19">text</li>
<li id="20">text</li>
</ul>
</div>
I want to create a CSS selector that will pick every 6th <li> tag under the div with the class "box". But I need the selector to take into account the entire <li> tags in the page and not to count them per <ul> tag. So in the end, the selector should pick the <li> with IDs 6,12,18. Currently I was only able to create a selector that picks IDs 6 & 15 when I used:
div.box li:nth-of-type(6n)
Notice 1: the IDs numbers are only added for reference. In reality the <li> tags don't have a class or an ID.
Notice 2: the number of <li> tags in each <ul> tag varies from site section to site section. Sometimes there can be even a 3rd and a 4th </ul> with more <li> tags.
Notice 3: I don't have control over the hard-coded HTML, which means I cannot unify tags, add IDs or CSS classes, etc. The selector will be called from an external JS file. While I can edit the DOM with jQuery after the page loads, I prefer to avoid such a solution to make the selector easier to handle.
Thanks
Generally Agree Impossible, except...
I basically agree with Sych and Fabrício that it is not currently possible to do as a pure CSS solution. However, there are always some exceptions, depending on actual html structure.
In your case, there may be an exception, but it does depend on the full constraints of your situation.
When Would it Be Possible?
Based off your given code, if these two constraints are true, then you can still get what you want via CSS:
All ul items that are direct children of .box are of class .gallery.
All gallery groups (except perhaps the very last one) consist of exactly nine li elements (both groups in your example do, but I don't know if that was coincidence or how you are actually setting up your code).
If the above two factors in your html are true, then this code gets what you want (using color to show selection here):
ul.gallery:nth-of-type(2n+1) li:nth-of-type(6n) {
color: red;
}
ul.gallery:nth-of-type(2n+2) li:nth-of-type(6n+3) {
color: red;
}
You can see it works on the code you gave in this fiddle, then you can see it continues to work given an expansion of the html as this fiddle shows, even if the final list is short of nine as both this fiddle and this fiddle shows, but it will fail if the .gallery varies in length at some midpoint of the sequence, as seen in this fiddle (notice how the last two selected texts are not 6 apart from each other because the second to last .gallery has only 7 items).
The Overarching Principle
So in general, if your dynamic html is output in some type of a regular pattern as demonstrated here, then it can open up the possibility of a pure css solution along the lines of that given. It is when the dynamic generation is also fully random (so in your case if either #1 or #2 condition above is not guaranteed true) that a pure css solution is impossible.
CSS does not provide such scope, it only provides traversing "deeper in to the DOM" tree. It does not even have a parent element selector.
If you are in jQuery environment, you can write your own selector, call it, say, ":nth-from-top(n)" that will work using jQuery's DOM traversing functions.
Note, that this type of selector will be much slower, because it cannot take advantage of the performance boost provided by the native DOM methods.
nth-child and nth-of-type match based in the element's position relative to its siblings only.
As far as I know there's currently no CSS-only solution for that unless all lis had the same parent. You will have to add a class to every 6th element or use some JavaScript.
So, constraining the answer to CSS selectors only without altering the markup and without hardcoding the nth start indexes: impossible. I'd like to be proven wrong though.
Looking by the bright side, adding a class will provide better selector performance. nth-child is already considered inefficient, now if what you want would be possible it'd mean that browsers would be forced to recursively evaluate selectors and count matches each time the DOM is updated. Though this would be terrible performance wise, I believe it'd still be possible to implement through new "scoped" nth selectors a la CSS Counters. Just food for thought.

How to render a hierarchy tree in HTML5/CSS?

I have not done any web development as of late. Was wondering if there is an easy way to load a data representation of a hierarchy tree such as
node parent
---------------------------------
root
Level1.Node1 root
Level1.Node2 root
Level1.Node3 root
Level2.Node1 Level1.Node1
Level2.Node2 Level1.Node2
Level2.Node3 Level1.Node2
And get it rendered like
root
--------Level1.Node1
--------------Level2.Node1
--------Level1.Node2
--------------Level2.Node2
--------------Level2.Node3
without using fancy tables?
Use styled and nested unordered lists.
<ul>
<li>Level 1
<ul>
<li>Level 2</li>
</ul>
</li>
</ul>
Practically you just want to keep on checking the Parent's Children. This is not a HTML5/CSS thing, but a JavaScript thing to check the DOM (node) roots.
Use the WebKit/Firebug tools to dump out the HTML DOM Object and see it's attributes. You can see what their properties and methods are and use them to iterate through them until you hit the bottom of each subtag.
console.log(document);
console.log(document.head);
These just return the HTML blocks.
console.log(document.body);
This returns the actual DOM object. You can see in the inspector that you actually get back tons of info to parse on.
Check [children] and [childNodes]. That's where you want to iterate your DOM structure.
[nodeName] and [nodeType] help you identify the attributes.
Printing it out you can do with placeholders var offset = ' '; and reloop them or use CSS to render <div> tags with mathematical calculated left-margins.

Resources