Skip to content

[a11y][web]: Semantics headingLevel is not working  #156203

Closed

Description

@k0psutin

I don't think the headingLevel is working in Semantics widget?

Try this with MacOS Voice Over:

https://dartpad.dev/?id=a8e32aa25ea01fe79a590b4a9138687e

Try to select heading with voice over, it says that the Flutter Demo Home Page is the last heading. You can't navigate to the second heading with keyboard arrows either.

Originally posted by @k0psutin in #125771 (comment)

Activity

  1. changed the title [-][web]: Semantics headingLevel is not working [/-] [+][a11y][web]: Semantics headingLevel is not working [/+] on Oct 4, 2024
  2. darshankawar commented on Oct 4, 2024

    @darshankawar
    Member

    This is replicable upon running the code on web, wherein, it doesn't read the headingLevel.
    Same goes for desktop as well, for which there's already an issue for tracking: #155928

    Stable : 3.24.3
    Master: 3.26.0-1.0.pre.353
    
  3. added
    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)
    platform-webWeb applications specifically
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    fyi-webFor the attention of Web platform team
    team-accessibilityOwned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)
    and removed
    in triagePresently being triaged by the triage team
    on Oct 4, 2024
  4. yjbanov commented on Oct 4, 2024

    @yjbanov
    Contributor

    This was supposed to be fixed by flutter-team-archive/engine#53703.

    @darshankawar How confident are you that this still reproduces on the master channel? Locally I see significant differences between the Dartpad output and master.

    Dartpad:

    <flt-semantics id="flt-semantic-node-4"
                   role="heading"
                   aria-level="1"
                   style="[STRIPPED]">
    </flt-semantics>

    Master channel:

    <h1 id="flt-semantic-node-4"
        style="[STRIPPED]">
      Im a level 1 heading
    </h1>

    This new HTML structure generated on the master channel is what I expect to see, and it should be treated by all screen readers correctly, as it's the most idiomatic way to represent headings in HTML.

    @k0psutin As a side note, the header: true is not necessary. Header and heading are supposed to be two different things. Even though the web engine marks headers as role="heading" today, we plan to fix it (see #152268).

  5. self-assigned this
    on Oct 4, 2024
  6. added
    P1High-priority issues at the top of the work list
    team-webOwned by Web platform team
    on Oct 4, 2024
  7. 1 remaining item

  8. removed
    team-webOwned by Web platform team
    triaged-webTriaged by Web platform team
    fyi-webFor the attention of Web platform team
    team-accessibilityOwned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)
    on Oct 4, 2024
  9. flutter-triage-bot commented on Oct 4, 2024

    @flutter-triage-bot

    Issue is assigned to multiple teams (web, accessibility). Please ensure the issue has only one team-* label at a time. Use fyi-* labels to have another team look at the issue without reassigning it.

  10. k0psutin commented on Oct 5, 2024

    @k0psutin
    Author

    @yjbanov Ah true, header and heading is two different things.

    On the side note, I was browsing Flutter engine code on semantics and I noticed that if a Semantic node has headingLevel it is treated as a GenericRole. https://github.com/flutter/engine/blob/01de9dcf6bbf3019b8173f63a0454610f0f92cc4/lib/web_ui/lib/src/engine/semantics/semantics.dart#L671

    So headingLevel only works if the semantic node has a label, e.g:

    Semantics(       
                  headingLevel: 1,
                  child: Text(
                    'Im a level 1 heading',
                    semanticsLabel: 'Im a level 1 heading',
                    style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600),
                  ),
                ),
    

    Outputs:

    <flt-semantics id="flt-semantic-node-4" role="heading" aria-level="1" style="position: absolute; overflow: visible; width: 198.703px; height: 31px; transform-origin: 0px 0px 0px; transform: matrix(1, 0, 0, 1, 528.148, 532); pointer-events: all; z-index: 1;"></flt-semantics>
    

    Maybe the documentation could be updated on that regard, i.e. "requires that semanticLabel or label is set"
    https://api.flutter.dev/flutter/semantics/SemanticsProperties/headingLevel.html

    @darshankawar Maybe the bug ticket can be closed if this is how the headingLevel should behave?

  11. yjbanov commented on Oct 5, 2024

    @yjbanov
    Contributor

    @k0psutin Yeah, the logic inside the GenericRole needs to be cleaned up. However, that class only kicks in if _getSemanticRoleKind decided that the node is generic. However, if headingLevel is set, then the heading role should be picked. I would not expect GenericRole to participate in such case.

    If you switch Dartpad to beta or main channels, you should see the new behavior, so the fix is making its way to stable.

  12. k0psutin commented on Oct 6, 2024

    @k0psutin
    Author

    @yjbanov I tested the headingLevel on main channel and it works without the label and renders as <h1 👍

    <h1 id="flt-semantic-node-4" style="margin: 0px; padding: 0px; font-size: 10px; position: absolute; overflow: visible; width: 198.703px; height: 31px; transform-origin: 0px 0px 0px; transform: matrix(1, 0, 0, 1, 528.148, 532); pointer-events: all; z-index: 1;">Im a level 1 heading</h1>
    

    I was also testing the link and linkUrl and noticed that, there is no way to assign target so Uri will open the link in the same window. I think there should be a way to designate target for links.

    https://dartpad.dev/?id=7f1abe2e7df0d501575900cc6a080826&channel=main

    And it seems that Link component is no longer working in main?

  13. darshankawar commented on Oct 7, 2024

    @darshankawar
    Member

    Master channel:

    Thanks for pointing out this change @yjbanov. I do see this as below upon running on master:

    Screenshot 2024-10-07 at 11 27 15 AM

    Per my earlier verification, I focused on enabling accessibility and then trying to navigate on the screen which didn't focus on headingLevel so I thought it was still replicable. I was mistaken.

    If you switch Dartpad to beta or main channels, you should see the new behavior, so the fix is making its way to stable.

    Based on this confirmation, I will go ahead and close this as WAI.

  14. added
    r: fixedIssue is closed as already fixed in a newer version
    on Oct 7, 2024
  15. github-actions commented on Oct 21, 2024

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  16. locked as resolved and limited conversation to collaborators on Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)found in release: 3.24Found to occur in 3.24found in release: 3.26Found to occur in 3.26has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions