This small directory adds local filtering to three readable project cards. Without JavaScript, all cards remain available.
Open the working example → · Download complete project (ZIP)
Build it step by step
- Read the data-tags attributes on each card.
- Type “photo”, “code” or “travel” into the filter.
- Try a word with no matches, then clear the field.
- Add a fourth card with its own tags and repeat the test.
How it works
The script reads existing text and data attributes. It changes the hidden state without rebuilding the content. The status message announces the number of matches to assistive technology.
Read the JavaScript
const input=document.querySelector('#filter');
const cards=[...document.querySelectorAll('[data-tags]')];
const status=document.querySelector('#count');
document.querySelector('#filter-ui').hidden=false;
function filter(){const query=input.value.trim().toLowerCase();let count=0;for(const card of cards){const text=(card.textContent+' '+card.dataset.tags).toLowerCase();card.hidden=!text.includes(query);if(!card.hidden)count++;}status.textContent=count?`${count} projects shown.`:'No matches. Try another word or clear the filter.';}
input.addEventListener('input',filter);filter();A small mistake to watch for
Using case-sensitive matching makes “Photo” and “photo” behave differently. Normalise both the query and the searchable text.
Check your work
Try a narrow window, enlarged text and keyboard navigation. Read the complete HTML, CSS and any JavaScript in the download. These examples use fictional sample content and no external libraries.