• ;
  • A Coding Boy
  • Blog
  • Videos
  • Projects
  • Home
HTML AND CSS
LOGIN PAGE
WEBSITE DESGIN
API PROJECTS
CARD DESGIN
JAVASCRIPTS GAMES
JAVASCRIPT PROJECTS
JAVA PROJECTS
PYTHON PROJECTS
demo post
only for demo nasa prospect
only for demo the gonnies
most popular
how to create parallax website
how to create a beautiful card
how to create a netflix login page
how to create flipping ui card
how to create image generator website
Create Functional Image Gallery in HTML CSS & JavaScript
If you’re a web designer or developer, you must have searched for copyright-free images for your projects on various websites. Pexels is one of the most popular sites for such images. But as a web developer, have you ever wanted to create a functional image gallery similar to Pexels?
In this blog post, I’ll show the steps for creating a fully-functional image gallery using HTML, CSS, and JavaScript. Not only will you learn the basics of DOM manipulation, event handling, and CSS styling, but you’ll also gain valuable experience working with APIs. With this Pexels clone coding project, you can effortlessly search, view, and download any image you desire, all within seconds. The images are displayed in a stylish masonry layout which looks great on any device, from desktops to mobile phones.
Creating Image Gallery [Source Code]
First, paste the following codes into your index.html file.
Plain text
Copy to clipboard
Open in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<!-- Coding By CodingNepal - youtube.com/codingnepal -->
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Image Gallery with JavaScript | CodingNepal</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.0/css/line.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="lightbox">
<div class="wrapper">
<header>
<div class="photographer">
<i class="uil uil-camera"></i>
<span></span>
</div>
<div class="buttons">
<i class="uil uil-import"></i>
<i class="close-icon uil uil-times"></i>
</div>
</header>
<div class="preview-img">
<div class="img"><img src="" alt="preview-img"></div>
</div>
</div>
</div>
<section class="search">
<img src="./images/search-img.jpg" alt="search-img">
<div class="content">
<h1>Image Gallery with JavaScript</h1>
<p>Search and download any images within a second</p>
<div class="search-box">
<i class="uil uil-search"></i>
<input type="text" placeholder="Search images">
</div>
</div>
</section>
<section class="gallery">
<ul class="images"></ul>
<button class="load-more">Load More</button>
</section>
</body>
</html>
<!DOCTYPE html> <!-- Coding By CodingNepal - youtube.com/codingnepal --> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Image Gallery with JavaScript | CodingNepal</title> <link rel="stylesheet" href="style.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.0/css/line.css"> <script src="script.js" defer></script> </head> <body> <div class="lightbox"> <div class="wrapper"> <header> <div class="photographer"> <i class="uil uil-camera"></i> <span></span> </div> <div class="buttons"> <i class="uil uil-import"></i> <i class="close-icon uil uil-times"></i> </div> </header> <div class="preview-img"> <div class="img"><img src="" alt="preview-img"></div> </div> </div> </div> <section class="search"> <img src="./images/search-img.jpg" alt="search-img"> <div class="content"> <h1>Image Gallery with JavaScript</h1> <p>Search and download any images within a second</p> <div class="search-box"> <i class="uil uil-search"></i> <input type="text" placeholder="Search images"> </div> </div> </section> <section class="gallery"> <ul class="images"></ul> <button class="load-more">Load More</button> </section> </body> </html>
Second, paste the following codes into your style.css file
Plain text
Copy to clipboard
Open in new window
EnlighterJS 3 Syntax Highlighter
/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
.search {
height: 40vh;
display: flex;
position: relative;
align-items: center;
justify-content: center;
}
.search::before, .search img, .lightbox {
left: 0;
top: 0;
width: 100%;
height: 100%;
position: absolute;
}
.search::before {
content: "";
z-index: 1;
background: rgba(0,0,0,0.25);
}
.search img {
object-fit: cover;
}
.search .content {
z-index: 2;
color: #fff;
padding: 0 13px;
text-align: center;
position: relative;
}
.search h1 {
font-size: 2.65rem;
font-weight: 600;
}
.search p {
margin-top: 8px;
font-size: 1.5rem;
}
.search .search-box {
height: 55px;
margin: 45px 0;
position: relative;
}
.search-box i {
position: absolute;
left: 20px;
top: 50%;
cursor: default;
color: #8D8D8D;
font-size: 1.4rem;
transform: translateY(-50%);
}
.search-box input {
width: 100%;
height: 100%;
outline: none;
border: none;
font-size: 1.1rem;
padding-left: 55px;
background: #fff;
border-radius: 5px;
}
.search-box input::placeholder {
color: #929292;
}
.search-box input:focus::placeholder {
color: #bfbfbf;
}
.gallery {
display: flex;
flex-direction: column;
align-items: center;
}
.gallery .images {
gap: 15px;
max-width: 95%;
margin-top: 40px;
columns: 5 340px;
list-style: none;
}
.gallery .images .card {
display: flex;
cursor: pointer;
overflow: hidden;
position: relative;
margin-bottom: 14px;
border-radius: 4px;
}
.gallery .images img {
width: 100%;
z-index: 2;
position: relative;
}
.images .details {
position: absolute;
z-index: 4;
width: 100%;
bottom: -100px;
display: flex;
align-items: center;
padding: 15px 20px;
justify-content: space-between;
transition: bottom 0.1s ease;
background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
}
.images li:hover .details {
bottom: 0;
}
.photographer {
color: #fff;
display: flex;
align-items: center;
}
.photographer i {
font-size: 1.4rem;
margin-right: 10px;
}
.photographer span {
font-size: 1.05rem;
}
button, i {
outline: none;
border: none;
cursor: pointer;
border-radius: 5px;
transition: 0.2s ease;
}
.details button {
background: #fff;
font-size: 1.1rem;
padding: 3px 8px;
}
.details .download-btn:hover {
background: #f2f2f2;
}
.gallery .load-more {
color: #fff;
background: #8A6CFF;
margin: 50px 0;
font-size: 1.2rem;
padding: 12px 27px;
}
.gallery .load-more.disabled {
opacity: 0.6;
pointer-events: none;
}
.gallery .load-more:hover {
background: #704dff;
}
.lightbox {
z-index: 5;
position: fixed;
visibility: hidden;
background: rgba(0,0,0,0.65);
}
.lightbox.show {
visibility: visible;
}
.lightbox .wrapper {
position: fixed;
left: 50%;
top: 50%;
width: 100%;
padding: 20px;
max-width: 850px;
background: #fff;
border-radius: 6px;
opacity: 0;
pointer-events: none;
transform: translate(-50%, -50%) scale(0.9);
transition: transform 0.1s ease;
}
.lightbox.show .wrapper {
opacity: 1;
pointer-events: auto;
transform: translate(-50%, -50%) scale(1);
}
.wrapper header {
display: flex;
align-items: center;
justify-content: space-between;
}
header .photographer {
color: #333;
}
header .photographer i {
font-size: 1.7rem;
cursor: auto;
}
header .photographer span {
font-size: 1.2rem;
}
header .buttons i {
height: 40px;
width: 40px;
display: inline-block;
color: #fff;
font-size: 1.2rem;
line-height: 40px;
text-align: center;
background: #8A6CFF;
border-radius: 4px;
transition: 0.2s ease;
}
header .buttons i:first-child:hover {
background: #704dff;
}
header .buttons i:last-child {
margin-left: 10px;
font-size: 1.25rem;
background: #6C757D;
}
header .buttons i:last-child:hover {
background: #5f666d;
}
.wrapper .preview-img {
display: flex;
justify-content: center;
margin-top: 25px;
}
.preview-img .img {
max-height: 65vh;
}
.preview-img img {
width: 100%;
height: 100%;
object-fit: contain;
}
@media screen and (max-width: 688px) {
.lightbox .wrapper {
padding: 12px;
max-width: calc(100% - 26px);
}
.wrapper .preview-img {
margin-top: 15px;
}
header .buttons i:last-child {
margin-left: 7px;
}
header .photographer span, .search p {
font-size: 1.1rem;
}
.search h1 {
font-size: 1.8rem;
}
.search .search-box {
height: 50px;
margin: 30px 0;
}
.gallery .images {
max-width: 100%;
padding: 0 13px;
margin-top: 20px;
}
.images .details {
bottom: 0px;
}
.gallery .load-more {
padding: 10px 25px;
font-size: 1.05rem;
}
}
/* Import Google font - Poppins */ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } .search { height: 40vh; display: flex; position: relative; align-items: center; justify-content: center; } .search::before, .search img, .lightbox { left: 0; top: 0; width: 100%; height: 100%; position: absolute; } .search::before { content: ""; z-index: 1; background: rgba(0,0,0,0.25); } .search img { object-fit: cover; } .search .content { z-index: 2; color: #fff; padding: 0 13px; text-align: center; position: relative; } .search h1 { font-size: 2.65rem; font-weight: 600; } .search p { margin-top: 8px; font-size: 1.5rem; } .search .search-box { height: 55px; margin: 45px 0; position: relative; } .search-box i { position: absolute; left: 20px; top: 50%; cursor: default; color: #8D8D8D; font-size: 1.4rem; transform: translateY(-50%); } .search-box input { width: 100%; height: 100%; outline: none; border: none; font-size: 1.1rem; padding-left: 55px; background: #fff; border-radius: 5px; } .search-box input::placeholder { color: #929292; } .search-box input:focus::placeholder { color: #bfbfbf; } .gallery { display: flex; flex-direction: column; align-items: center; } .gallery .images { gap: 15px; max-width: 95%; margin-top: 40px; columns: 5 340px; list-style: none; } .gallery .images .card { display: flex; cursor: pointer; overflow: hidden; position: relative; margin-bottom: 14px; border-radius: 4px; } .gallery .images img { width: 100%; z-index: 2; position: relative; } .images .details { position: absolute; z-index: 4; width: 100%; bottom: -100px; display: flex; align-items: center; padding: 15px 20px; justify-content: space-between; transition: bottom 0.1s ease; background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent); } .images li:hover .details { bottom: 0; } .photographer { color: #fff; display: flex; align-items: center; } .photographer i { font-size: 1.4rem; margin-right: 10px; } .photographer span { font-size: 1.05rem; } button, i { outline: none; border: none; cursor: pointer; border-radius: 5px; transition: 0.2s ease; } .details button { background: #fff; font-size: 1.1rem; padding: 3px 8px; } .details .download-btn:hover { background: #f2f2f2; } .gallery .load-more { color: #fff; background: #8A6CFF; margin: 50px 0; font-size: 1.2rem; padding: 12px 27px; } .gallery .load-more.disabled { opacity: 0.6; pointer-events: none; } .gallery .load-more:hover { background: #704dff; } .lightbox { z-index: 5; position: fixed; visibility: hidden; background: rgba(0,0,0,0.65); } .lightbox.show { visibility: visible; } .lightbox .wrapper { position: fixed; left: 50%; top: 50%; width: 100%; padding: 20px; max-width: 850px; background: #fff; border-radius: 6px; opacity: 0; pointer-events: none; transform: translate(-50%, -50%) scale(0.9); transition: transform 0.1s ease; } .lightbox.show .wrapper { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); } .wrapper header { display: flex; align-items: center; justify-content: space-between; } header .photographer { color: #333; } header .photographer i { font-size: 1.7rem; cursor: auto; } header .photographer span { font-size: 1.2rem; } header .buttons i { height: 40px; width: 40px; display: inline-block; color: #fff; font-size: 1.2rem; line-height: 40px; text-align: center; background: #8A6CFF; border-radius: 4px; transition: 0.2s ease; } header .buttons i:first-child:hover { background: #704dff; } header .buttons i:last-child { margin-left: 10px; font-size: 1.25rem; background: #6C757D; } header .buttons i:last-child:hover { background: #5f666d; } .wrapper .preview-img { display: flex; justify-content: center; margin-top: 25px; } .preview-img .img { max-height: 65vh; } .preview-img img { width: 100%; height: 100%; object-fit: contain; } @media screen and (max-width: 688px) { .lightbox .wrapper { padding: 12px; max-width: calc(100% - 26px); } .wrapper .preview-img { margin-top: 15px; } header .buttons i:last-child { margin-left: 7px; } header .photographer span, .search p { font-size: 1.1rem; } .search h1 { font-size: 1.8rem; } .search .search-box { height: 50px; margin: 30px 0; } .gallery .images { max-width: 100%; padding: 0 13px; margin-top: 20px; } .images .details { bottom: 0px; } .gallery .load-more { padding: 10px 25px; font-size: 1.05rem; } }
Last, paste the following codes into your script.js file.In the code, you will notice a variable called apiKey. You need to get your own Pexels API key and insert it into this variable. You can get a free API key by visiting the official Pexels API documentation. Additionally, you will find a variable named perPage, which has a default value of 15. This means that every time the API is called, 15 new images will be fetched.
Plain text
Copy to clipboard
Open in new window
EnlighterJS 3 Syntax Highlighter
const imageWrapper = document.querySelector(".images");
const searchInput = document.querySelector(".search input");
const loadMoreBtn = document.querySelector(".gallery .load-more");
const lightbox = document.querySelector(".lightbox");
const downloadImgBtn = lightbox.querySelector(".uil-import");
const closeImgBtn = lightbox.querySelector(".close-icon");
// API key, paginations, searchTerm variables
const apiKey = "PASTE-YOUR-API-KEY";
const perPage = 15;
let currentPage = 1;
let searchTerm = null;
const downloadImg = (imgUrl) => {
// Converting received img to blob, creating its download link, & downloading it
fetch(imgUrl).then(res => res.blob()).then(blob => {
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = new Date().getTime();
a.click();
}).catch(() => alert("Failed to download image!"));
}
const showLightbox = (name, img) => {
// Showing lightbox and setting img source, name and button attribute
lightbox.querySelector("img").src = img;
lightbox.querySelector("span").innerText = name;
downloadImgBtn.setAttribute("data-img", img);
lightbox.classList.add("show");
document.body.style.overflow = "hidden";
}
const hideLightbox = () => {
// Hiding lightbox on close icon click
lightbox.classList.remove("show");
document.body.style.overflow = "auto";
}
const generateHTML = (images) => {
// Making li of all fetched images and adding them to the existing image wrapper
imageWrapper.innerHTML += images.map(img =>
`<li class="card">
<img onclick="showLightbox('${img.photographer}', '${img.src.large2x}')" src="${img.src.large2x}" alt="img">
<div class="details">
<div class="photographer">
<i class="uil uil-camera"></i>
<span>${img.photographer}</span>
</div>
<button onclick="downloadImg('${img.src.large2x}');">
<i class="uil uil-import"></i>
</button>
</div>
</li>`
).join("");
}
const getImages = (apiURL) => {
// Fetching images by API call with authorization header
searchInput.blur();
loadMoreBtn.innerText = "Loading...";
loadMoreBtn.classList.add("disabled");
fetch(apiURL, {
headers: { Authorization: apiKey }
}).then(res => res.json()).then(data => {
generateHTML(data.photos);
loadMoreBtn.innerText = "Load More";
loadMoreBtn.classList.remove("disabled");
}).catch(() => alert("Failed to load images!"));
}
const loadMoreImages = () => {
currentPage++; // Increment currentPage by 1
// If searchTerm has some value then call API with search term else call default API
let apiUrl = `https://api.pexels.com/v1/curated?page=${currentPage}&per_page=${perPage}`;
apiUrl = searchTerm ? `https://api.pexels.com/v1/search?query=${searchTerm}&page=${currentPage}&per_page=${perPage}` : apiUrl;
getImages(apiUrl);
}
const loadSearchImages = (e) => {
// If the search input is empty, set the search term to null and return from here
if (e.target.value === "") return searchTerm = null;
// If pressed key is Enter, update the current page, search term & call the getImages
if (e.key === "Enter") {
currentPage = 1;
searchTerm = e.target.value;
imageWrapper.innerHTML = "";
getImages(`https://api.pexels.com/v1/search?query=${searchTerm}&page=1&per_page=${perPage}`);
}
}
getImages(`https://api.pexels.com/v1/curated?page=${currentPage}&per_page=${perPage}`);
loadMoreBtn.addEventListener("click", loadMoreImages);
searchInput.addEventListener("keyup", loadSearchImages);
closeImgBtn.addEventListener("click", hideLightbox);
downloadImgBtn.addEventListener("click", (e) => downloadImg(e.target.dataset.img));
const imageWrapper = document.querySelector(".images"); const searchInput = document.querySelector(".search input"); const loadMoreBtn = document.querySelector(".gallery .load-more"); const lightbox = document.querySelector(".lightbox"); const downloadImgBtn = lightbox.querySelector(".uil-import"); const closeImgBtn = lightbox.querySelector(".close-icon"); // API key, paginations, searchTerm variables const apiKey = "PASTE-YOUR-API-KEY"; const perPage = 15; let currentPage = 1; let searchTerm = null; const downloadImg = (imgUrl) => { // Converting received img to blob, creating its download link, & downloading it fetch(imgUrl).then(res => res.blob()).then(blob => { const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = new Date().getTime(); a.click(); }).catch(() => alert("Failed to download image!")); } const showLightbox = (name, img) => { // Showing lightbox and setting img source, name and button attribute lightbox.querySelector("img").src = img; lightbox.querySelector("span").innerText = name; downloadImgBtn.setAttribute("data-img", img); lightbox.classList.add("show"); document.body.style.overflow = "hidden"; } const hideLightbox = () => { // Hiding lightbox on close icon click lightbox.classList.remove("show"); document.body.style.overflow = "auto"; } const generateHTML = (images) => { // Making li of all fetched images and adding them to the existing image wrapper imageWrapper.innerHTML += images.map(img => `<li class="card"> <img onclick="showLightbox('${img.photographer}', '${img.src.large2x}')" src="${img.src.large2x}" alt="img"> <div class="details"> <div class="photographer"> <i class="uil uil-camera"></i> <span>${img.photographer}</span> </div> <button onclick="downloadImg('${img.src.large2x}');"> <i class="uil uil-import"></i> </button> </div> </li>` ).join(""); } const getImages = (apiURL) => { // Fetching images by API call with authorization header searchInput.blur(); loadMoreBtn.innerText = "Loading..."; loadMoreBtn.classList.add("disabled"); fetch(apiURL, { headers: { Authorization: apiKey } }).then(res => res.json()).then(data => { generateHTML(data.photos); loadMoreBtn.innerText = "Load More"; loadMoreBtn.classList.remove("disabled"); }).catch(() => alert("Failed to load images!")); } const loadMoreImages = () => { currentPage++; // Increment currentPage by 1 // If searchTerm has some value then call API with search term else call default API let apiUrl = `https://api.pexels.com/v1/curated?page=${currentPage}&per_page=${perPage}`; apiUrl = searchTerm ? `https://api.pexels.com/v1/search?query=${searchTerm}&page=${currentPage}&per_page=${perPage}` : apiUrl; getImages(apiUrl); } const loadSearchImages = (e) => { // If the search input is empty, set the search term to null and return from here if (e.target.value === "") return searchTerm = null; // If pressed key is Enter, update the current page, search term & call the getImages if (e.key === "Enter") { currentPage = 1; searchTerm = e.target.value; imageWrapper.innerHTML = ""; getImages(`https://api.pexels.com/v1/search?query=${searchTerm}&page=1&per_page=${perPage}`); } } getImages(`https://api.pexels.com/v1/curated?page=${currentPage}&per_page=${perPage}`); loadMoreBtn.addEventListener("click", loadMoreImages); searchInput.addEventListener("keyup", loadSearchImages); closeImgBtn.addEventListener("click", hideLightbox); downloadImgBtn.addEventListener("click", (e) => downloadImg(e.target.dataset.img));
If you encounter any problems or your code is not working as expected, you can download the source code files for this image gallery for free. Click on the download button to get the zip file containing the project folder with source code files. Remember to paste your API key into the code.
Download files
Info
Home
Projects
Blogs
Videos
About us
Follow us for more!
© 2023 All Rights Reserved A Coding Boy

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Glassmorphism Login Form | CodingNepal</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="wrapper"> <form action="#"> <h2>Login</h2> <div class="input-field"> <input type="text" required> <label>Enter your email</label> </div> <div class="input-field"> <input type="password" required> <label>Enter your password</label> </div> <div class="forget"> <label for="remember"> <input type="checkbox" id="remember"> <p>Remember me</p> </label> <a href="#">Forgot password?</a> </div> <button type="submit">Log In</button> <div class="register"> <p>Don't have an account? <a href="#">Register</a></p> </div> </form> </div> </body> </html>

@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@200;300;400;500;600;700&display=swap"); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Open Sans", sans-serif; } body { display: flex; align-items: center; justify-content: center; min-height: 100vh; width: 100%; padding: 0 10px; } body::before { content: ""; position: absolute; width: 100%; height: 100%; background: url("https://www.codingnepalweb.com/demos/create-glassmorphism-login-form-html-css/hero-bg.jpg"), #000; background-position: center; background-size: cover; } .wrapper { width: 400px; border-radius: 8px; padding: 30px; text-align: center; border: 1px solid rgba(255, 255, 255, 0.5); backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px); } form { display: flex; flex-direction: column; } h2 { font-size: 2rem; margin-bottom: 20px; color: #fff; } .input-field { position: relative; border-bottom: 2px solid #ccc; margin: 15px 0; } .input-field label { position: absolute; top: 50%; left: 0; transform: translateY(-50%); color: #fff; font-size: 16px; pointer-events: none; transition: 0.15s ease; } .input-field input { width: 100%; height: 40px; background: transparent; border: none; outline: none; font-size: 16px; color: #fff; } .input-field input:focus~label, .input-field input:valid~label { font-size: 0.8rem; top: 10px; transform: translateY(-120%); } .forget { display: flex; align-items: center; justify-content: space-between; margin: 25px 0 35px 0; color: #fff; } #remember { accent-color: #fff; } .forget label { display: flex; align-items: center; } .forget label p { margin-left: 8px; } .wrapper a { color: #efefef; text-decoration: none; } .wrapper a:hover { text-decoration: underline; } button { background: #fff; color: #000; font-weight: 600; border: none; padding: 12px 20px; cursor: pointer; border-radius: 3px; font-size: 16px; border: 2px solid transparent; transition: 0.3s ease; } button:hover { color: #fff; border-color: #fff; background: rgba(255, 255, 255, 0.15); } .register { text-align: center; margin-top: 30px; color: #fff;}