Yes there are several ways you can do this.
The reason you are shown this error is for screen readers, they need some programatically determinable text in order to tell the user what the button does.
You only showed part of the button HTML but my guess is you are only using an icon within it so there is no way for the screen reader to work out useful information for the end user.
Two ways you could fix this are:-
1. Add an aria-label
WAI-ARIA is used to provide extra information to screen readers. If you change your markup to include an aria-label
as follows this lets screen reader users know what the button does:-
<div class="invitation-chat__close" role="button" data-dl-element="button" data-dl-name="No, don't start" aria-label="open chat or whatever is the action of the button">
The aria-label
tells screen readers "ignore the contents of this element when determining how to announce this item, instead use this text I have defined".
2. Add some visually hidden text.
Unfortunately aria-label
does not have universal support.
As such the better way to do this is with "visually hidden text" (text that is not visible but accessible to screen readers).
Please see this answer I gave about sr-only text to understand that further and for the reason to use the below class.
For your example all you need to do is add a span with the visually-hidden
class containing text that is descriptive of the button purpose.
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<div class="invitation-chat__close" role="button" data-dl-element="button" data-dl-name="No, don't start">
<span class="visually-hidden">Open chat or whatever is appropriate text for the button</span>
<!-- other HTML such as icon -->
ICON
</div>
Further suggestions.
As I would imagine you are using HTML5 I would encourage you to change your markup.
Instead of a <div>
with a role="button"
, just use a <button>
element.
Not only is this more robust it is also easier to maintain and it has all of the functionality baked in such as focus indicators, click events etc.
This yet again is down to support, although support is much better for role
than other WAI-ARIA attributes.
<button class="invitation-chat__close" data-dl-element="button" data-dl-name="No, don't start">
<span class="visually-hidden">Open chat or whatever is appropriate text for the button</span>
<!-- other HTML such as icon -->
ICON
</button>
What if you cannot change the source code?
At that point you need to do the same but with JavaScript.
Once your component has initialised target the offending div using a query selector and insert the relevant HTML.
const myNewHTML = '<span class="visually-hidden">Open chat or whatever is appropriate text for the button</span>';
let el = document.querySelector('[data-dl-name="No, don\'t start"]');
el.innerHTML = el.innerHTML + myNewHTML
console.log("NEW INNER HTML", el.innerHTML);
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<div class="invitation-chat__close" role="button" data-dl-element="button" data-dl-name="No, don't start">
<!-- other HTML such as icon -->
ICON
</div>