Back to insights

Lightning Web Components & Accessibility

Using SLDS does not make your LWC accessible

JSBC Labs8 min read

Visual consistency is not an accessible outcome

A custom Lightning web component can look native and still be unusable without a mouse. The button has the right SLDS class and the modal resembles Salesforce, yet its controls have unclear names, focus disappears after an action and a validation message is never announced. Styling has made the defect look credible; it has not made the interaction accessible.

The JSBC Labs position is that SLDS is a design foundation, not an accessibility certificate. Salesforce describes SLDS as giving custom components the look and feel of Lightning Experience. Its accessibility guidance separately asks developers to make components perceivable, understandable, navigable and interactive. Those behavioural outcomes must survive real tasks; a CSS class cannot confer them.

Prefer base components for behaviour, not convenience

Salesforce recommends considering a Lightning base component before building a custom control. Base components combine SLDS styling with accessibility behaviour, public attributes, events and methods. For example, when a label is supplied to lightning-input, Salesforce associates it with the rendered input. That removes a class of implementation risk while keeping the component aligned with platform updates.

Composition should therefore be the default. Build a business-specific experience from suitable platform primitives before recreating them with divs and event handlers. A requirement the base component cannot meet can justify custom implementation; visual preference alone rarely justifies owning keyboard behaviour, semantics, focus and future maintenance.

Use native semantics before adding ARIA

A control's accessible name and role are part of its contract. Use a real button for an action, a link for navigation and a labelled input for data entry. Salesforce's LWC guidance calls the label association critical and recommends visible text when information matters to everyone. aria-label is useful when no visual label can exist, but it should not become a patch for ambiguous content or a replacement for understandable interface copy.

Custom components also need deliberate public accessibility properties. If consumers can change the visible title but not the accessible name, the two can drift. A component whose role is fixed should not let a consumer make it misleading. Define which values are owned internally, which are configurable and how they reach the rendered element; treat them like data and event APIs.

Focus is workflow state

Keyboard focus tells a user where the next input will go. It must move logically, remain visible and land somewhere useful when the interface changes. Native interactive elements already participate in keyboard navigation. Salesforce documents tabindex values of 0 and -1 for custom focus management and warns that careless use can disrupt the sequence. Making every container focusable adds noise instead of access.

Design focus transitions as part of each journey. After opening a dialog, which control receives focus? After closing it, does focus return to the trigger? When a row is deleted, where does the user continue? If validation blocks save, how does the user reach the first problem? These are product decisions, not post-build polish. Document them so developers and testers evaluate the same behaviour.

Make dynamic state perceivable

LWC interfaces frequently update without a page reload: a spinner becomes a result, a filter changes a count, a save produces a toast and an inline error appears. Sighted users may infer those changes from position or colour, while a screen-reader user receives no new information and a keyboard user may be left focused on a control that has disappeared. The component needs an explicit communication strategy for loading, success, failure and empty states.

Start with the information outcome rather than an ARIA attribute. Decide what changed, whether it needs immediate attention and what action is available. Keep important text visible, preserve meaningful headings and do not use colour alone for severity or status. Then choose the platform component, semantic HTML and state mechanism that implement the outcome. This keeps assistive-technology behaviour tied to business meaning.

Component boundaries affect accessibility

Shadow DOM gives LWC valuable encapsulation, but it affects relationships between elements. Salesforce documents that template IDs may be transformed and that ID-based ARIA relationships inside one template are linked automatically. Relationships across templates require extra handling, and native shadow DOM cannot link IDs and ARIA attributes between separate templates. A label in one component and its input in another may therefore be an architectural smell, not merely a missing attribute.

Keep related controls, labels, descriptions and errors within one component when practical. Light DOM can enable cross-component ID references, but Salesforce also notes its weaker encapsulation and security considerations. Do not switch rendering modes to rescue a fragmented design. First reshape the component to own a coherent interaction; choose light DOM only after assessing the consequences.

A copied blueprint becomes your responsibility

When no base component meets the requirement, an SLDS blueprint is the right starting point. Salesforce describes blueprints as framework-agnostic accessible HTML and CSS, but they do not provide application logic. The team must still implement interaction, state and data behaviour correctly. More importantly, copied blueprint markup is not automatically updated when Salesforce changes the blueprint, while base components are updated by Salesforce.

Record the blueprint review date, supported form factors and deviations. Assign an owner to revisit the component during seasonal-release work and when SLDS guidance changes. Avoid depending on internal markup or CSS classes of base components because Salesforce does not support that coupling. A bespoke control is a maintained product surface, not a one-off snippet.

Test the interaction, not the screenshot

A visual regression test can show a focus ring; it cannot prove that focus arrives in the right order. A unit test can assert an attribute; it cannot prove that a screen reader announces a useful outcome. Automated checks can detect missing names, invalid relationships and some contrast defects, but their pass rate is a floor, not acceptance evidence.

For each critical component, test keyboard-only completion, visible focus, zoom, error recovery, and a supported screen-reader and browser combination. Exercise conditional rendering and asynchronous transitions, not only the initial DOM. Include disabled, empty, loading, partial and failure states. Record defects against the user task they block so prioritisation reflects business impact.

Make accessibility part of the component contract

A reusable component should publish more than its properties and events. Document its accessible name, keyboard model, focus behaviour, state announcements, supported form factors and expected consumer responsibilities. If slotted content must include a heading or a label property must never be blank, enforce or test that condition. Accessibility failures often arise at composition time, where two individually reasonable components produce an incoherent journey.

Add accessibility acceptance criteria to the definition of done and keep representative tests in the functional release pipeline. Review public-property changes for their effect on names and states, DOM restructuring for reading and focus order, and styling for contrast, target visibility and zoom. The contract should make regressions difficult to introduce accidentally.

Govern outcomes across complete journeys

Keep accessibility evidence for high-value journeys: personas and assistive technologies, keyboard path, expected announcements, known constraints, results and owner. Re-run the journey when a shared component, navigation shell or platform release changes. Component-level conformance matters, but users experience an assembled application where focus and meaning cross ownership boundaries.

The practical rule is straightforward: use base components where they meet the need, native HTML where it expresses the correct semantics and SLDS blueprints where custom work is genuinely required. Then verify the resulting behaviour with people, keyboards and assistive technology. SLDS can make a component belong visually in Salesforce. Only disciplined interaction design and evidence can show that every intended user can operate it.

Official references

Continue reading