Article · Intermediate
Use native HTML before adding ARIA
Choose the browser’s native semantic and interaction contracts first, then add ARIA only when it communicates a real state or relationship.
- Published
- Last checked
Start with the browser contract
Native HTML elements come with behavior, semantics, and platform integration. An
anchor with an href participates in navigation, can open in a new context,
appears in link lists, accepts expected pointer and keyboard input, and exposes
a link role. A button submits or performs an action, receives focus, activates
with the expected keys, and exposes button state.
ARIA can describe roles, states, and relationships to assistive technologies. It
does not automatically add keyboard behavior, focus management, form submission,
validation, navigation, or visual styling. Giving a div the role of button
changes part of its accessibility exposure while leaving the author responsible
for the rest of the button contract.
That difference explains the durable rule: use the native element whose semantics and behavior match the job. Add ARIA when the interface has a real state or relationship that native markup does not express by itself. The rule is not hostility to ARIA; it is a way to reduce custom code and failure modes.
Roles do not manufacture behavior
Consider a generic element styled as a control. Adding role="button" may make
some screen readers announce it as a button. The element still may not enter the
tab sequence, activate on Space, expose a disabled state correctly, submit a
form, or follow high-contrast system styling. Each missing behavior needs code,
tests, and maintenance.
A native button supplies those foundations and communicates its purpose to browsers, assistive technology, automation, and future developers. It can still be styled. Resetting its appearance carefully is generally less work than rebuilding its interaction model on a generic node.
The same principle applies to links, headings, lists, tables, labels, fieldsets, details, dialog, progress, and form controls. An ARIA role can expose a semantic approximation, but it does not guarantee that all browser and device behavior matches the native element.
Choose links and buttons by outcome
Use a link when activation moves to a resource or address. Give it a real href
so it remains crawlable, copyable, openable in another tab, and functional when
ordinary script enhancement fails. Use a button when activation changes state,
submits a form, opens a dialog, or performs another action on the current page.
Visual appearance is not the deciding factor. A call-to-action can look like a large filled button and remain an anchor when it navigates. A text-only icon can remain a button when it opens a menu. CSS describes presentation; element choice describes the operation.
Avoid placing one interactive element inside another. A linked card containing buttons creates competing activation and focus behavior. Structure the card with a clear primary link and separate actions, or reconsider whether the whole surface needs to be clickable.
Let forms expose their relationships
A native label associated with a control provides a programmatic name and a larger clickable target. Placeholder text is not a replacement because it disappears and behaves inconsistently as instruction. A fieldset and legend express the shared question for a radio or checkbox group without repeating it inside every option.
Use native input types, required state, autocomplete tokens, and validation as
the first layer. These features can improve mobile keyboards and browser
interaction, though the server must still validate authoritative rules. Add
aria-describedby for useful instructions or errors that need an explicit
relationship, not as a blanket list of every nearby sentence.
When validation changes dynamically, communicate invalid state and associate the error with its field. A status region can announce a concise submission result. ARIA is valuable here because it expresses a changing relationship or state; native structure still supplies the field, label, group, and button.
Use native disclosure and dialog foundations carefully
The details and summary elements provide a native disclosure for content that can be expanded and collapsed. They are a strong starting point for frequently asked questions and optional explanations. Do not replace them with a generic clickable heading unless the design requires a different interaction and the team is prepared to implement and test it.
The dialog element supplies dialog semantics and, when opened modally through its API, browser support for a top layer and inert surrounding content. The author still needs an accessible name, an intentional initial focus target, useful close controls, Escape behavior, and focus return. Native does not mean finished; it means the browser carries part of the contract.
ARIA Authoring Practices patterns are valuable for composite widgets that HTML does not provide directly, such as certain tab, tree, or grid interactions. They should be treated as implementation and testing specifications rather than attributes to copy. If the product does not need the composite interaction, a simpler group of links, headings, or controls is often more robust.
Add ARIA only for evidence-backed gaps
Before adding an attribute, state what information is missing. Does a navigation landmark need a distinct name because more than one exists? Does a toggle need to expose expanded state? Does a control manage another element whose identity is otherwise unclear? Does a live result need a status announcement?
Then choose the smallest valid property and keep it synchronized with visible
behavior. aria-expanded must change when the controlled region opens or
closes. aria-current should identify the current item and move when navigation
changes. aria-invalid should reflect actual validation state. A stale ARIA
state is worse than missing decoration because it confidently reports the wrong
interface.
Do not add redundant roles to native elements without a specific compatibility reason. Do not hide focusable content from the accessibility tree. Do not use an ARIA label that replaces useful visible text with a different name. The best accessible name is usually the same language everyone can see.
Review generated components skeptically
Generated interfaces often add ARIA because the prompt requested “accessibility,” while leaving the underlying element and behavior unchanged. Common results include clickable generic containers, duplicate labels, menus that are simply navigation lists, invalid attributes, and expanded states that never update.
Review the job before the attributes. Ask whether a native element already matches it. Remove unnecessary roles and properties, replace generic controls, and keep the DOM order meaningful. This usually shortens the component and reduces the number of states that require tests.
Do not judge the result from source alone. Browser parsing, framework wrappers, CSS, and scripts determine the final accessibility tree and interaction. Open the rendered page, inspect computed names and roles, and exercise every state with the keyboard.
Test semantics and operation together
Remove CSS and confirm the document still reads coherently. Use the accessibility tree to inspect names, roles, states, relationships, and landmarks. Tab and Shift+Tab through the page; activate links with Enter and buttons with Enter and Space. Operate composite controls with their documented keys.
Test normal, focused, disabled, expanded, selected, invalid, loading, success, and failure states. Use a screen reader for the primary journey and record the browser and version. Automated rules can catch invalid or missing markup, but they cannot prove that a custom interaction is understandable or complete.
Repeat at narrow widths, text zoom, reduced motion, and forced colours. Native semantics can survive a visual rearrangement while CSS reordering creates a different focus sequence, so accessibility review must include layout as well as attributes.
Know the limit of the rule
Native HTML does not contain every application widget, and browser support or design constraints can require carefully built custom behavior. ARIA exists for real gaps. The decision should be proportional: choose a documented pattern, implement its keyboard and focus contract, expose synchronized state, and test with assistive technology.
Using a native element is also not a certification. A button can have an unclear name, a label can describe the wrong field, and a dialog can open with unusable focus. Native-first reduces the amount of behavior authors must recreate; it does not remove the need for content judgment and behavioral testing.
The practical review question is not “does this page use ARIA?” It is “does each element express the correct job, does every added state remain true, and can a person complete the task with the platform behaviors they expect?” Start with HTML, add only the missing semantics, and verify the rendered result.