Loading Developer Playground

Loading ...

Skip to main content
ARIA ATTRIBUTEWidget Attributes

aria-autocomplete

Describes the type of autocompletion behavior a combobox, textbox, or searchbox will use. Tells screen readers how input predictions will be presented to users.

Value Type
none | inline | list | both
Common Use
Comboboxes, Search
Used With
role="combobox"

Overview

The aria-autocomplete attribute describes the type of autocomplete behavior a text input will provide. It tells assistive technologies how suggestions or predictions will be presented as the user types.

This attribute is used on elements with role="combobox", role="textbox", or role="searchbox". It helps screen reader users understand what to expect when they start typing.

Required Companions

When using aria-autocomplete="list" or both, you typically need: aria-expanded, aria-haspopup="listbox", aria-controls, and aria-activedescendant for full accessibility.

Live Demo: Combobox with aria-autocomplete="list"

Try typing "a" to see filtered suggestions. Use arrow keys to navigate.

Screen reader announcement: "Search Fruits, combobox, autocomplete list, expanded, 15 items". When navigating options: "Apple, 1 of 15".

Attribute Values

none

No autocomplete suggestions are provided. The element may have a popup list, but it shows all options regardless of what the user types. The list is static, not filtered.

Example: A dropdown that always shows all options
list

A list of suggestions appears in a popup as the user types. The user can select from the list or continue typing. This is the most common autocomplete pattern (like search suggestions).

Example: Google search, address autocomplete, tag suggestions
inline

Text is automatically completed inline within the input field itself. The suggested completion appears after the cursor, typically selected, so typing replaces it.

Example: Email domain completion, URL bar suggestions
both

Combines inline completion AND a popup list. The best match appears inline while a full list of suggestions is shown in a popup. This provides maximum flexibility.

Example: Browser address bar (shows inline + dropdown)

Code Examples

None (No Autocomplete)

<!-- aria-autocomplete="none" -->
<!-- No autocomplete suggestions provided -->
<label for="name">Name</label>
<input 
  type="text" 
  id="name"
  role="combobox"
  aria-autocomplete="none"
  aria-expanded="false"
  aria-haspopup="listbox"
/>

<!-- Use "none" when the input has a popup list
     but doesn't filter or suggest based on input.
     Example: A dropdown that shows all options regardless of typing -->

List Autocomplete

<!-- aria-autocomplete="list" -->
<!-- Shows a list of suggestions that appear in a popup -->
<div class="combobox-container">
  <label for="fruit">Favorite Fruit</label>
  <input 
    type="text" 
    id="fruit"
    role="combobox"
    aria-autocomplete="list"
    aria-expanded="true"
    aria-controls="fruit-listbox"
    aria-haspopup="listbox"
    aria-activedescendant="fruit-option-1"
  />
  <ul 
    id="fruit-listbox" 
    role="listbox"
    aria-label="Fruit suggestions"
  >
    <li id="fruit-option-0" role="option">Apple</li>
    <li id="fruit-option-1" role="option" aria-selected="true">
      Apricot
    </li>
    <li id="fruit-option-2" role="option">Avocado</li>
  </ul>
</div>

<!-- Screen reader: "Favorite Fruit, combobox, autocomplete list,
     expanded, Apricot, option 2 of 3" -->

Inline Autocomplete

<!-- aria-autocomplete="inline" -->
<!-- Text is auto-completed inline as user types -->
<label for="email">Email address</label>
<input 
  type="email" 
  id="email"
  role="combobox"
  aria-autocomplete="inline"
  aria-expanded="false"
/>

<!-- Example behavior:
     User types: "john"
     Input shows: "john|@example.com" (completion selected)
     
     The completion text is typically selected so typing
     overwrites it. Less common than "list" or "both". -->

Both (Inline + List)

<!-- aria-autocomplete="both" -->
<!-- Combines inline completion AND a popup list -->
<div class="combobox-container">
  <label for="country">Country</label>
  <input 
    type="text" 
    id="country"
    role="combobox"
    aria-autocomplete="both"
    aria-expanded="true"
    aria-controls="country-listbox"
    aria-haspopup="listbox"
  />
  <ul id="country-listbox" role="listbox">
    <li role="option">United States</li>
    <li role="option">United Kingdom</li>
    <li role="option">United Arab Emirates</li>
  </ul>
</div>

<!-- User types: "uni"
     Input shows: "uni|ted States" (inline completion)
     Popup shows: List of matching countries
     
     This is like Google search: you see inline suggestion
     AND a dropdown of options -->

React Component

// React Combobox with Autocomplete
import { useState, useRef, useEffect } from 'react';

function Combobox({ 
  label, 
  options, 
  autocomplete = 'list', // 'none' | 'list' | 'inline' | 'both'
  onChange 
}) {
  const [query, setQuery] = useState('');
  const [isOpen, setIsOpen] = useState(false);
  const [activeIndex, setActiveIndex] = useState(-1);
  const inputRef = useRef(null);
  const listRef = useRef(null);
  
  // Filter options based on query
  const filteredOptions = options.filter(opt => 
    opt.toLowerCase().includes(query.toLowerCase())
  );
  
  // Active descendant ID
  const activeDescendant = activeIndex >= 0 
    ? `option-${activeIndex}` 
    : undefined;
  
  const handleKeyDown = (e) => {
    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        if (!isOpen) {
          setIsOpen(true);
          setActiveIndex(0);
        } else {
          setActiveIndex(prev => 
            prev < filteredOptions.length - 1 ? prev + 1 : 0
          );
        }
        break;
        
      case 'ArrowUp':
        e.preventDefault();
        setActiveIndex(prev => 
          prev > 0 ? prev - 1 : filteredOptions.length - 1
        );
        break;
        
      case 'Enter':
        e.preventDefault();
        if (activeIndex >= 0 && filteredOptions[activeIndex]) {
          selectOption(filteredOptions[activeIndex]);
        }
        break;
        
      case 'Escape':
        setIsOpen(false);
        setActiveIndex(-1);
        inputRef.current?.focus();
        break;
    }
  };
  
  const selectOption = (option) => {
    setQuery(option);
    setIsOpen(false);
    setActiveIndex(-1);
    onChange?.(option);
    inputRef.current?.focus();
  };
  
  const handleInputChange = (e) => {
    const value = e.target.value;
    setQuery(value);
    setIsOpen(value.length > 0);
    setActiveIndex(-1);
  };
  
  return (
    <div className="combobox">
      <label htmlFor="combobox-input">{label}</label>
      <input
        ref={inputRef}
        id="combobox-input"
        type="text"
        role="combobox"
        aria-autocomplete={autocomplete}
        aria-expanded={isOpen}
        aria-controls="combobox-listbox"
        aria-haspopup="listbox"
        aria-activedescendant={activeDescendant}
        value={query}
        onChange={handleInputChange}
        onKeyDown={handleKeyDown}
        onFocus={() => query && setIsOpen(true)}
        onBlur={() => setTimeout(() => setIsOpen(false), 200)}
      />
      
      {isOpen && filteredOptions.length > 0 && (
        <ul
          ref={listRef}
          id="combobox-listbox"
          role="listbox"
          aria-label={`${label} suggestions`}
        >
          {filteredOptions.map((option, index) => (
            <li
              key={option}
              id={`option-${index}`}
              role="option"
              aria-selected={index === activeIndex}
              onClick={() => selectOption(option)}
              className={index === activeIndex ? 'active' : ''}
            >
              {option}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

// Usage
<Combobox
  label="Search fruits"
  options={['Apple', 'Banana', 'Cherry', 'Date']}
  autocomplete="list"
  onChange={(value) => console.log('Selected:', value)}
/>

Best Practices

Use aria-autocomplete="list" for most search/filter autocomplete implementations

Always pair with aria-expanded, aria-haspopup, and aria-controls when using list/both

Use aria-activedescendant to track the currently highlighted option in the list

Implement arrow key navigation for moving through suggestions

Close the suggestions list on Escape and blur

Announce the number of suggestions for screen reader users

×

Don't use aria-autocomplete without proper role (combobox, textbox, searchbox)

×

Don't forget keyboard navigation—Enter to select, Escape to close

×

Don't use aria-autocomplete="inline" unless you actually implement inline completion

×

Don't confuse aria-autocomplete with the HTML autocomplete attribute (different purposes)

Common Use Cases

Search input with suggestions
Address autocomplete fields
Tag/mention inputs
Country/city selectors
Product search filters
Command palettes
Email recipient fields
URL/path completion

Related Attributes

Specifications & Resources