How to Build a Weather App with HTML, CSS, and Vanilla JavaScript

Learn how to use an API to Fetch Data

Esther Vaati
Stackademic
Published in
6 min readFeb 26, 2024

--

The best way to learn JavaScript or any other programming language is by doing. In this tutorial, we will create a fully functioning weather app and it will look like this:

HTML Structure

When building any project, it’s essential to have the design of how you want it to look. The HTML structure will look like this

 <body>
<div class="container">
<div class="date">

<p>Wednesday, 21st Feb 2024</p>
</div>
<div class="location">
<input type="text" placeholder="Enter city" />
<button class="fa-solid fa-magnifying-glass"></button>
</div>

<section class="weather hidden">
<img src="" alt="" />
<span class="cityName">Rome</span>
<span class="description">clear clouds</span>
<span class="temp">23°C</span>

</section>

<section class="weather-details hidden">
<div class="wind">
<p>Wind</p>
<i class="fa-solid fa-wind"></i>
<p class="speed">6.17</p>
</div>
<div class="humidity">
<p>Humidity</p>
<i class="fa-solid fa-droplet"></i>
<p id="humidity">40</p>
</div>
<div class="feeling">
<p>Feels</p>
<i class="fa-solid fa-temperature-three-quarters"></i>
<p id="feeeling">30°C</p>
</div>
</div>
</section>

We will replace the data dynamically with Javascript.

Styling with CSS

And here are the CSS styles:

  @import url("https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap");

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

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

.container {
position: relative;
width: 450px;
height: 750px;
background: #f0f0f0;
padding: 18px 12px;
overflow: hidden;
border-radius: 18px;
font-family: "Roboto", sans-serif;
transition: 0.6s ease-out;
border-radius: 30px;
}

.date {
padding: 20px 32px;
text-align: center;
}
.location {
padding: 20px 32px;

display: flex;
align-items: center;
justify-content: space-around;
}

.location input {
/* color: #e26010; */
width: 80%;
background-color: #f0f0f0;
font-size: 20px;
font-weight: 500;
margin-left: 22px;
}
.location button {
cursor: pointer;
width: 40px;
height: 40px;
color: #e35519;
background: #e8dad1;
border-radius: 50%;
font-size: 22px;
transition: 0.4s ease;
}
.weather {
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 20px;
}
.weather img {
width: 50%;
}
.weather span{
font-size: 24px;
font-weight: 500;
}

.weather-details {
background: #fff;
border-radius: 40px;
padding: 20px 32px;
display: flex;
align-items: center;
justify-content: space-around;
}
.wind,
.humidity,
.feeeling {
padding: 10px 22px;
}

.weather-details .wind p,
.weather-details .humidity p,
.weather-details .feeling p {
margin: 8px 0;
}

.humidity i {
color: rgb(73, 73, 220);
}
#feeeling i {
color: orange;
}

.hidden {
visibility: hidden;
}

Things to Note

The section with the class weather will display the general weather, like the city name, weather description, and current temperature.

The weather-details section will display the rest of the weather details. Both sections have the class hidden and will be hidden by default.

.hidden {
visibility: hidden;
}

Once we get the Weather from the open weather API, we will use JavaScript to change the visibility of the sections.

Open Weather API

The Open Weather API is an organization that allows developers to get real-time data about the weather all over the world. To get the weather data, we need an API key. An API KEY is a secret key allowing us to authenticate ourselves when we request the data. Head to the Open weather API page and sign up for free to obtain your API Key.

There are multiple ways to get the weather data; you can use latitude and longitudes. However, the open weather provides a simple request that uses the city name as a parameter.

https://api.openweathermap.org/data/2.5/weather?q={city}&appid={APIKEY}

The only thing required of you is to replace city with the city you want the weather for and APIKEY with your APIKEY. For exmplee, the endpoint for getting the weather in rome will look like this:

https://api.openweathermap.org/data/2.5/weather?q=rome&appid=04419024fb0f20edd3f1abd06e46dd6d

If you paste this link on your browser, you will get this data

From this data, we are in a position to extract the weather information

JavaScript Functionality

Next, make a GET request to this endpoint using the fetch method to get the weather for the city provided by the user. In your JavaScript file, create a variable called currentDate and use the new Date constructor to get the current Date.

const currentDate = new Date();

Display the current date at the top of the page.

const currentDate = document.querySelector(".date p");
currentDate.textContent = date
.toString()
.split(" ")
.slice(0, 4)
.join(" ");

Next, select all the DOM elements that will be updated dynamically with JavaScript.

const currentDate = document.querySelector(".date p");
const searchButton = document.querySelector(".location button");
const weatherDetails = document.querySelector(".weather-details");
const weather = document.querySelector(".weather");
const image = document.querySelector(".weather img");

Add an event listener to the search button. This event listener will listen for a click event.

searchButton.addEventListener("click", function () {
}

Inside the function, we want to get the city name value from the input, perform a request using the fetch method, and print the data to the console.

const BASE_URL = ` https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${APIKEY}`;
console.log(BASE_URL);
fetch(BASE_URL)
.then((resp) => resp.json())
.then((data) => {
console.log(data);
});

Logging the data is also essential to ensure the fetch request performs as expected.

As you can see, the request was successful. Next, we will create an if statement that will extract data from the weather if cod ===200, 200 means a successful response, we will then display the appropriate weather icon.

The data will be contained in the first Array of the weather key

data.weather[0].main
data.weather[0].icon
data.weather[0].description
searchButton.addEventListener("click", function () {
const city = document.querySelector(".location input").value;
const APIKEY = "04419024fb0f20edd3f1abd06e46dd6d";
const BASE_URL = ` https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${APIKEY}`;

fetch(BASE_URL)
.then((resp) => resp.json())
.then((data) => {
if (data.cod === 200) {

const iconUrl = `http://openweathermap.org/img/wn/${data.weather[0].icon}.png`;
image.src =iconUrl;

const description = document.querySelector(".description");
const temp = document.querySelector(".temp");
const cityName = document.querySelector(".cityName");



cityName.textContent = data.name;
description.textContent = data.weather[0].description;
const roundedCelsius = Math.round(data.main.temp / 18.14);
temp.textContent = `${roundedCelsius}°C `;


weather.style.visibility = "visible";

}
});
});

Let’s Summarise the code above.

The open weather API data comes with an icon code for each weather, which looks like this:

"weather": [
{
"id": 500,
"main":"Rain",
"description": "light rain",
"icon": "10n"
}
],

We have extracted the icon from the data and used it to construct the URL for the weather icon image.

Outside of the if statement, we are updating the city name, weather description, and the current temperature. Finally, we are setting the visibility of the element with the class weather to be visible. Now, if you search any city, you will get the following information.

The final step is to display

  • Wind
  • Pressure
  • Feels like

Get the DOM elements:

const windSpeed = document.querySelector(".speed");
const humidity = document.getElementById("humidity");
const feeeling = document.getElementById("feeeling");

Update the text content and change the visibility of the weather details element.

 windSpeed.textContent = `{data.wind.speed}m/s`;
humidity.textContent = `${data.main["humidity"]}%`;
feeeling.textContent = `${Math.round(data.main["feels_like"]/18.14)} °C`;
weatherDetails.style.visibility = "visible";
weather.style.visibility = "visible";

Conclusion

Here is the Codepen. You can fork it and update the features of the weather app.

Subscribe to my Practical JavaScript Substack and master JavaScript by building projects, along with other talented developers who read it weekly.

Stackademic 🎓

Thank you for reading until the end. Before you go:

--

--