EsLint Plugin Lit A11y: heading-has-content
Enforce that heading elements (h1
, h2
, etc.) have content and that the content is accessible to screen readers. Accessible means that it is not hidden using the aria-hidden
attribute. Refer to the references to learn about why this is important.
Rule Details
This rule aims to...
Examples of incorrect code for this rule:
html`
<h1>
<div aria-hidden="true">foo</div>
</h1>
`;
html` <h1></h1> `;
Examples of correct code for this rule:
html` <h1>Foo</h1> `;
html`
<h1>
<div aria-hidden="true">foo</div>
foo
</h1>
`;
Options
The customHeadingElements
option lets you specify tag names to include in this rule, for example, if you have a custom element which implements heading semantics.
customElements.define(
'custom-heading',
class CustomHeading extends HTMLElement {
static get observedAttributes() {
return ['level'];
}
get level() {
const parsed = parseInt(this.getAttribute('level'));
if (!Number.isNaN(parsed)) return parsed;
else return null;
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
attributeChangedCallback() {
if (typeof this.level === 'number') this.render();
}
render() {
const heading = `h${this.level}`;
this.shadowRoot.innerHTML = `
<${heading}>
<slot></slot>
</${heading}>
`;
}
},
);
{
"rules": {
"lit-a11y/heading-has-content": [
"error",
{
"customHeadingElements": ["custom-heading"]
}
]
}
}
Examples of incorrect code with customHeadingElements: ["custom-heading"]
:
html` <custom-heading></custom-heading> `;
Examples of incorrect code with customHeadingElements: ["custom-heading"]
:
html`
<custom-heading>Heading</custom-heading>
<custom-heading><span>Heading</span></custom-heading>
<custom-heading>${foo}</custom-heading>
`;