Introduction
In the fast-paced world of web development, a dynamic search input with suggestions can significantly enhance user experience by providing real-time results. Whether you’re building an e-commerce site, a knowledge base, or a content-driven platform, implementing search auto-suggestions can improve usability and efficiency.
In this step-by-step guide, we will walk through the process of creating a search input with real-time suggestions using HTML, CSS, and JavaScript. By the end of this tutorial, you will have a fully functional autocomplete search feature that dynamically filters results as users type.

Table of Contents
Prerequisites
Before getting started, ensure you have a basic understanding of:
- HTML for structuring the search input field
- CSS for styling the search bar and suggestions dropdown
- JavaScript for handling the dynamic filtering of search results
You’ll also need a text editor (such as VS Code) and a web browser to test your implementation.
1. Setting Up the HTML Structure
We’ll begin by creating a simple HTML structure for our search bar. This will include:
- A text input field for user input
- A dropdown container to display suggestions
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Building a Dynamic Search Input with Suggestions: A Step-by-Step Guide</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
</head>
<body translate="no">
<div class="search-wrapper">
<div class="search-input">
<input type="text" placeholder="Type to search..." id="searchInput">
<div id="suggestions">
<a href="#">Khushal</a>
<a href="#">Vishal</a>
<a href="#">Hiren</a>
<a href="#">Jaydip</a>
<a href="#">Abhay</a>
<a href="#">Bhavik</a>
<a href="#">Darsh</a>
<a href="#">Mayur</a>
</div>
<div class="search-icon"><i class="fas fa-search"></i></div>
<div class="error-message" id="errorMessage">No matching suggestion found</div>
<div class="cancel-button" id="cancelButton"><i class="fas fa-times-circle"></i></div>
</div>
</div>
</body>
</html>
2. Styling with CSS
A well-designed search bar enhances usability. Let’s apply CSS to style our search input and suggestions dropdown.
<style>
/* Add your styles here */
.search-wrapper {
margin: 50px;
}
.search-input {
position: relative;
max-width: 300px;
margin: auto;
}
input[type="text"] {
width: calc(100% - 32px);
padding: 8px;
padding-left: 35px;
outline: none;
border: 2px solid #ccc;
border-radius: 50px;
}
input[type="text"]:focus {
border: 2px solid rgb(146, 146, 146) !important;
}
#suggestions {
list-style: none;
padding: 0;
display: none;
position: absolute;
background-color: white;
width: 100%;
border: 1px solid #ccc;
z-index: 1;
}
#suggestions a {
display: block;
padding: 8px;
border-bottom: 1px solid #eee;
text-decoration: none;
color: #333;
}
#suggestions a:last-child {
border-bottom: none;
}
input::placeholder {
color: rgb(146, 146, 146);
}
.error-message {
display: none;
color: red;
margin-top: 5px;
}
.cancel-button {
position: absolute;
top: 19px;
right: 0px;
transform: translateY(-50%);
cursor: pointer;
display: none;
}
.search-icon{
position: absolute;
top: 8px;
left: 10px;
}
</style>
3. Implementing Dynamic Search with JavaScript
Now, we’ll add JavaScript functionality to filter and display suggestions dynamically.
4. Enhancing User Interaction
To improve usability, we’ll add:
- A reset button to clear input
- Keyboard navigation support
Modify the HTML and JavaScript:
<script id="rendered-js" >
const searchInput = document.getElementById('searchInput');
const suggestionsList = document.getElementById('suggestions');
const errorMessage = document.getElementById('errorMessage');
const cancelButton = document.getElementById('cancelButton');
searchInput.addEventListener('input', function () {
const inputValue = this.value.trim().toLowerCase();
const suggestionItems = suggestionsList.querySelectorAll('a');
let hasMatches = false;
suggestionItems.forEach(function (listItem) {
const textValue = listItem.textContent.toLowerCase();
const displayStyle = textValue.includes(inputValue) ? 'block' : 'none';
listItem.style.display = displayStyle;
hasMatches = hasMatches || displayStyle === 'block';
});
suggestionsList.style.display = hasMatches ? 'block' : 'none';
errorMessage.style.display = hasMatches || inputValue.length === 0 ? 'none' : 'block';
cancelButton.style.display = inputValue.length > 0 ? 'block' : 'none';
});
cancelButton.addEventListener('click', function () {
searchInput.value = '';
suggestionsList.style.display = 'none';
errorMessage.style.display = 'none';
cancelButton.style.display = 'none';
});
//# sourceURL=pen.js
</script>
Conclusion
Congratulations! 🎉 You’ve successfully built a dynamic search input with suggestions. Here’s what we covered:
- Structuring the HTML for a search bar
- Styling it with CSS for a clean UI
- Implementing JavaScript to filter and display search suggestions dynamically
- Enhancing user experience with reset functionality
Feel free to extend this functionality by:
- Fetching search suggestions from an API or database
- Adding animations for a smoother experience
- Making it mobile-responsive
Full Source Code: [CodePen Link Here]
Happy coding! 🚀
Full Source Code
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<meta name="apple-mobile-web-app-title" content="CodePen">
<title>CodePen - Building a Dynamic Search Input with Suggestions: A Step-by-Step Guide</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
</head>
<style>
/* Add your styles here */
.search-wrapper {
margin: 50px;
}
.search-input {
position: relative;
max-width: 300px;
margin: auto;
}
input[type="text"] {
width: calc(100% - 32px);
padding: 8px;
padding-left: 35px;
outline: none;
border: 2px solid #ccc;
border-radius: 50px;
}
input[type="text"]:focus {
border: 2px solid rgb(146, 146, 146) !important;
}
#suggestions {
list-style: none;
padding: 0;
display: none;
position: absolute;
background-color: white;
width: 100%;
border: 1px solid #ccc;
z-index: 1;
}
#suggestions a {
display: block;
padding: 8px;
border-bottom: 1px solid #eee;
text-decoration: none;
color: #333;
}
#suggestions a:last-child {
border-bottom: none;
}
input::placeholder {
color: rgb(146, 146, 146);
}
.error-message {
display: none;
color: red;
margin-top: 5px;
}
.cancel-button {
position: absolute;
top: 19px;
right: 0px;
transform: translateY(-50%);
cursor: pointer;
display: none;
}
.search-icon{
position: absolute;
top: 8px;
left: 10px;
}
</style>
<body translate="no">
<div class="search-wrapper">
<div class="search-input">
<input type="text" placeholder="Type to search..." id="searchInput">
<div id="suggestions">
<a href="#">Khushal</a>
<a href="#">Vishal</a>
<a href="#">Hiren</a>
<a href="#">Jaydip</a>
<a href="#">Abhay</a>
<a href="#">Bhavik</a>
<a href="#">Darsh</a>
<a href="#">Mayur</a>
</div>
<div class="search-icon"><i class="fas fa-search"></i></div>
<div class="error-message" id="errorMessage">No matching suggestion found</div>
<div class="cancel-button" id="cancelButton"><i class="fas fa-times-circle"></i></div>
</div>
</div>
<script id="rendered-js" >
const searchInput = document.getElementById('searchInput');
const suggestionsList = document.getElementById('suggestions');
const errorMessage = document.getElementById('errorMessage');
const cancelButton = document.getElementById('cancelButton');
searchInput.addEventListener('input', function () {
const inputValue = this.value.trim().toLowerCase();
const suggestionItems = suggestionsList.querySelectorAll('a');
let hasMatches = false;
suggestionItems.forEach(function (listItem) {
const textValue = listItem.textContent.toLowerCase();
const displayStyle = textValue.includes(inputValue) ? 'block' : 'none';
listItem.style.display = displayStyle;
hasMatches = hasMatches || displayStyle === 'block';
});
suggestionsList.style.display = hasMatches ? 'block' : 'none';
errorMessage.style.display = hasMatches || inputValue.length === 0 ? 'none' : 'block';
cancelButton.style.display = inputValue.length > 0 ? 'block' : 'none';
});
cancelButton.addEventListener('click', function () {
searchInput.value = '';
suggestionsList.style.display = 'none';
errorMessage.style.display = 'none';
cancelButton.style.display = 'none';
});
//# sourceURL=pen.js
</script>
</body>
</html>