skip to Main Content

I’m encountering a warning in my Angular application that states:

Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead.

I’m using a modal dialog created with the Angular Bootstrap (ng-bootstrap) library. Here’s a simplified version of the relevant code:

<div class="modal-header">
  <h4 class="modal-title">Serial Number</h4>
  <button type="button" class="btn-close" aria-label="Close" aria-label="Close" (click)="popupClose(false)">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

Issue:
The warning indicates that an element with aria-hidden is blocking focus from its descendant elements. I want to ensure that my modal is accessible and does not cause issues for assistive technology users.

I considered using the inert attribute as suggested, but I’m unsure how to implement it in this context.
I’ve looked through the ng-bootstrap documentation and found no specific guidance on this warning.

2

Answers


  1. This warning occurs when an element or one of its ancestors has the aria-hidden="true" attribute, which hides the element from assistive technologies like screen readers. However, if this element (or any of its descendants) is focusable, assistive technology users may still "see" it, which can create a confusing user experience.

    Here’s how you can resolve it:

    Remove aria-hidden="true" from any element that has focusable children (like buttons). Focusable elements should not be hidden from assistive technology users, so it’s best to avoid using aria-hidden="true" on these elements or their ancestors.
    
    Use the inert attribute if you need to make the element temporarily inactive or "invisible" for both interaction and focus purposes. The inert attribute prevents both keyboard focus and interaction, which can be useful if you’re working with modals or dynamically displayed content. However, note that inert is not supported in all browsers, so you may need a polyfill.
    
    Check the modal logic: If you are using Bootstrap modals, ensure that the aria-hidden="true" attribute is not added to elements that will have focus. Sometimes, these attributes can be added by JavaScript frameworks or libraries, so check your modal configuration.
    

    Here’s an example of how to adjust your button:

    By removing aria-hidden="true" and using aria-label to improve accessibility, you avoid the conflict with focusable elements. If you need the button hidden temporarily, consider setting it to display: none instead, as it will remove it from the accessibility tree entirely.

    Login or Signup to reply.
  2. Let’s suppose this is how you’re using the NgbModal to open the modal inside your angular component:

    import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
    import { Component } from '@angular/core';
    import { ModalComponent } from './modal.component';
    import { MODAL_CONFIG } from './modal-config';
    
    @Component({
      selector: 'app-parent',
      template: '<button type="button" (click)="openModal()">Open Modal</button>',
    })
    export class ParentComponent {
      constructor(private modalService: NgbModal) {}
    
      openModal() {
        this.modalService.open(ModalComponent, MODAL_CONFIG.MEDIUM); // Open the modal
      }
    }
    

    Now you will see expected warning which occurs because of how ng-bootstrap manages modals. When a modal is opened, ng-bootstrap adds aria-hidden="true" to the ‘app-root’ element to make it inaccessible to assistive technologies while the modal is active.

    However, at this moment:

    • The element that triggered the modal (e.g., the "Open Modal" button)
      retains focus.
    • Since the button is inside app-root, and app-root now has
      aria-hidden="true", this creates an accessibility conflict. Assistive
      technologies flag this as an issue because the focused element is
      effectively hidden.

    To resolve this, remove the focus from the button (or any triggering element) before opening the modal. This prevents the focused element from being inside the aria-hidden="true" ancestor.

    import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
    import { Component } from '@angular/core';
    import { ModalComponent } from './modal.component';
    import { MODAL_CONFIG } from './modal-config';
    
    @Component({
      selector: 'app-parent',
      template: '<button type="button" (click)="openModal()">Open Modal</button>',
    })
    export class ParentComponent {
      constructor(private modalService: NgbModal) {}
    
      openModal() {
        const buttonElement = document.activeElement as HTMLElement; // Get the currently focused element
        buttonElement.blur(); // Remove focus from the button
        this.modalService.open(ModalComponent, MODAL_CONFIG.MEDIUM); // Open the modal
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search