Building a Weather App using JavaScript & CSS

I have been tinkering with CSS for over a decade on various client projects. While I learned and applied a lot from CSS3, including following the Responsive Web Design principles, using the Bootstrap framework, and utilizing CSS Grid and Flexbox in my work, I wanted to go beyond stylistic changes. I wanted to create a useable product from scratch that would pull in real data and display it beautifully. As part of my Human Computer Interaction (HCI) Master’s program at the University of Maryland, I decided to execute that vision through building a working weather app prototype using JavaScript.

terpweather: A weather app built by UMD students #goterps

In this case study, I’ll be providing context and my work with the data as well as sharing my design decisions and outputs.


Objective

Develop a MVP weather application that will allow users to track weather information for the upcoming five days for cities in the United States using zip codes entered by a user.

Technologies & Resources Used

Data Affordances & Constraints

Affordances

The API provided by OpenWeatherMap offers several powerful data points as part of their free API that provides forecast data for every three hours for five days (which comes to 8 times a day for a total 40 sets of data), including:

  • Temperature: Average, Maximum, and Minimum
  • Geolocation: Latitude and Longitude
  • Humidity, Rain & Snow Volume, and Cloudiness
  • Wind Speed, Sea Level, and Pressure
  • Weather Description and Corresponding Icons

Constraints

With that said, I had to work with the following constraints with the API:

OpenWeatherMap’s default icons
  1. The icons that came with the service were quite dated and rudimentary looking. In contrast to the high-quality information coming from the API, the icons did not seem to do it justice.
  2. The data in this specific API does not include information for the current time, but rather for time in future 3-hour intervals. For example, it could be 8pm, but the API is only showing data coming in at 9pm, 12am, 3am, and so on.
  3. The times only came in Universal Time Coordinated (UTC) time, which is four hours ahead of the Eastern Standard Time (EST) time zone that would be applicable to students in Maryland.
  4. The data does not include aggregate weather data for a full day. For example, the data will say that at 12pm on Monday, the temperature maximum is 68º and the temperature minimum is 62º. But there isn’t one place where the data shows that for the entire day of Monday, the temperature will be between 58º to 73º.
  5. The naming convention for weather ID’s to align with descriptions (e.g. “clear sky”) mainly followed one format, but there were exceptions. Essentially, every ID followed the X00 format (e.g. “700”) except for clouds, which followed the 80X format (e.g. “802”).

I dealt with these constraints in the following way:

  • In regards to the icons, I originally thought of creating my own array of icons to use, but then decided to first check if anybody else had already done the same. I fortunately was able to find a set of icons designed by Erik Flowers that had file names corresponding to the weather description IDs from the OWM API. This was a good reminder that I don’t have to needlessly reinvent the wheel and can leverage online free resources.
  • As for time-related constraints, I quickly found that vanilla JavaScript wasn’t quite adept at manipulating the time strings I was receiving. After several lines of code to do something simple, like changing the time to EST and displaying it in a 12-hr format, I found out much of this could be achieved by a few lines of code using Moment.JS, a library specifically to ‘parse, validate, manipulate, and display dates and times in JavaScript.’ This considerably sped up my development and allowed me to quickly add in functions to manipulate the time strings.
  • Lastly, to display aggregate weather data and different CSS classes based on the weather description, I used nested for-loops where it ran through the 40 sets of data five times to pull weather data per date into an array, after which another function determined the highest, lowest, or most frequent element depending on the objective I was trying to achieve. I similarly used another function to set a unique CSS class for each one of the seven main weather types identified.
My main part of the functional code

Integrity & Expandability

When you start going through the designs, you may wonder why I went through the pains of manipulating the data to show the time for EST — especially because there aren’t any specific times displayed in the final version — or why I didn’t just show the weather data for a specific point in time for every day (e.g., 12pm) instead of aggregating each date’s data. In fact, I came across other folks that posted they did the latter as their solution for creating similar weather prototypes in their own journey of development. The answer for me had to do with the following reasons:

  • Integrity: In case I ever did release my app to be used by others, it’s important they’re working off of accurate data. If my data didn’t show rain when it could have — and someone was soaked as a result of my decision — that’s on me.
  • Functional expandability: As you’ll see below, even though the design was kept simple at the end, the design allows for additional information to be shown upon clicking on a day. Even though the site currently does not drill down to 3-hr intervals, the code has been built with a framework that will allow for that functionality to be added at a future time.

I stand by these two reasons in all the work I do, and I believe this is what defines a professional creator: integrity and preparing for the future through creating products that are expandable.

Design

The original vision that I had designed onto a low-fidelity wireframe was to keep the app as a connected panel of weather patterns. The idea was that this would be provide the user with a quick view of what to expect for the current week in a minimalistic manner that would emphasize the current day.

Low-Fidelity Wireframe

Upon interacting with the data, I saw that there was potential for more data points to be returned, so I created a view to accommodate data for multiple intervals throughout the day. Based on the data output, I made some other changes, including only showing the average temperature because the max. and min. temperature didn’t change much — if at all — in the span of three hours. Also, for the sake of some brevity, I only included the icons without a description.

First draft of prototype

This new design meant that there was a good amount of scrolling involved, but the prototype now had data that allowed the user to know what to expect for every three hours. I was thrilled.

I conducted user testing following the creation of this first draft and received the following suggestions for improvement:

“I like the detail, but there’s just too much going on. I want this information synthesized for me.”
“It’s hard to focus on information for a specific day due to the monochromatic look.”
“Is there any other information you can include? I know my weather app includes other info like humidity for the day.”
“I think it would be good to include the descriptions of the icons for accessibility and clarity purposes. It’s hard to tell what some of the icons exactly mean.

I went back to the drawing board. Referencing my original wireframes, I incorporated the feedback received into a better design that not only had a more modern interface, but most importantly, it addressed what my users had asked for.

View Interactive Demo: arifkabir.com/weather

I went for a clean, sleek design that incorporated colors that were vivid but not overly bright. I was initially torn when deciding whether to make the colors based on the temperature or based on the type of weather. After experimenting with both, I then decided to focus more so on the colors being conceptual visual differentiators to show the variety in weather during the week. The colors do lean towards the type of weather — particularly as the weather goes from cloudy to stormy —and evoke some of the scenery or emotions felt during the respective type of weather, but this was intentionally kept more abstract so that the users would also read the information after gaining an initial understanding of the app through the colors.

My design decisions for each weather element

I received further feedback (more positive this time around!) and continued iterating on the design, this time focusing on making the site mobile-friendly and in adding hover states for several of the elements.

Next Steps

The site also works on your mobile phones!

I recognize this is only the MVP state of an application that can be further developed. I would like to take this app to the next level with the following:

  • Offer functionality to show data in more regular intervals during a day when a user clicks to find out more details on a day.
  • Incorporate Geolocation capabilities so that the user will not need to input any text.
  • Look into providing a custom look and feel for specific regions or timezones.
  • Customize the colors further, both in terms of the background to improve readability and in terms of the text to differentiate between the information provided.
  • Add icons for humidity and wind speed. For wind speed, have the icons reflect the degree of the wind for the day.
  • Add designs that signify the time of day. Further clarify the weather icons by having them dynamically move.

Reflections

I learned a great deal about JavaScript and its associated libraries through getting my feet wet with this project. I was pleasantly surprised to see how naturally JavaScript flowed from CSS, and how I am finally able to put into practice more design elements that are based on dynamic interactions instead of static behavior. I was also glad to see my UX and CSS expertise being helpful in taking the code from text being served to a thoughtful and aesthetically-pleasing user experience. I am now looking forward to refining this site and building more apps in the future.

If you have any tips and suggestions for me to grow on my learning journey, I’d love to hear from you! You can contact me here.