Autocomplete

Use autocomplete to help users select from a large list of options by showing suggestions as they type.

Default Autocomplete

  • Australia
  • Austria
  • Azerbaijan
<div class="form-group">
  <label class="form-label" for="country">Country</label>
  <div class="autocomplete">
    <input class="form-input" id="country" type="text"
           autocomplete="off" aria-autocomplete="list">
    <ul class="autocomplete-list" role="listbox">
      <li class="autocomplete-item" role="option">Australia</li>
      <li class="autocomplete-item autocomplete-item-highlighted"
          role="option" aria-selected="true">Austria</li>
      <li class="autocomplete-item" role="option">Azerbaijan</li>
    </ul>
  </div>
</div>

With Hint Text

Start typing to see suggestions

No Results

  • No results found
<li class="autocomplete-no-results">No results found</li>

JavaScript Implementation

class Autocomplete {
  constructor(input, options = {}) {
    this.input = input;
    this.options = options;
    this.data = options.data || [];
    this.minLength = options.minLength || 2;

    this.createList();
    this.bindEvents();
  }

  createList() {
    this.list = document.createElement('ul');
    this.list.className = 'autocomplete-list';
    this.list.setAttribute('role', 'listbox');
    this.list.style.display = 'none';
    this.input.parentNode.appendChild(this.list);
  }

  bindEvents() {
    this.input.addEventListener('input', () => this.onInput());
    this.input.addEventListener('keydown', (e) => this.onKeydown(e));
    document.addEventListener('click', (e) => this.onClickOutside(e));
  }

  onInput() {
    const query = this.input.value.toLowerCase();
    if (query.length < this.minLength) {
      this.hide();
      return;
    }

    const matches = this.data.filter(item =>
      item.toLowerCase().includes(query)
    );

    this.render(matches);
  }

  render(items) {
    if (items.length === 0) {
      this.list.innerHTML = '<li class="autocomplete-no-results">No results found</li>';
    } else {
      this.list.innerHTML = items.map(item =>
        `<li class="autocomplete-item" role="option">${item}</li>`
      ).join('');
    }
    this.show();
  }

  show() { this.list.style.display = 'block'; }
  hide() { this.list.style.display = 'none'; }
}

// Usage
new Autocomplete(document.getElementById('country'), {
  data: ['Australia', 'Austria', 'Belgium', ...],
  minLength: 2
});

When to Use

Use autocomplete when:

  • Users need to select from a large list (50+ options)
  • There is a defined set of valid options
  • Typing is faster than scrolling through a dropdown
  • Users might not know the exact value they need

Don't use autocomplete when:

  • The list is small (use a select dropdown instead)
  • Users need to see all options at once
  • Free-text input is acceptable

Accessibility

  • Use role="listbox" on the suggestions list
  • Use role="option" on each suggestion
  • Use aria-autocomplete="list" on the input
  • Support keyboard navigation (arrow keys, enter, escape)
  • Announce selected items to screen readers
  • Ensure minimum contrast on highlighted items

CSS Classes

.autocomplete { }
.autocomplete-list { }
.autocomplete-item { }
.autocomplete-item-highlighted { }
.autocomplete-no-results { }