This is for:


Coveo designed the Atomic library with accessibility in mind. It adheres to the Accessible Rich Internet Applications (ARIA) standards and follows the Web Content Accessibility Guidelines (WCAG).

In November 2022, Atomic was evaluated by Deque Systems, an accessibility testing company. Their report, which is based on the Voluntary Product Accessibility Template (VPAT), is available for download.

While developing Atomic, we’ve tried to make the user experience with screen readers as comfortable and consistent as possible. We’ve tested it with the following screen readers:

However, Atomic is a customizable library which can’t control every element of a web page. Consequently, it can only ensure that some parts of the user experience adhere to the listed accessibility standards. This article explains how you can improve the accessibility of your own search interfaces when using Atomic.

Improve contrast ratios

We recommend that the color contrast ratios in your interface conform to WCAG Level AA (see Success Criterion 1.4.3: Contrast (Minimum)).

If you’re using the theme that’s included with Atomic (coveo.css), you can ensure that Atomic conforms to accessibility standards by replacing it with the accessibility theme (accessible.css).

If you’re using a custom theme, we recommend that you customize the colors and font sizes in your interface to conform to accessibility standards.

Add headings

According to a survey by WebAIM, 67.7% of respondents were likely to navigate by headings first when trying to find information on a lengthy web page. Atomic is a component-based library that lets you divide your search interfaces to suit your needs, so its components don’t include headings. We recommend that you add headings to allow screen reader users to jump between relevant sections of your page.

    .screen-reader-only {
      height: 0;
      margin: 0;
      overflow: hidden;
    <h1 class="screen-reader-only">Search</h1>
    <h1 class="screen-reader-only">Summary</h1>
    <h1 class="screen-reader-only">Facets</h1>
      <h2 class="screen-reader-only">Brand</h2>
      <atomic-facet field="ec_brand" label="Brand"></atomic-facet>
      <h2 class="screen-reader-only">Rating</h2>
      <atomic-rating-facet field="ec_rating" label="Rating"></atomic-rating-facet>
    <h1 class="screen-reader-only">Results</h1>
    <atomic-result-list display="grid">

Improve result accessibility

Since results are highly customizable, the relevant components offer limited out-of-the-box accessibility support. However, we recommend the following to help you provide an accessible experience for your users.

Reorder result sections


This is only relevant if you use result sections in your result template.

While the visual order of sections is independent of the order in which they were defined in the template, screen readers will try reading sections in the order in which they’re defined. As such, we recommend that you order result sections from most important to least important, with the title section being the most important. This order is highly subjective, so we recommend that you take inspiration from other accessible search pages with a purpose similar to yours.


Hide the thumbnail

Your results may include a thumbnail as well as a detailed title. If your title accurately describes the content which is depicted in a thumbnail, it means that the thumbnail doesn’t contain additional information for screen readers.

In such a case, the thumbnail would slow down navigation for screen reader users, so we recommend that you hide the thumbnail from screen readers.

Achieve this by setting its aria-hidden property to true.


Add roles

We recommend that you add semantic roles to certain result components to better communicate to screen readers what they represent in your particular template. However, be aware that adding a role to a component overwrites its original role and that screen readers may expect some roles to have specific children or support specific keyboard shortcuts.

In general, we recommend making the following adjustments:

  • Add the role="grid" property to the element containing all your fields and:

    • Wrap each field label-value pair in an element with the role="row" property.

    • Add the role="rowheader" property to each field label.

    • Add the role="cell" property to each field value.

      <atomic-result-fields-list role="grid">
        <div role="row">
          <span role="rowheader">Priority:&nbsp;</span>
          <atomic-result-text field="priority" role="cell"></atomic-result-text>
        <atomic-field-condition if-defined="deadline" role="row">
          <span role="rowheader">Deadline:&nbsp;</span>
          <atomic-result-date field="deadline" role="cell"></atomic-result-date>
  • Add the role="note" property to atomic-result-badge components.

    <atomic-result-badge field="special" role="note"></atomic-result-badge>

Instant results accessibility

Out of the box, the atomic-search-box-instant-results component doesn’t support accessibility. You must implement it yourself using the ariaLabelGenerator property, as in the following code sample.


The following is merely an example. Details depend heavily on the way you implemented your instant results. Assume that instant results are non-text content, and make sure to test your implementation to validate that all the visible content is described by the string you return.

// index.html
// ...
document.querySelector('atomic-search-box-instant-results').ariaLabelGenerator = ({i18n}, result) => { 1
  const information = [result.title]; 2

  if ('ec_rating' in result.raw) { 3
      i18n.t('stars', {
        count: result.raw.ec_rating,
        max: 5,
  } else {

  if ('ec_price' in result.raw) { 4
      result.raw.ec_price.toLocaleString(i18n.languages, {
        style: 'currency',
        currency: 'USD',

  return information.join(', ');
1 The ariaLabelGenerator function takes in the i18next bindings and the target result. The i18next bindings are required when you want to support localization.
2 Create an array of strings that your function will concatenate and return. The first thing you include is the item title. You’ll add other strings below.
3 If the rating field is populated, add it to the information array, using i18n dynamic values for localization. Turn the rating into a string as in the locales.json file below.
// locales.json
  // ...
  "stars": {
    "en": "{{count}} stars out of {{max}}",
    "fr": "{{count}} étoiles sur {{max}}"
  // ...
4 If the price field is populated, turn it into a string using the toLocaleString function, and add it to the information array.

You can find full examples in the Atomic project repository: