Skip to main content


Bitwarden strives to comply with WCAG AA requirements. The following serves as an introduction to common aspects of accessibility that should be considered while implementing features and content. This list is not comprehensive, but provides a starting point for common “gotchas” that can limit the accessibility of a new feature. For comprehensive guidelines on accessibility, visit the official WCAG site.

Visual Presentation

WCAG Success CriteriaDescription
1.4.3 Contrast minimum

1.4.11 Non-text contrast
Content should have contrast meeting or exceeding the WCAG AA guidelines:
  - For normal text: 4.5:1
  - For large text and graphics: 3:1
  - Use the WebAIM contrast checker to learn more.
  - When using variables from the Component Library, the text-main variable is tested on background and background-alt variables. All other backgrounds generally use text-contrast.
1.4.13 Content on Hover of focusBitwarden design best practice: Interactive elements should always be visible without a user needing to hover or focus that element. This allows content to be more discoverable and thus accessible to users, while also eliminating the complexity necessary to implement such a pattern to meet WCAG criteria.
2.4.7 Focus visibleBitwarden design best practice: All interactive elements should have visible focus, hover states, and the correct cursor styling.
Bitwarden design best practice: Icons and text that is shortened should always have a title attribute to provide additional context.

Keyboard Navigation

WCAG Success CriteriaDescription
2.1.1 KeyboardAll mouse interactive elements on a page should be accessible via keyboard navigation.
2.1.1 Keyboard

2.1.2 No keyboard trap
If a popup (especially in the case of multiple dialogs) is opened, be sure to test that focus is moving to and from each dialog correctly and there is no keyboard trap.
2.4.7 Focus visibleEach interactive element should have a visible focus indicator to assist user navigating the page by keyboard.

Screen Reader

Users with low vision or blindness will often navigate products using keyboard navigation and a screen reader. This results in an audio read out of the page’s content, often with additional instruction depending on what semantic element is in focus.

To understand more about screen reader and keyboard navigation, turn on VoiceOver on macOS or download NVDA on Windows and try navigating your device with keyboard and screen reader.

WCAG Success CriteriaDescription
1.1 Text alternativesInclude alt-text or aria-labels for any non-text elements that conveys information not provided elsewhere. If elements are not informative, they may be marked as decorative.
1.3.1 Info and relationships

1.3.2 Meaningful sequence

3.3.1 Error identification

3.3.2 Labels or instructions
Be sure that related content is presented together and can be programmatically determined.

Use aria-describedby to associate content from one element with another. This is often used for form errors or helper text.
4.1.2 Name, role, valueUse aria-haspopup on elements that trigger another element like a menu or dialog. This tells a screen reader (and thus the user) that another element is opening that will have additional actions. See aria-haspopup - Accessibility MDN for more information.
4.1.2 Name, role, valueUse aria-expanded on elements that expand or collapse to show or hide more information. Note: both aria-haspopup and aria-expanded should not be used on the same element. Default to aria-haspopup for menus and use aria-expanded for interactions like accordions or other show/hide toggles.
4.1.2 Name, role, valueUse aria-selected when there are multiple elements that can be selected or unselected such as tabs, table rows, or grid cells. See more in aria-selected - Accessibility MDN.
4.1.2 Name, role, valueMost html elements have roles already assigned to them. However in some instances you may need to specify the role of an element. See WAI-ARIA Roles - Accessibility MDN for more information on roles. Most Bitwarden Component Library components already have applicable roles applied. But there may be cases where you need to build a new component where you should consider the element’s role.
4.1.3 Status messagesSometimes an interaction on a page will trigger additional content being added or change. Example: clicking a button that says “Send verification code” triggers a confirmation message. It is important that this content is announced via the screen reader. This can be done via an aria-live region or using a role=alert attribute.

Semantic Structure

Be sure to use proper semantic structure on each page. The elements used to create a page provide screen readers with more context in what type of content that element contains. The proper use of landmarks and headings, also allows users to navigate pages by just landmarks or heading levels, rather than having to always tab through the full page’s content.

WCAG Success CriteriaDescription
3.1.1 Language of pageInclude a lang attribute on the html element of each page.
2.4.2 Page titledUse a title element and a single h1 to display the title on each page.
1.3.1 Info and relationshipsWrap content in the elements that have semantic meaning that matches the content’s purpose. Note: div and span have no semantic meaning so its best to avoid using them to wrap text. Instead use a p element.
1.3.1 Info and relationshipsUse logical sequence for heading levels. A h4 should not come before the first h3 element. In addition don’t skip heading levels, use the next descending header to create structure.
1.3.1 Info and relationshipsUse landmark regions to communicate what content can be expected; be sure to include a nav element around the page’s navigation and main around the content of the page.
1.3.1 Info and relationshipsUse a elements with hrefs for links; use a link when the user is navigating to a new page.
1.3.1 Info and relationshipsUse button elements to submit data or perform on-screen actions that do not move keyboard focus.
3.3.2 Labels or instructionsUse proper form semantics every input having a corresponding label element, and fieldset when applicable.