Search code examples
htmlaccessibilityweb-componentwai-aria

What should be the aria-role for the box that can be opened by clicking on notification icon on navbar?


I am trying to implement the notification component that will show the list of the items and will be opened by clicking on the notification icon on the fixed navigation bar on the top. I don't think it's a menu bar. Because the menu provides the actions that can be performed and it can also have a sub-menu. https://www.w3.org/TR/wai-aria-practices/#menu

Can anyone let me know what should be the aria-role of such kind of components?

Below is the code sample. I will open the template dynamically by clicking on the notification icon button:-

    <button aria-label="notifications">
      <mat-icon class="mr-md">notifications</mat-icon>
    </button>

    <!-- Notification template -->
    <div class="notifications__item">
      Notifications
      <li *ngFor="let notification of notifications" class="notifications__item">
        <mat-icon class="notifications__icon material-icons-round">
          {{ notification.icon }}
        </mat-icon>
        <div class="notifications__content">
          <div [ngClass]="{ 'notifications__warn': notification?.type }">
            <span>{{ notification.title }}</span>
          </div>
          <div>{{ notification.description }}</div>
        </div>
        <small class="notifications__caption">
          {{ notification.duration }}
        </small>
      </li>
    </div>

Solution

  • There are still a lot of things to consider that your example doesn't cover, so this isn't a complete answer, it is just pointing you to the relevant WAI-ARIA depending on what route you take.

    The button

    The first thing to consider is the button. You need to tell screen reader users what state it is currently in. For this we use aria-expanded to indicate whether the item it controls is currently opened or closed. (aria-expanded="true" for open, aria-expanded="false" for closed.)

    At the same time we want to indicate what item this button controls (as the notification list isn't 'owned' by the element - for example if it was an <li> with a nested <ul> in a menu then the list would be 'owned' by it).

    For this we would use aria-controls or aria-owns and point it to the ID of the element it controls. For the difference between them see this stack overflow post as a good explanation, in this example I would say it is aria-controls but yet again depends on your implementation and positioning in the DOM.

    With regards to the button itself and where it sits in your menu, this is still considered navigation so it should sit within your <nav> element. However if this sits outside of your navigation along with say a 'help' and 'account' section you may consider those items part of a toolbar. (yet again I would say it doesn't apply here but something to look at)

    Also it doesn't appear to be applicable here but if you include any links etc. within the 'popup' / modal that shows the notification list (i.e. a 'view all notifications' link), you should consider aria-haspopup="true"

    The notification list

    Right so we have a button pointed to the container (don't forget to give the container the relevant ID for aria-owns or aria-controls). Next what about the container itself?

    Well in this example it appears that the container should be treated like a modal.

    So for this reason you need to consider:-

    • trapping focus in the modal,
    • close with Escape,
    • returning focus to the button that activated it on close,
    • providing a close button that is accessible by keyboard,
    • a title for the modal (even if it is visually hidden)

    What I would recommend is add some of the accessibility features above, try it with a screen reader and keyboard and see if it is easy to use. Once you have decided on your pattern ask some more questions on specific use case issues as the above is general guidance.

    A few things to consider based on your markup

    Additional things to consider from your example:-

    • use aria-hidden="true" on your icons, they don't add anything for screen readers (assuming your notification.title is descriptive).
    • For the notification title consider making it a relevant heading (<h2> - <h6> depending on position in document.
    • Don't forget to add some visually-hidden text that describes the warning level (I can see you have some form of colouring / distinction in [ngClass]="{ 'notifications__warn': notification?.type }" - expose the same info to screen readers.)
    • You currently have a <li> within a <div> - maybe change the outer <div> into an <ul> so it is semantically correct (<div class="notifications__item"> into <ul class="notifications__item">)

    I hope the above is useful to set you on the right track, a lot to read but after reading the linked articles you should be able to make a better decision on what pattern you are using (as I didn't even mention making this a sub item within your menu) and can then ask some more questions on specific details you don't yet understand.

    final thoughts / tips

    test with a screen reader - this is the biggest tip I can give on working out how WAI-ARIA works and interacts with things.

    Also if you are ever in doubt as to whether a WAI-ARIA attributre is applicable it is better to not include it.

    Incorrect use or WAI-ARIA is actually worse than not including it at all so make sure you understand when to use an attribute reasonably well before implementing it. If I am ever unsure (as it still happens to me!) I tend to look at 2 or 3 examples of it in use and see if my pattern fits the examples I looked at.