HomeJavascriptBuild an Image Gallery with Search and Filter Using HTML, CSS, and...

Build an Image Gallery with Search and Filter Using HTML, CSS, and JavaScript

Creating an image gallery that allows users to search and filter images by category is a great way to practice basic web development skills. In this tutorial, we’ll walk through the HTML, CSS, and JavaScript that together build a simple but beautiful image gallery.

Video Tutorial:

HTML:

The HTML lays the foundation of our gallery. Inside the <section> element with the class gallery-section, we have a container that includes the title, search box, filter buttons, and the gallery itself. Each image in the gallery is wrapped inside a div with the class gallery-item. Important attributes like data-category and data-title are used to store the image’s category (nature, people, tech) and title, making it easier for JavaScript to filter them later. Overall, the HTML provides a clean, semantic layout that’s easy to style and manipulate.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="style.css" />
    <title>Image Gallery With Search And Filter</title>
  </head>
  <body>
    <section class="gallery-section">
      <div class="container">
        <h1 class="title">Image Gallery</h1>
        <div class="controls">
          <input type="text" id="searchBox" placeholder="Search images" />
          <div class="filter-buttons">
            <button class="filter-btn active" data-filter="all">All</button>
            <button class="filter-btn" data-filter="nature">Nature</button>
            <button class="filter-btn" data-filter="people">People</button>
            <button class="filter-btn" data-filter="tech">Tech</button>
          </div>
        </div>
        <div class="gallery" id="gallery">
          <!--Nature-->
          <div
            class="gallery-item"
            data-category="nature"
            data-title="Forest
            Trail"
          >
            <img src="Forest Trail.jpg" alt="Forest Trail" />
            <p>Forest Trail</p>
          </div>
          <div
            class="gallery-item"
            data-category="nature"
            data-title="Mountain View"
          >
            <img src="Mountain View.jpg" alt="Mountain View" />
            <p>Mountain View</p>
          </div>
          <div
            class="gallery-item"
            data-category="nature"
            data-title="Beach Sunset"
          >
            <img src="Beach Sunset.jpg" alt="Beach Sunset" />
            <p>Beach Sunset</p>
          </div>
          <div
            class="gallery-item"
            data-category="nature"
            data-title="River
            Stream"
            alt="River Stream"
          >
            <img src="River Stream.jpg" alt="River Stream" />
            <p>River Stream</p>
          </div>

          <!--Tech-->
          <div
            class="gallery-item"
            data-category="tech"
            data-title="Laptop Workspace"
          >
            <img src="Laptop Workspace.jpg" alt="Laptop Workspace" />
            <p>Laptop Workspace</p>
          </div>
          <div
            class="gallery-item"
            data-category="tech"
            data-title="Smartphone
          Setup"
          >
            <img src="Smartphone Setup.jpg" alt="Smartphone Setup" />
            <p>Smartphone Setup</p>
          </div>
          <div
            class="gallery-item"
            data-category="tech"
            data-title="Tech Accesories"
          >
            <img src="Tech Accesories.jpg" alt="Tech Accesories" />
            <p>Tech Accesories</p>
          </div>
          <!-- People -->
          <div
            class="gallery-item"
            data-category="people"
            data-title="Smiling Woman"
          >
            <img src="smiling woman.jpg" alt="Smiling Woman" />
            <p>Smiling Woman</p>
          </div>
          <div
            class="gallery-item"
            data-category="people"
            data-title="Team Meeting"
          >
            <img src="Team Meting.jpg" alt="Team Meeting" />
            <p>Team Meeting</p>
          </div>
          <div
            class="gallery-item"
            data-category="people"
            data-title="Street Portrait"
          >
            <img src="street portrait.jpg" />
            <p>Street Potrait</p>
          </div>
        </div>
      </div>
    </section>
    <script src="script.js"></script>
  </body>
</html>

CSS:

The CSS makes the gallery look visually appealing and responsive. We start by setting up the body with a nice font (Poppins) and a light background color. The container is centered with a maximum width and some padding. The controls section is designed with flexbox to stack the search box and buttons nicely. Each button is styled with rounded corners and smooth hover effects. The gallery itself uses CSS columns to automatically arrange images in a responsive, masonry-like grid, adjusting the number of columns based on the screen size. The gallery items have subtle shadows, rounded corners, and padding for a clean, modern appearance.

body {
  font-family: "Poppins", sans-serif;
  margin: 0;
  padding: 0;
  background-color: #f9fafb;
  color: #111827;
}
.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 2rem;
}
.title {
  font-size: 2rem;
  font-weight: 600;
  text-align: center;
  margin-bottom: 2rem;
}
.controls {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-bottom: 2rem;
}
#searchBox {
  padding: 0.75rem 1rem;
  width: 100%;
  max-width: 400px;
  border: 2px solid #e5e7eb;
  border-radius: 0.5rem;
  font-size: 1rem;
  margin: 0 auto;
}
.filter-buttons {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.filter-btn {
  padding: 0.5rem 1rem;
  border: none;
  background-color: #e5e7eb;
  border-radius: 20px;
  cursor: pointer;
  font-weight: 500;
  transition: background 0.3s ease;
}
.filter-btn.active,
.filter-btn:hover {
  background-color: #111827;
  color: #ffffff;
}
.gallery {
  column-count: 1;
  column-gap: 1.5rem;
}
@media (min-width: 600px) {
  .gallery {
    column-count: 2;
  }
}
@media (min-width: 900px) {
  .gallery {
    column-count: 3;
  }
}
.gallery-item {
  display: inline-block;
  width: 100%;
  margin-bottom: 1.5rem;
  background: #ffffff;
  border-radius: 1rem;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  text-align: center;
  transition: transform 0.3s ease;
  break-inside: avoid;
}
.gallery-item img {
  width: 100%;
  height: auto;
  display: block;
}
.gallery-item p {
  margin: 0;
  padding: 1rem;
  font-weight: 500;
}

Javascript:

The JavaScript adds interactivity to the gallery. First, we select the search box, filter buttons, and all gallery items. When a user clicks on a filter button, we update which button is active and call the updateGallery() function, passing in the selected category and search text. Similarly, whenever the user types in the search box, the gallery is updated in real-time. The updateGallery() function checks if each image matches the selected category and if its title includes the search term. If it matches both, the image is shown; otherwise, it’s hidden. This creates a seamless search and filter experience without reloading the page.

const searchBox = document.getElementById("searchBox");
const filterButtons = document.querySelectorAll(".filter-btn");
const galleryItems = document.querySelectorAll(".gallery-item");

filterButtons.forEach((btn) => {
  btn.addEventListener("click", () => {
    document.querySelector(".filter-btn.active").classList.remove("active");
    btn.classList.add("active");
    const filter = btn.getAttribute("data-filter");
    updateGallery(filter, searchBox.value.toLowerCase());
  });
});

searchBox.addEventListener("input", () => {
  const filter = document
    .querySelector(".filter-btn.active")
    .getAttribute("data-filter");
  updateGallery(filter, searchBox.value.toLowerCase());
});

function updateGallery(category, searchTerm) {
  galleryItems.forEach((item) => {
    const matchesCategory =
      category === "all" || item.dataset.category === category;
    const matchesSearch = item.dataset.title.toLowerCase().includes(searchTerm);
    item.style.display =
      matchesCategory && matchesSearch ? "inline-block" : "none";
  });
}

Conclusion

By combining HTML, CSS, and JavaScript, we can easily build an interactive image gallery that looks professional and feels responsive. HTML structures the content, CSS beautifies it, and JavaScript brings it to life with real-time search and category filtering. Projects like these not only strengthen your web development skills but also prepare you to build more complex, dynamic websites in the future. Keep experimenting with more categories, animations, and layout tweaks to make your gallery even more impressive!

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

ten − 9 =

Most Popular