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!
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>
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>
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;
}
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;
}
}
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');
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)}°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`;
});
});
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>
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;
}
}
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)}°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`;
})
})
Top comments (0)