DEV Community

Van_mai
Van_mai

Posted on

#Weather App with fantastic animations Tutorial for Beginners

Weather App Tutorial for Beginners

Hey everyone! Today, I will teach you how to create a weather app with some fantastic animations using JavaScript. Let’s dive in step by step!

Image description

Step 0: Setting Up the Weather API

This app will use the OpenWeatherMap API. So, make sure your API key is ready. You can visit the OpenWeatherMap website to get your free API key.

Step 1: Create the Weather App HTML

Here’s a simple structure for your weather app:

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link
        href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800;900&family=Roboto:wght@300;400;500;700;900&display=swap"
        rel="stylesheet">
    <link rel="stylesheet" href="weather-app.css">
    <title>Weather App</title>
</head>
<body>
</body>
<script src="https://kit.fontawesome.com/7c8801c017.js" crossorigin="anonymous"></script>
<script src="weather-app.js"></script>
</html>
Enter fullscreen mode Exit fullscreen mode

We create the following divs: .container, .search-box, .not-found, .weather-box, and .weather-details.

<div class="container">
    <div class="search-box">
        <i class="fa-solid fa-location-dot"></i>
        <input type="text" placeholder="Enter your location">
        <button class="fa-solid fa-magnifying-glass"></button>
    </div>

    <div class="not-found">
        <img src="images/404.png">
        <p>Oops! Invalid location</p>
    </div>

    <div class="weather-box">
        <img src="">
        <p class="temperature"></p>
        <p class="description"></p>
    </div>

    <div class="weather-details">
        <div class="humidity">
            <i class="fa-solid fa-water"></i>
            <div class="text">
                <span></span>
                <p>Humidity</p>
            </div>
        </div>

        <div class="wind">
            <i class="fa-solid fa-wind"></i>
            <div class="text">
                <span></span>
                <p>Wind Speed</p>
            </div>
        </div>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Image description

Step 2: Create the Weather App CSS

Here’s the basic CSS to get you started:

* {
    margin: 0;
    padding: 0;
    border: 0;
    outline: 0;
    box-sizing: border-box;
}

body {
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #06283D;
}

.container {
    position: relative;
    width: 400px;
    height: 105px;
    background: #fff;
    padding: 28px 32px;
    overflow: hidden;
    border-radius: 18px;
    font-family: Arial, sans-serif;
    transition: 0.6s ease-out;
}

.search-box {
    width: 100%;
    height: min-content;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.search-box input {
    color: #06283d;
    width: 80%;
    font-size: 25px;
    font-weight: 500;
    text-transform: uppercase;
    padding-left: 32px;
}

.search-box ::placeholder {
    font-size: 20px;
    font-weight: 500;
    color: #06283d;
    text-transform: capitalize;
}

.search-box button {
    cursor: pointer;
    width: 50px;
    height: 50px;
    color: #06283D;
    background: #dff6ff;
    border-radius: 50%;
    font-size: 25px;
    transition: 0.4s ease;
}

.search-box button:hover {
    color: #fff;
    background: #06283D;
}

.weather-box {
    text-align: center;
}

.weather-box img {
    width: 60%;
    margin-top: 30px;
}

.weather-box .temperature {
    font-size: 4rem;
    font-weight: 800;
    color: #06283D;
    position: relative;
    margin-top: 30px;
    margin-left: -16px;
}

.weather-box .temperature span {
    position: absolute;
    margin-left: 4px;
    font-size: 1.5rem;
}

.weather-box .description {
    font-size: 22px;
    font-weight: 500;
    color: #06283D;
    text-transform: capitalize;
}

.weather-details {
    width: 100%;
    display: flex;
    justify-content: space-between;
    margin-top: 30px;
}

.weather-details .humidity, .weather-details .wind {
    display: flex;
    align-items: center;
    width: 50%;
    height: 100px;
}

.weather-details .humidity {
    padding-right: 20px;
    justify-content: flex-start;
}

.weather-details .wind {
    padding-right: 20px;
    justify-content: flex-end;
}

.weather-details i {
    color: #06283D;
    font-size: 26px;
    margin-right: 10px;
    margin-top: 6px;
}

.weather-details span {
    font-size: 22px;
    font-weight: 500;
    color: #06283D;
}

.weather-details p {
    font-size: 14px;
    font-weight: 500;
    color: #06283D;
}

.not-found {
    width: 100%;
    text-align: center;
    margin-top: 50px;
    scale: 0;
    opacity: 0;
    display: none;
}

.not-found img {
    width: 70%;
}

.not-found p {
    color: #06283D;
    font-size: 22px;
    font-weight: 500;
    margin-top: 12px;
}
Enter fullscreen mode Exit fullscreen mode

Important:

To add animation, you can use the fadeIn animation to make the app more dynamic:

.weather-box, .weather-details {
    scale: 0;
    opacity: 0;
}

.fadeIn {
    animation: 0.5s fadeIn forwards;
    animation-delay: 0.5s;
}

@keyframes fadeIn {
    to {
        scale: 1;
        opacity: 1;
    }
}
Enter fullscreen mode Exit fullscreen mode

Image description

Step 3: Create the Weather App JavaScript

Now it’s time to bring the app to life with JavaScript. You’ll need to integrate with the OpenWeatherMap API. Below is the starting point for your JS:

const container = document.querySelector('.container');
const search = document.querySelector('.search-box button');
const weatherBox = document.querySelector('.weather-box');
const weatherDetails = document.querySelector('.weather-details');
const error404 = document.querySelector('.not-found');
Enter fullscreen mode Exit fullscreen mode

Next, you’ll need to set up the fetch API to get weather data:

search.addEventListener('click', () => {
    const key_API = `f62b1ae7f33dea18b1279c2e658a1d63`;
    const city = document.querySelector('.search-box input').value;

    if (city === ``) return;

    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${key_API}`)
        .then(response => response.json())
        .then(json => {
            if (json.cod === `404`) {
                container.style.height = `400px`;
                weatherBox.style.display = `none`;
                weatherDetails.style.display = `none`;
                error404.style.display = `block`;
                error404.classList.add(`fadeIn`);
                return;
            }

            const image = document.querySelector('.weather-box img');
            const temperature = document.querySelector('.weather-box .temperature');
            const description = document.querySelector('.weather-box .description');
            const humidity = document.querySelector('.weather-details .humidity span');
            const wind = document.querySelector('.weather-details .wind span');

            switch (json.weather[0].main) {
                case `Clear`:
                    image.src = `images/clear.png`;
                    break;
                case `Rain`:
                    image.src = `images/rain.png`;
                    break;
                case `Snow`:
                    image.src = `images/snow.png`;
                    break;
                case `Clouds`:
                    image.src = `images/cloud.png`;
                    break;
                case `Haze`:
                    image.src = `images/mist.png`;
                    break;
                default:
                    image.src = ``;
            }

            temperature.innerHTML = `${parseInt(json.main.temp)}&deg;C`;
            description.innerHTML = `${json.weather[0].main}`;
            humidity.innerHTML = `${json.main.humidity}%`;
            wind.innerHTML = `${json.wind.speed} Km/h`;

            weatherBox.style.display = ``;
            weatherDetails.style.display = ``;
            weatherBox.classList.add(`fadeIn`);
            weatherDetails.classList.add(`fadeIn`);
            container.style.height = `590px`;
        });
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

That’s it! You now have a fully functional weather app. Keep improving it by adding more features like more detailed forecasts, custom icons, or even a background image that changes based on the weather conditions.

If you found this tutorial helpful, feel free to connect with me for more web development tips and tricks.

Here are the full code.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link
        href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800;900&family=Roboto:wght@300;400;500;700;900&display=swap"
        rel="stylesheet">
    <link rel="stylesheet" href="weather-app.css">
    <title>Weather-App</title>

</head>
<body>

    <div class="container">
        <div class="search-box">
            <i class="fa-solid fa-location-dot"></i>
            <input type="text" placeholder="Enter your location">
            <button class="fa-solid fa-magnifying-glass"></button>             
        </div>
        <div class="not-found">
            <img src="images/404.png">
            <p>Oops! Invalid location</p>
        </div>

        <div class="weather-box">
            <img src="">
            <p class="temperature"></p>
            <p class="description"></p>
        </div>

        <div class="weather-details">
            <div class="humidity">
                <i class="fa-solid fa-water"></i>
                <div class="text">
                    <span></span>
                    <p>Humidity</p>
                </div>
            </div>

            <div class="wind">
                <i class="fa-solid fa-wind"></i>
                <div class="text">
                    <span></span>
                    <p>Wind Speed</p>
                </div>
            </div>



        </div>



    </div>





</body>

<script src="https://kit.fontawesome.com/7c8801c017.js" crossorigin="anonymous"></script>
<script src="weather-app.js"></script>
</html>

Enter fullscreen mode Exit fullscreen mode

CSS

*{
    margin: 0;
    padding: 0;
    border: 0;
    outline: 0;
    box-sizing: border-box;

}

body{
    height: 100vh;
    display: flex;
    align-items:center;
    justify-content:center;
    background: #06283D

}

.container{
    position: relative;
    width: 400px;
    height: 105px;
    background: #fff;
    padding: 28px 32px;
    overflow: hidden;
    border-radius: 18px;
    font-family: Arial, sans-serif;
    transition: 0.6s ease-out; 
}

.search-box{
    width: 100%;
    height: min-content;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.search-box input{
    color: #06283d;
    width: 80%;
    font-size: 25px;
    font-weight: 500;
    text-transform: uppercase;
    padding-left: 32px;

}

.search-box ::placeholder{
    font-size: 20px;
    font-weight: 500;
    color: #06283d;
    text-transform: capitalize;

}

.search-box button{
    cursor: pointer;
    width: 50px;
    height: 50px;
    color: #06283D;
    background: #dff6ff;
    border-radius: 50%;
    font-size: 25px;
    transition: 0.4s ease;

}

.search-box button:hover{
    color: #fff;
    background: #06283D;
}

.weather-box{
    text-align: center;
}

.weather-box img{
    width: 60%;
    margin-top: 30px;
}

.weather-box .temperature{
    font-size: 4rem;
    font-weight: 800;
    color: #06283D;
    position: relative;
    margin-top: 30px;
    margin-left: -16px;
}

.weather-box .temperature span{
    position: absolute;
    margin-left: 4px;
    font-size: 1.5rem;

}

.weather-box .description{
    font-size: 22px;
    font-weight: 500;
    color: #06283D;
    text-transform: capitalize;
}

.weather-details{
    width: 100%;
    display: flex;
    justify-content: space-between;
    margin-top: 30px;

}

.weather-details .humidity, .weather-details .wind{
    display: flex;
    align-items: center;
    width: 50%;
    height: 100px;
}

.weather-details .humidity{
    padding-right: 20px;
    justify-content: flex-start;
}

.weather-details .wind{
    padding-right: 20px;
    justify-content: flex-end;
}

.weather-details i{
    color: #06283D;
    font-size: 26px;
    margin-right: 10px;
    margin-top: 6px;

}

.weather-details span{
    font-size: 22px;
    font-weight: 500;
    color: #06283D;
}

.weather-details p{
    font-size: 14px;
    font-weight: 500;
    color: #06283D;
}


.not-found{
    width: 100%;
    text-align: center;
    margin-top: 50px;
    scale: 0;
    opacity: 0;
    display: none;
}

.not-found img{
    width: 70%;

}

.not-found p{
    color: #06283D;
    font-size: 22px;
    font-weight: 500;
    margin-top: 12px;

}

.weather-box, .weather-details{
    scale: 0;
    opacity: 0;
}

.fadeIn{
    animation: 0.5s fadeIn forwards;
    animation-delay: 0.5s;

}

@keyframes fadeIn{
    to {
        scale: 1;
        opacity: 1;
    }
}

Enter fullscreen mode Exit fullscreen mode

JS


const container = document.querySelector('.container');
const search = document.querySelector('.search-box button');
const weatherBox = document.querySelector('.weather-box');
const weatherDetails = document.querySelector('.weather-details');
const error404 = document.querySelector('.not-found');

search.addEventListener('click', () => {
    const key_API=`f62b1ae7f33dea18b1279c2e658a1d63`
    const city = document.querySelector('.search-box input').value;

    if (city === ``)
        return;

    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${key_API}`)
    .then(response => response.json()).then(json => {

        if (json.cod === `404`){
            container.style.height = `400px`;
            weatherBox.style.display = `none`;
            weatherDetails.style.display = `none`;
            error404.style.display = `block`;
            error404.classList.add(`fadeIn`);
            return;

        }

        error404.style.display = `none`;
        error404.classList.remove(`fadeIn`);

        const image = document.querySelector(`.weather-box img`);
        const temperature = document.querySelector(`.weather-box .temperature`);
        const description = document.querySelector(`.weather-box .description`);
        const humidity= document.querySelector(`.weather-details .humidity span`);
        const wind = document.querySelector(`.weather-details .wind span`);

        switch (json.weather[0].main){
            case `Clear`:
                image.src = `images/clear.png`;
                break;
            case `Rain`:
                image.src = `images/rain.png`;
                break;
            case `Snow`:
                image.src = `images/snow.png`;
                break;
            case `Clouds`:
                image.src = `images/cloud.png`;
                break;
            case `Haze`:
                image.src = `images/mist.png`;
                break;
            default:
                image.src = ``; 
        }

        temperature.innerHTML = `${parseInt(json.main.temp)}&deg;C`;
        description.innerHTML = `${json.weather[0].main}`;
        humidity.innerHTML = `${json.main.humidity}%`;
        wind.innerHTML = `${json.wind.speed}Km/h`;

        weatherBox.style.display = ``;
        weatherDetails.style.display = ``;
        weatherBox.classList.add(`fadeIn`);
        weatherDetails.classList.add(`fadeIn`);
        container.style.height = `590px`;

    })

})


Enter fullscreen mode Exit fullscreen mode

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more