Closed Bug 1619092 Opened 2 years ago Closed 1 year ago

display:contents and role="presentation" don't work together for tbody

Categories

(Core :: Disability Access APIs, defect, P1)

73 Branch
defect

Tracking

()

VERIFIED FIXED
84 Branch
Tracking Status
firefox84 --- verified

People

(Reporter: streltsyn, Assigned: eeejay)

References

(Blocks 1 open bug)

Details

(Whiteboard: [mac2020_2])

Attachments

(2 files)

Attached image bug.png

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0

Steps to reproduce:

  1. Open the HTML page with the following code and default styling:

<table role="table">
<tbody>
<tr role="row">
<td>One</td>
</tr>
<tr role="presentation">
<td role="presentation">
<table role="presentation">
<tbody role="presentation">
<tr role="row">
<td>Two</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>

  1. Inspect the Accessibility properties of the external table element (via developer tools)

  2. Change the style of the elements with role="presentation" to display: contents.

  3. Inspect the Accessibility properties of the external table element again.

Link to the testcase with both examples: https://cdpn.io/SelenIT/debug/abOwZwq/dGrXWKaOzBKM

Actual results:

With default styles, the Accessibility tree for the "table" element has two direct "row" children.

After the style change, the Accessibility tree for the "table" element has one "row" child and one "nothing" child. The second row is the child of this "nothing" node. The Properties tab reports that this "nothing" node corresponds to the tbody element.

Expected results:

In both cases, the table should have two "row" children. CSS display (except the "none" value) should have no effect on the accessibility semantics (https://www.w3.org/TR/css-display-3/#the-display-properties).

Hi streltsyn,

Thanks for your report.

I tried to open the test case but the link seems to have expired. Could you provide us with a new one?

Also, please let us know if you are able to reproduce the issue when using the latest Firefox Nightly. You can download it from here: https://nightly.mozilla.org/

Thanks!
Virginia

Flags: needinfo?(streltsyn)

The link seems to work for me, maybe it was a temporary problem? Doesn't it open in CodePen editor mode (https://codepen.io/SelenIT/pen/abOwZwq)?

Anyway, the code demonstrating the problem is already in the description. The only difference that caused the behavior that I believe is incorrect is adding the [role="presentation"] { display: contents; } CSS style to the same markup.

Flags: needinfo?(streltsyn)

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: Untriaged → Accessibility Tools
Product: Firefox → DevTools

This belongs in Disability Access APIs. And it has to do (once again) how we create and handle table and related elements in various conditions.

Blocks: tablea11y
Component: Accessibility Tools → Disability Access APIs
OS: Unspecified → All
Product: DevTools → Core
Hardware: Unspecified → All

I agree this behaviour is broken. That said, I'm curious: why set both display: contents and role presentation? My understanding is that the point of display: contents is to prevent the node from having any impact on layout; i.e. you still want it to have semantic impact, but no layout impact. But if you're applying role presentation, you're saying you don't want it to have semantic impact. So, why include the node at all?

Flags: needinfo?(streltsyn)
Priority: -- → P3

This example was part of the experimenting where I tried to implement the TreeTable-like control using nested actual tables and collapsing/expanging the hierarchy levels by changing the display of intermediate wrappers from none to contents and back (example: https://codepen.io/SelenIT/pen/wvadgJK). This approach seemed promising because of its simplicity comparing to the usual approach with storing the hierarchy data in HTML classes, but Firefox didn't treat the rows of the resulting dynamic table as same-table rows. In Chrome, it seemed to work as I expected.

Flags: needinfo?(streltsyn)

Chrome never exposes tbody elements in the accessible tree, no matter their style (or even other interesting attributes like role or id). I think it makes sense to adopt that behavior in Gecko too. It would fix bugs like this, and remove intermediate groups that interfere with a properly structured table. For example, VoiceOver does not like seeing anything but AXColumn and AXRow as children of a table.

Assignee: nobody → eitan

(In reply to Eitan Isaacson [:eeejay] from comment #7)

Chrome never exposes tbody elements in the accessible tree, no matter their style (or even other interesting attributes like role or id).

As per our chat, it does on Windows if there is a role at least. I didn't check id, focusable, etc. However, I still agree there's no point in exposing it if there isn't something like role.

Whiteboard: [mac2020_2]
Priority: P3 → P1
Pushed by eisaacson@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/6abea0908b00
Don't expose tbody/tfoot/thead as intermediate groups. r=Jamie

Backed out changeset 6abea0908b00 (bug 1619092) for test_table_3 failures.

Push with failures: https://treeherder.mozilla.org/jobs?repo=autoland&group_state=expanded&searchStr=a11y&fromchange=c1d158fe6028f812cb79dc54848d99641371d08a&tochange=aa3fa371af2fa7c3d62cebfe38faed40719c1792&selectedTaskRun=WI5hhDwqRamdDe3Ta5j7Ug.0

Backout link: https://hg.mozilla.org/integration/autoland/rev/aa3fa371af2fa7c3d62cebfe38faed40719c1792

Failure log: https://treeherder.mozilla.org/logviewer?job_id=320495745&repo=autoland&lineNumber=6612

[task 2020-11-02T18:05:56.157Z] 18:05:56     INFO - TEST-START | accessible/tests/mochitest/tree/test_table_3.html
[task 2020-11-02T18:05:56.165Z] 18:05:56     INFO - GECKO(1514) | [1514, Main Thread] WARNING: 'NS_FAILED(targetPrincipal->GetAsciiOrigin(targetOrigin))', file /builds/worker/checkouts/gecko/toolkit/components/antitracking/AntiTrackingUtils.cpp:347
[task 2020-11-02T18:05:56.222Z] 18:05:56     INFO - GECKO(1514) | [1514, Main Thread] WARNING: Failed to retarget HTML data delivery to the parser thread.: file /builds/worker/checkouts/gecko/parser/html/nsHtml5StreamParser.cpp:1132
[task 2020-11-02T18:05:56.223Z] 18:05:56     INFO - GECKO(1514) | [1514, Main Thread] WARNING: 'NS_FAILED(targetPrincipal->GetAsciiOrigin(targetOrigin))', file /builds/worker/checkouts/gecko/toolkit/components/antitracking/AntiTrackingUtils.cpp:347
[task 2020-11-02T18:05:56.225Z] 18:05:56     INFO - GECKO(1514) | [1514, Main Thread] WARNING: 'NS_FAILED(targetPrincipal->GetAsciiOrigin(targetOrigin))', file /builds/worker/checkouts/gecko/toolkit/components/antitracking/AntiTrackingUtils.cpp:347
[task 2020-11-02T18:05:56.226Z] 18:05:56     INFO - GECKO(1514) | [1514, Main Thread] WARNING: 'NS_FAILED(targetPrincipal->GetAsciiOrigin(targetOrigin))', file /builds/worker/checkouts/gecko/toolkit/components/antitracking/AntiTrackingUtils.cpp:347
[task 2020-11-02T18:05:56.349Z] 18:05:56     INFO - TEST-INFO | started process screentopng
[task 2020-11-02T18:05:56.707Z] 18:05:56     INFO - TEST-INFO | screentopng: exit 0
[task 2020-11-02T18:05:56.707Z] 18:05:56     INFO - Buffered messages logged at 18:05:56
[task 2020-11-02T18:05:56.707Z] 18:05:56     INFO - must wait for load
[task 2020-11-02T18:05:56.708Z] 18:05:56     INFO - TEST-PASS | accessible/tests/mochitest/tree/test_table_3.html | Wrong value of property 'role' for ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280]. 
[task 2020-11-02T18:05:56.709Z] 18:05:56     INFO - Matching { table: [ caption: [ text leaf: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ] , row: [ cell: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ] ]  } and ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] child at index 0 : ['caption node', address: [object HTMLTableCaptionElement], role: caption, address: 0x7f2bb6efbe20]
[task 2020-11-02T18:05:56.709Z] 18:05:56     INFO - Buffered messages finished
[task 2020-11-02T18:05:56.709Z] 18:05:56     INFO - TEST-UNEXPECTED-FAIL | accessible/tests/mochitest/tree/test_table_3.html | { table: [ caption: [ text leaf: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ] , row: [ cell: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ] ]  } and ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] have different children at index 1 : { grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ]  }, ['tr node', address: [object HTMLTableRowElement], role: row, address: 0x7f2bb6f3eb20] 
[task 2020-11-02T18:05:56.709Z] 18:05:56     INFO - SimpleTest.ok@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:417:16
[task 2020-11-02T18:05:56.710Z] 18:05:56     INFO - testAccessibleTree@chrome://mochitests/content/a11y/accessible/tests/mochitest/common.js:580:15
[task 2020-11-02T18:05:56.710Z] 18:05:56     INFO - doTest@chrome://mochitests/content/a11y/accessible/tests/mochitest/tree/test_table_3.html:191:21
[task 2020-11-02T18:05:56.710Z] 18:05:56     INFO - Matching { table: [ caption: [ text leaf: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ] , row: [ cell: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ] ]  } and ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] child at index 1 : ['tr node', address: [object HTMLTableRowElement], role: row, address: 0x7f2bb6f3eb20]
[task 2020-11-02T18:05:56.714Z] 18:05:56     INFO - Matching { table: [ caption: [ text leaf: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ] , row: [ cell: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ] ]  } and ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] child at index 2 : ['tr node', address: [object HTMLTableRowElement], role: row, address: 0x7f2bb6f3ebe0]
[task 2020-11-02T18:05:56.715Z] 18:05:56     INFO - Not taking screenshot here: see the one that was previously logged
[task 2020-11-02T18:05:56.719Z] 18:05:56     INFO - TEST-UNEXPECTED-FAIL | accessible/tests/mochitest/tree/test_table_3.html | { table: [ caption: [ text leaf: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ] , row: [ cell: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ] ]  } and ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] have different children at index 3 : { grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ]  }, ['tr node', address: [object HTMLTableRowElement], role: row, address: 0x7f2bb6f3e3a0] 
[task 2020-11-02T18:05:56.719Z] 18:05:56     INFO - SimpleTest.ok@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:417:16
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - testAccessibleTree@chrome://mochitests/content/a11y/accessible/tests/mochitest/common.js:580:15
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - doTest@chrome://mochitests/content/a11y/accessible/tests/mochitest/tree/test_table_3.html:191:21
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - Matching { table: [ caption: [ text leaf: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] , cell: [ text leaf: [ ] ] ] ] , row: [ cell: [ ] ] , grouping: [ row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] , row: [ cell: [ text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] , cell: [ statictext: [ ] , text leaf: [ ] ] ] ] ]  } and ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] child at index 3 : ['tr node', address: [object HTMLTableRowElement], role: row, address: 0x7f2bb6f3e3a0]
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - Not taking screenshot here: see the one that was previously logged
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - TEST-UNEXPECTED-FAIL | accessible/tests/mochitest/tree/test_table_3.html | ['table@id="table" node', address: [object HTMLTableElement], role: table, address: 0x7f2bb6e70280] has an extra child at index 4 : ['tr node', address: [object HTMLTableRowElement], role: row, address: 0x7f2bb6f3e5e0] 
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - SimpleTest.ok@chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:417:16
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - testAccessibleTree@chrome://mochitests/content/a11y/accessible/tests/mochitest/common.js:567:15
[task 2020-11-02T18:05:56.720Z] 18:05:56     INFO - doTest@chrome://mochitests/content/a11y/accessible/tests/mochitest/tree/test_table_3.html:191:21
[task 2020-11-02T18:05:56.723Z] 18:05:56     INFO - GECKO(1514) | MEMORY STAT | vsize 12419MB | residentFast 700MB | heapAllocated 320MB
[task 2020-11-02T18:05:56.723Z] 18:05:56     INFO - TEST-OK | accessible/tests/mochitest/tree/test_table_3.html | took 201ms
Flags: needinfo?(eitan)
Pushed by eisaacson@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/83390d28389e
Don't expose tbody/tfoot/thead as intermediate groups. r=Jamie
Status: UNCONFIRMED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 84 Branch
Flags: needinfo?(eitan)

Reproduced the initial issue using old Nightly from 2020-10-20, verified that using Firefox 84.0b3 this is no longer an issue across platforms (Windows 10 64bit, macOS 11 and Ubuntu 18.04 64bit).

Status: RESOLVED → VERIFIED
Flags: qe-verify+

Thanks for fixing this!

You need to log in before you can comment on or make changes to this bug.