Build a live filter
Bring structure, styling, and events together.
Start with useful HTML
The input has a visible label. The list is usable before JavaScript runs. JavaScript adds filtering without having to construct the content from scratch.
Normalize before comparing
toLowerCase makes the comparison case-insensitive. includes checks whether the item text contains the query. An empty query matches every string, so clearing the input restores every item.
Update only what changes
The hidden property controls whether each item is shown. The status paragraph reports the result count. This is a small complete interaction you can reuse in a reference page or a personal project.
Try the example
<style>
body { font: 16px sans-serif; padding: 24px; background: #f7f8f2; }
input { display: block; padding: 12px; margin: 12px 0; max-width: 100%; box-sizing: border-box; }
li { padding: 8px; }
</style>
<h1>Find your next topic.</h1>
<label for="search">Filter topics</label>
<input id="search" type="search" placeholder="Try CSS">
<ul><li>HTML structure</li><li>CSS layout</li><li>CSS colors</li><li>JavaScript events</li></ul>
<p id="status" role="status">4 topics</p>
<script>
document.querySelector("#search").addEventListener("input", (event) => {
const query = event.target.value.toLowerCase();
let visible = 0;
document.querySelectorAll("li").forEach((item) => {
item.hidden = !item.textContent.toLowerCase().includes(query);
if (!item.hidden) visible += 1;
});
document.querySelector("#status").textContent = `${visible} topics`;
});
</script>Enable JavaScript to edit and run the example in the playground.
Your turn
Add two more topics. Test an uppercase query, an empty query, and a query with no matches.
Check your understanding
Why convert both the query and item text to lowercase?
- To make the comparison case-insensitive
- To remove all spaces
- To sort the list
Show answer and explanation
To make the comparison case-insensitive. Normalizing both strings lets CSS match css without changing the displayed text.