Skip to main content

Command Palette

Search for a command to run...

Movie App using HTML, CSS, and Javascript

Published
4 min read
A

I am a frontend developer

Dear Reader,

Let’s do some good exercises by building a Trending Movies app using HTML, CSS, and Javascript. The movie’s data used in the project are fetched from themoviebd. org API.

Folder Structure of the project

  1. index.html — contains the HTML layout which defines the element structure that would be shown on the page.
  1. style.css- contains CSS code for styling. Using CSS we can style the different portions to make them more visually appealing.
  1. script.js — contains Javascript code to fetch the API data and to represent it on the browser

HTML Layout

Open VSCode and create the basic HTML structure in an index.html file by ! and then pressing the tab. Give the title as a movie app Link styles.css and script.js to the created HTML file. Inside the body, we will have a header tag that contains an h1 tag to display the title of the app and a from the tag that holds the search bar used for searching the movies. we have a div tag with the id content where our API-fetched data will be presented dynamically.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Movie App</title>
        <link rel="stylesheet" href="styles.css" />
        <script src="index.js" defer></script>
    </head>
    <body>
        <header>
            <form id="form">
                <input
                    type="text"
                    id="search"
                    placeholder="Search"
                    class="search"
                />
            </form>
        </header>
        <main id="main"></main>
    </body>
</html>

Javascript logic

Below functions are defined in the javascript code,

getMovies() — A function to fetch movies from API and returns the results using the fetch function. The results will be passed to the showMovies() function.

showMovies() — A function to showcase the results in the browser which inserts the HTML code dynamically. The data to this function is passed from the getMovies() function.

getClassByRate() — A function that returns the color based on the movie rating obtained from API. This color is used in CSS to choose the color of the movie rating text.

An EventListener for the search of movies. Once you enter the movie name in the search bar and by clicking on enter will submit the form and this event listener will be triggered. The movie matching the name entered in the search bar will be fetched from the API and it will automatically display all the related titles on the list.

const APIURL =
    "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=04c35731a5ee918f014970082a0088b1&page=1";
const IMGPATH = "https://image.tmdb.org/t/p/w1280";
const SEARCHAPI =
    "https://api.themoviedb.org/3/search/movie?&api_key=04c35731a5ee918f014970082a0088b1&query=";

const main = document.getElementById("main");
const form = document.getElementById("form");
const search = document.getElementById("search");

// initially get fav movies
getMovies(APIURL);

async function getMovies(url) {
    const resp = await fetch(url);
    const respData = await resp.json();

    console.log(respData);

    showMovies(respData.results);
}

function showMovies(movies) {
    // clear main
    main.innerHTML = "";

    movies.forEach((movie) => {
        const { poster_path, title, vote_average, overview } = movie;

        const movieEl = document.createElement("div");
        movieEl.classList.add("movie");

        movieEl.innerHTML = `
            <img
                src="${IMGPATH + poster_path}"
                alt="${title}"
            />
            <div class="movie-info">
                <h3>${title}</h3>
                <span class="${getClassByRate(
                    vote_average
                )}">${vote_average}</span>
            </div>
            <div class="overview">
                <h3>Overview:</h3>
                ${overview}
            </div>
        `;

        main.appendChild(movieEl);
    });
}

function getClassByRate(vote) {
    if (vote >= 8) {
        return "green";
    } else if (vote >= 5) {
        return "orange";
    } else {
        return "red";
    }
}

form.addEventListener("submit", (e) => {
    e.preventDefault();

    const searchTerm = search.value;

    if (searchTerm) {
        getMovies(SEARCHAPI + searchTerm);

        search.value = "";
    }
});

CSS Styling

I explained only the important parts here and the rest of the CSS code mostly deals with positioning, size, and color of the elements. I shared the GitHub link at the end of the post where you can see the complete code.

Here we are arranging the list of the movies obtained from the API using flex. The img tag which holds an image of the movie, the movie-info div class which holds information about the movie like movie name and rating, the div class overview which has an overview of the movie is inserted in the javascript code dynamically and not defined in the HTML file.

Just hovering on the movie banner should show the overview. For that, we are using transform translateY(0)

Here is the complete CSS code,

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;600&display=swap");

* {
    box-sizing: border-box;
}

body {
    background-color: #22254b;
    font-family: "Poppins", sans-serif;
    margin: 0;
}

header {
    background-color: #373b69;
    display: flex;
    justify-content: flex-end;
    padding: 1rem;
}

.search {
    background-color: transparent;
    border: 2px solid #22254b;
    border-radius: 50px;
    color: #fff;
    font-family: inherit;
    font-size: 1rem;
    padding: 0.5rem 1rem;
}

.search::placeholder {
    color: #7378c5;
}

.search:focus {
    background-color: #22254b;
    outline: none;
}

main {
    display: flex;
    flex-wrap: wrap;
}

.movie {
    background-color: #373b69;
    border-radius: 3px;
    box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);
    overflow: hidden;
    position: relative;
    margin: 1rem;
    width: 300px;
}

.movie img {
    width: 100%;
}

.movie-info {
    color: #eee;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 1rem 1rem;
    letter-spacing: 0.5px;
}

.movie-info h3 {
    margin: 0;
}

.movie-info span {
    background-color: #22254b;
    border-radius: 3px;
    font-weight: bold;
    padding: 0.25rem 0.5rem;
}
.movie-info span.green {
    color: rgb(39, 189, 39);
}

.movie-info span.orange {
    color: orange;
}

.movie-info span.red {
    color: rgb(189, 42, 42);
}

.overview {
    background-color: #fff;
    padding: 2rem;
    position: absolute;
    max-height: 100%;
    overflow: auto;
    left: 0;
    bottom: 0;
    right: 0;
    transform: translateY(101%);
    transition: transform 0.3s ease-in;
}

.overview h3 {
    margin-top: 0;
}

.movie:hover .overview {
    transform: translateY(0);
}