Holiday Notice: Support will be provided on a limited scale from December 24th, 2024, to January 2nd, 2025. Happy holidays and a wonderful New Year!


Topic: MDB Sidenav is failing accessibility audit

rikuwolf priority asked 2 years ago


Expected behavior

All MDB components pass accessibility tests, for example using Lighthouse

Actual behavior

We've implemented the MDB sidenav and when we run an accessibility audit using Chrome's Lighthouse snapshot test, it fails. You can see the report below.

It looks like we cannot fix this ourselves. We need you in the MDB Team to include an improvement in a future release. Soon please. It's not good that our accessibility score is negatively affected by this MDB component.

If the problem originates in the way we've implemented this, please explain what we can do to make the sidenav accessible ourselves.

Google Chrome rates this problem as "SERIOUS". According to the linked info in the Lighthouse: https://dequeuniversity.com/rules/axe/4.4/aria-hidden-focus?utm_source=lighthouse&utm_medium=devtools

Thanks in advance for caring about accessibility when you are planning your next release!

Resources (screenshots, code snippets etc.)

[aria-hidden="true"] elements contain focusable descendentsFocusable descendents within an [aria-hidden="true"] element prevent those interactive elements from being available to users of assistive technologies like screen readers. Learn more.Failing Elementsmdb-sidenav-layout > multisite-sidenav > mdb-sidenav > div.cdk-visually-hiddenmdb-sidenav-layout > multisite-sidenav > mdb-sidenav > div.cdk-visually-hidden

Layout

    <mdb-sidenav-layout>
  <multisite-sidenav #sidenav [user]="user" (sideNavToggled)="sidenavToggled($event)"
  ></multisite-sidenav>
  <mdb-sidenav-content #sidenavContent>
    <div class="custom-backdrop"></div>
    <header>
      <multisite-main-navigation
        [user]="user"
        [logo]="'default'"
        [navLinks]="mainNavigationLinks"
        (doSideNavToggle)="toggleSidenav()"
        (logout)="logout()"
        [loading]="loading"
        [sidenavStatus]="sidenavStatus"
        >
      </multisite-main-navigation>
    </header>
    <multisite-breadcrumb></multisite-breadcrumb>
    <main> 
      <section class="main-section">
        <router-outlet></router-outlet>
      </section>
    </main>

    <multisite-footer></multisite-footer> 
  </mdb-sidenav-content>
</mdb-sidenav-layout>

CONTENT

<mdb-sidenav #sidenav="mdbSidenav"
  [backdrop]="false"
  [backdropClass]="'custom-backdrop'"
  [width]="360"
  [slimWidth]="136"
  [right]="true"
  (sidenavHidden)="toggled('hidden', $event)"
  (sidenavExpanded)="toggled('expanded', $event)"
  (sidenavCollapsed)="toggled('collapsed', $event)"
  >
  <ul class="sidenav-menu" [ngClass]=" sidenav.slimCollapsed ? 'sidenav-slim' : 'sidenav-wide'">
    <!-- SIDENAV TOP PART -->
    <li class="sidenav-top-content">
      <div class="sidenav-header">
        <div class="content-left">
          <a class="sidenav-close" (click)="toggle()" tabindex="0" *ngIf="!sidenav.slim">
            <i class="fas fa-times"></i>
          </a>
        </div>
        <div mdbDropdown class="dropdown dropstart">
          <a class="nav-link dropdown-toggle" id="navbarSettingsDropdown" role="button" mdbDropdownToggle
            aria-expanded="false">
            <div class="content-right">
              <div class="profile-info">
                <p class="name h5">{{user?.fname +' ' +user?.lname}}</p>
                <p class="profession h6">{{user?.profile?.job_title}}</p>
              </div>

              <img class="user-profile-img"
                [src]="user?.picture ? user.picture : 'https://res.cloudinary.com/cebt/image/upload/v1616972586/users/avatars/default-avatar.gif' "
                alt="Profile image">
                <span class="click-indicator animation-pulse-infinite"></span>

            </div>
          </a>
            <multisite-user-account-dropdown [user]="user" mdbDropdownMenu class="dropdown-menu"></multisite-user-account-dropdown>
        </div>
      </div>
    </li>
    <!-- 
      SIDENAV BOTTOM PART
      (One scrollable element - ssplit into two parts) 
    -->
    <li class="sidenav-main-content">
      <!-- TOP PART OF MAIN CONTENT -->
      <div>
        <div class="card-group">
          <!-- Card -->
          <div class="card-sidenav">
            <div class="card-body">
              <div class="content-left">
                <div class="card-status-icon bg-success">
                  A
                </div>
                <div class="card-text text-wrap">
                  <p class="card-title">Course A</p>
                  <p class="card-value">100%</p>
                </div>
              </div>
              <div class="content-right">
                <button class="btn" aria-label="Useful name for button A">
                  <i class="fa-solid fa-angle-right"></i>
                </button>
              </div>
            </div>
          </div>
          <!-- Card -->
          <div class="card-sidenav">
            <div class="card-body">
              <div class="content-left">
                <div class="card-status-icon bg-warning">
                  B
                </div>
                <div class="card-text text-wrap">
                  <p class="card-title">Course A</p>
                  <p class="card-value">100%</p>
                </div>
              </div>
              <div class="content-right">
                <button class="btn" aria-label="Useful name for button A">
                  <i class="fa-solid fa-angle-right"></i>
                </button>
              </div>
            </div>
          </div>
          <!-- Card -->
          <div class="card-sidenav">
            <div class="card-body">
              <div class="content-left">
                <div class="card-status-icon bg-danger">
                  C
                </div>
                <div class="card-text text-wrap">
                  <p class="card-title">Course A</p>
                  <p class="card-value">100%</p>
                </div>
              </div>
              <div class="content-right">
                <button class="btn" aria-label="Useful name for button A">
                  <i class="fa-solid fa-angle-right"></i>
                </button>
              </div>
            </div>
          </div>
          <a href="#">Show all cards</a>
        </div>
        <div class="accreditation-card bg-success">
          <img src="https://iili.io/HH2EezN.png" alt="badge">
          <div class="card-text text-wrap">
            <p class="title text-white">Accredited until 2025</p>
            <p class="sub-title text-white">New Tool</p>
          </div>
        </div>
      </div>
      <!-- BOTTOM PART OF MAIN CONTENT -->
      <div>
        <hr>
        <div class="progress-card">
          <p class="title" id="progresslabel">
            Total Progress
          </p>
          <p class="progress-value">
            68%
          </p>
          <div class="progress">
            <div class="progress-bar" role="progressbar" style="width: 68%" aria-valuenow="68" aria-valuemin="0"
              aria-valuemax="100" aria-labelledby="progresslabel"></div>
          </div>
        </div>
        <div class="trainer-card">
          <carousel [interval]="false">
            <p class="trainer-title">Trainers</p>
            <slide>
              <div class="trainer-img">
                <img src="https://iili.io/yzAHJf.png" alt="">
                <div class="status-indicator"></div>
              </div>
              <div class="card-text">
                <p class="title">Terry Tester</p>
                <p class="subtitle">
                  Head of ...
                </p>
              </div>
            </slide>
            <slide>
              <div class="trainer-img">
                <img src="https://iili.io/yzAHJf.png" alt="">
                <div class="status-indicator"></div>
              </div>
              <div class="card-text">
                <p class="title">Earl E. Adopta</p>
                <p class="subtitle">
                  UX/UI Designer
                </p>
              </div>
            </slide>
            <slide>
              <div class="trainer-img">
                <img src="https://iili.io/yzAHJf.png" alt="">
                <div class="status-indicator"></div>
              </div>
              <div class="card-text">
                <p class="title">John Doe</p>
                <p class="subtitle">
                  NaN
                </p>
              </div>
            </slide>
          </carousel>

          <!-- <div class="card-body bg-white">
              <div class="trainer-img">
                <img src="https://iili.io/yzAHJf.png" alt="">
                <div class="status-indicator"></div>
              </div>
              <div class="card-text">
                text
              </div>
            </div> -->
        </div>
      </div>
    </li>
  </ul>
</mdb-sidenav>

Arkadiusz Idzikowski staff commented 2 years ago

Thank you for letting us know about this problem, we will take a closer look at that and let you know what we found.

Could you please edit your post and provide an example code that you use to render the component? We would like to test that using a similar configuration.



In v5.1.0 we added some changes that should improve the accessibility of this component.

We plan to continue working on improving this aspect, but the remaining fixes will probably require more serious changes to the HTML structure of the sidenav and we will only be able to add them in the next major update.

Please let us know if you encounter any further problems.


webshapers priority commented 8 months ago

Hello, mdb-Team! We ran into a similar issue (mdb latest version as of today). mdb is injecting a tabindex="1", which makes little sense to us. Could you please describe, WHICH changes you have added to improve the accessibility?


Rafał Seifert free commented 8 months ago

HTML structure was changed: we removed li element that was not contained within list element and added attribute role listitem to item element instead. We also changed the basic example code and added attributes like role, aria-expanded, aria-label and aria-controls.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Priority
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: MDB5 4.0.0
  • Device: MacBook Pro
  • Browser: Chrome
  • OS: MacOs
  • Provided sample code: Yes
  • Provided link: Yes