May
10

How to Create an Autocomplete Search Box

05/10/2025 12:00 AM by How to Create an Autocomplete Search Box in Html


autocomplete search

 

Creating an autocomplete search box is a powerful way to enhance user experience on websites or applications. This feature provides real-time suggestions as users type, making search faster and more intuitive. In this comprehensive guide, we’ll walk through building an autocomplete search box using HTML, CSS, and JavaScript, with a focus on accessibility, responsiveness, and modern design. We’ll include examples, link to free AI tools for development, and provide a complete code snippet.

Why Use an Autocomplete Search Box?

Autocomplete search boxes are essential for modern websites, especially e-commerce platforms, blogs, or content-heavy applications. Benefits include:

  • Improved User Experience: Suggestions help users find content quickly.

  • Efficiency: Reduces typing time and errors.

  • Engagement: Encourages exploration of related content.

  • Accessibility: Assists users with diverse abilities or language barriers.

This tutorial will cover:

  • Structuring the search box with HTML.

  • Styling it with CSS for aesthetics and responsiveness.

  • Implementing autocomplete functionality with JavaScript.

  • Using free AI tools to enhance development.

  • Providing a complete, ready-to-use code snippet.

  • Offering a complex SVG image as the article’s Featured Image.

Step 1: Setting Up the HTML Structure

The autocomplete search box will consist of an input field and a suggestion list that appears dynamically. We’ll ensure accessibility with ARIA attributes and semantic HTML.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Autocomplete Search Box</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="search-container">
    <h1>Autocomplete Search</h1>
    <div class="search-wrapper">
      <input type="text" id="searchInput" placeholder="Search..." aria-label="Search" autocomplete="off">
      <ul id="suggestions" role="listbox" aria-live="polite"></ul>
    </div>
  </div>
  <script src="script.js"></script>
</body>
</html>

 

Explanation

  • Input Field: The type="text" input allows user typing, with autocomplete="off" to prevent browser defaults.

  • Suggestion List: A <ul> element dynamically populated with suggestions, marked with role="listbox" for accessibility.

  • ARIA Attributes: aria-label and aria-live ensure screen readers announce suggestions.

Step 2: Styling with CSS

The CSS will make the search box visually appealing, responsive, and interactive. The suggestion list will appear below the input with smooth transitions.

body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  margin: 0;
  background-color: #f4f7fa;
}

.search-container {
  background: white;
  padding: 30px;
  border-radius: 12px;
  box-shadow: 0  unitsize: 0.5;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
  text-align: center;
  max-width: 400px;
  margin: 0 auto;
}

h1 {
  font-size: 28px;
  margin-bottom: 20px;
  color: #333;
}

.search-wrapper {
  position: relative;
  width: 100%;
}

input {
  width: 100%;
  padding: 12px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 8px;
  outline: none;
  transition: border-color 0.3s;
}

input:focus {
  border-color: #007bff;
}

#suggestions {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: white;
  border: 1px solid #ccc;
  border-radius: 8px;
  max-height: 200px;
  overflow-y: auto;
  margin-top: 5px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  z-index: 10;
}

#suggestions li {
  padding: 10px;
  cursor: pointer;
  transition: background 0.2s;
}

#suggestions li:hover {
  background: #e8ecef;
}

#suggestions li.active {
  background: #007bff;
  color: white;
}

@media (max-width: 600px) {
  .search-container {
    padding: 20px;
    max-width: 90%;
  }

  h1 {
    font-size: 24px;
  }

  input {
    font-size: 14px;
    padding: 10px;
  }
}

 

Explanation

  • Flexbox: Centers the search box on the page.

  • Responsive Design: Adjusts padding and font sizes for mobile devices.

  • Styling: Smooth transitions, hover effects, and a clean, modern look.

  • Accessibility: High contrast and clear focus states.

Step 3: Adding JavaScript for Autocomplete

JavaScript will handle user input, filter suggestions, and manage keyboard navigation. We’ll use a static array for suggestions, but you can replace it with an API for dynamic data.

const suggestionsData = [
  'JavaScript',
  'HTML',
  'CSS',
  'React',
  'Vue',
  'Angular',
  'Node.js',
  'Python',
  'Django',
  'Flask',
  'Ruby',
  'Rails',
  'PHP',
  'Laravel',
  'Java',
  'Spring',
];

const searchInput = document.getElementById('searchInput');
const suggestionsList = document.getElementById('suggestions');

searchInput.addEventListener('input', handleInput);
searchInput.addEventListener('keydown', handleKeydown);

function handleInput() {
  const query = this.value.trim().toLowerCase();
  suggestionsList.innerHTML = '';

  if (query) {
    const filteredSuggestions = suggestionsData.filter(item =>
      item.toLowerCase().includes(query)
    );

    filteredSuggestions.forEach((suggestion, index) => {
      const li = document.createElement('li');
      li.textContent = suggestion;
      li.setAttribute('role', 'option');
      li.setAttribute('aria-selected', 'false');
      li.addEventListener('click', () => selectSuggestion(suggestion));
      suggestionsList.appendChild(li);
    });
  }
}

function handleKeydown(e) {
  const items = suggestionsList.querySelectorAll('li');
  const activeItem = suggestionsList.querySelector('li.active');
  let index = activeItem ? Array.from(items).indexOf(activeItem) : -1;

  if (e.key === 'ArrowDown') {
    e.preventDefault();
    index = Math.min(index + 1, items.length - 1);
    updateActiveItem(items, index);
  } else if (e.key === 'ArrowUp') {
    e.preventDefault();
    index = Math.max(index - 1, 0);
    updateActiveItem(items, index);
  } else if (e.key === 'Enter' && activeItem) {
    e.preventDefault();
    selectSuggestion(activeItem.textContent);
  }
}

function updateActiveItem(items, index) {
  items.forEach(item => item.classList.remove('active'));
  if (index >= 0) {
    items[index].classList.add('active');
    items[index].setAttribute('aria-selected', 'true');
  }
}

function selectSuggestion(suggestion) {
  searchInput.value = suggestion;
  suggestionsList.innerHTML = '';
}

 

Explanation

  • Filtering: Matches user input against the suggestion array.

  • Keyboard Navigation: Supports ArrowUp, ArrowDown, and Enter keys for accessibility.

  • Selection: Updates the input field and clears suggestions on selection.

  • Extensibility: Easily swap the static array for an API call (e.g., fetch suggestions from a server).

Step 4: Using Free AI Tools

Enhance your development process with these free AI-powered tools:

  • CodePen: Test and share your HTML, CSS, and JavaScript code.

  • Canva: Create custom icons or visuals for the search box.

  • Figma: Design and prototype the UI before coding.

  • ColorSpace: Generate accessible color schemes.

  • WAVE Accessibility Checker: Ensure WCAG compliance.

These tools are beginner-friendly and can streamline design and testing.

Step 5: Ensuring Accessibility

To make the search box inclusive:

  • Use role="listbox" and aria-live for screen readers.

  • Ensure a contrast ratio of at least 4.5:1 (e.g., text on #007bff).

  • Support keyboard navigation (Tab, Arrow keys, Enter).

  • Validate with WAVE to meet WCAG 2.1 standards.

Step 6: Testing and Deployment

Test the search box in Chrome, Firefox, and Safari, and on mobile devices. For deployment, use:

  • GitHub Pages: Host the search box for free.

  • Netlify: Deploy with Git integration or drag-and-drop.

  • Vercel: Fast deployment with automatic scaling.

 

Complete Code

Below is the complete code for the autocomplete search box, combining HTML, CSS, and JavaScript. The suggestions use a static array, but you can modify it to fetch data dynamically.

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Autocomplete Search Box</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      margin: 0;
      background-color: #f4f7fa;
    }

    .search-container {
      background: white;
      padding: 30px;
      border-radius: 12px;
      box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
      text-align: center;
      max-width: 400px;
      width: 100%;
    }

    h1 {
      font-size: 28px;
      margin-bottom: 20px;
      color: #333;
    }

    .search-wrapper {
      position: relative;
      width: 100%;
    }

    input {
      width: 100%;
      padding: 12px;
      font-size: 16px;
      border: 1px solid #ccc;
      border-radius: 8px;
      outline: none;
      transition: border-color 0.3s;
    }

    input:focus {
      border-color: #007bff;
    }

    #suggestions {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      background: white;
      border: 1px solid #ccc;
      border-radius: 8px;
      max-height: 200px;
      overflow-y: auto;
      margin-top: 5px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
      z-index: 10;
    }

    #suggestions li {
      padding: 10px;
      cursor: pointer;
      transition: background 0.2s;
    }

    #suggestions li:hover {
      background: #e8ecef;
    }

    #suggestions li.active {
      background: #007bff;
      color: white;
    }

    @media (max-width: 600px) {
      .search-container {
        padding: 20px;
        max-width: 90%;
      }

      h1 {
        font-size: 24px;
      }

      input {
        font-size: 14px;
        padding: 10px;
      }
    }
  </style>
</head>
<body>
  <div class="search-container">
    <h1>Autocomplete Search</h1>
    <div class="search-wrapper">
      <input type="text" id="searchInput" placeholder="Search..." aria-label="Search" autocomplete="off">
      <ul id="suggestions" role="listbox" aria-live="polite"></ul>
    </div>
  </div>
  <script>
    const suggestionsData = [
      'JavaScript',
      'HTML',
      'CSS',
      'React',
      'Vue',
      'Angular',
      'Node.js',
      'Python',
      'Django',
      'Flask',
      'Ruby',
      'Rails',
      'PHP',
      'Laravel',
      'Java',
      'Spring',
    ];

    const searchInput = document.getElementById('searchInput');
    const suggestionsList = document.getElementById('suggestions');

    searchInput.addEventListener('input', handleInput);
    searchInput.addEventListener('keydown', handleKeydown);

    function handleInput() {
      const query = this.value.trim().toLowerCase();
      suggestionsList.innerHTML = '';

      if (query) {
        const filteredSuggestions = suggestionsData.filter(item =>
          item.toLowerCase().includes(query)
        );

        filteredSuggestions.forEach((suggestion, index) => {
          const li = document.createElement('li');
          li.textContent = suggestion;
          li.setAttribute('role', 'option');
          li.setAttribute('aria-selected', 'false');
          li.addEventListener('click', () => selectSuggestion(suggestion));
          suggestionsList.appendChild(li);
        });
      }
    }

    function handleKeydown(e) {
      const items = suggestionsList.querySelectorAll('li');
      const activeItem = suggestionsList.querySelector('li.active');
      let index = activeItem ? Array.from(items).indexOf(activeItem) : -1;

      if (e.key === 'ArrowDown') {
        e.preventDefault();
        index = Math.min(index + 1, items.length - 1);
        updateActiveItem(items, index);
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        index = Math.max(index - 1, 0);
        updateActiveItem(items, index);
      } else if (e.key === 'Enter' && activeItem) {
        e.preventDefault();
        selectSuggestion(activeItem.textContent);
      }
    }

    function updateActiveItem(items, index) {
      items.forEach(item => item.classList.remove('active'));
      if (index >= 0) {
        items[index].classList.add('active');
        items[index].setAttribute('aria-selected', 'true');
      }
    }

    function selectSuggestion(suggestion) {
      searchInput.value = suggestion;
      suggestionsList.innerHTML = '';
    }
  </script>
</body>
</html>