Accessible Web Components


The LabelledComponent mixin enables elements within a Web Components to be associated with suitable labels created in the DOM outside of the Web Component.


Extending from LabelledComponent in JavaScript

import {LabelledComponent} from 'accessible-web-components';
class DropdownSelector extends LabelledComponent(HTMLElement) {
constructor() {
.attachShadow({mode: 'open'})
.innerHTML = `<div><div id="labelled-element"></div></div>`;
this.__labelledElementIds = ['labelled-element'];
// other initialisation
connectedCallback() {
if (this.isConnected) {
// other initialisation requiring access to DOM and ShadowDOM
disconnectedCallback() {
// other cleanup

Using a LabelledComponent in HTML

<label for="choose-something">Choose something from the list</label>
<dropdown-selector id="choose-something"></dropdown-selector>
<label id="label-for-selector">Choose something from the list</label>
<dropdown-selector aria-labelledby="label-for-selector"></dropdown-selector>


The LabelledComponent mixin looks for any labels that have been associated in the DOM, either through a for/id relationship or an id/aria-labelledby relationship. It then creates a label with the same content within the Web Component and sets the aria-labelledby attribute on elements within the Web Component which are listed in the __labelledElementIds property.

The label created within the Web Component is invisible to users, but will be announced by screen readers when the associated elements are focussed.

The mixin will also set up appropriate listeners on the original label to set focus on the Web Component when the label is clicked.

Authoring Experience

The LabelledComponent mixin was created to mimic the native approach for labelling form inputs when working with Web Components. For example:

<label for="type-something">Type in the input</label>
<input id="type-something" type="text"/>
<label for="choose-something">Choose something from the list</label>
<dropdown-selector id="choose-something"></dropdown-selector>

This means that the label can be naturally styled the same way as any other label used across the site.

The common alternatives are to use an attribute - which typically limits the label content to text, or use a slot:

<dropdown-selector id="with-attribute" label="Choose something from the list"></dropdown-selector>
<dropdown-selector id="with-slot">
<slot name="label">
Choose something from the list

One downside to either of these approaches is that it's a different pattern of authoring. Another is that it makes it harder to style the label.