Design Weather App Interface using HTML and CSS (Source Code)

Faraz

By Faraz -

Design a responsive weather app interface with HTML/CSS. Our tutorial covers everything from setup to styling - create your UI today!


Design Weather App Interface using HTML and CSS.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. Preview
  5. Conclusion

Weather apps have become an integral part of our daily lives, providing us with real-time forecasts and weather-related information at our fingertips. The seamless and visually pleasing user interface (UI) of these apps plays a significant role in enhancing the user experience.

In this comprehensive guide, we will take you through the process of creating a weather app UI layout using HTML and CSS. Whether you're a seasoned web developer or just starting, this tutorial will provide you with step-by-step instructions to design an engaging weather app interface from scratch.

By the end of this guide, you'll have gained valuable insights into UI design principles, HTML structure, CSS styling, and responsive design techniques. So, let's dive into the world of weather app UI development and create a layout that not only provides accurate weather information but also looks visually appealing on various devices.

Credit: Ryan Mulligan

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our weather app layout.

After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.

Let's break down the different parts of the code:

1. <!DOCTYPE html>: This declaration defines the document type and version of HTML being used, which in this case is HTML5.

2. <html lang="en">: The opening tag for the HTML document, with the "lang" attribute indicating that the content is in English.

3. <head>: This section contains metadata and settings for the web page that are not directly visible to the user.

  • <title>: Sets the title of the web page, which typically appears in the browser's title bar or tab.
  • <meta charset="UTF-8">: Specifies the character encoding for the document (UTF-8, which supports a wide range of characters).
  • <meta name="viewport" content="width=device-width">: Defines the viewport settings for responsive design on different devices.
  • <link rel="stylesheet" href="styles.css">: Links an external stylesheet (styles.css) to the HTML document for styling purposes.

4. <body>: This section contains the visible content of the web page.

5. <section class="viewport">: A section that contains the main content of the page. The class "viewport" might be used for styling or JavaScript interactions.

6. <div class="warning">: A warning message to be shown if the browser does not support scroll-driven animations.

7. <header class="flex-stack">: The header section contains the main title and weather information.

  • <h1 id="location">: The main title of the weather app, "Fresh Coast," and a span containing a summary of temperature and weather conditions.
  • <p class="flex-stack">: A paragraph containing the current temperature and weather conditions.
  • <ul id="range">: An unordered list containing the high and low temperatures for the day.

8. <main>: The main content area of the web page.

  • <article>: A section containing information about severe weather alerts.
  • <article>: A section containing an hourly forecast with a list of forecast tiles.
  • <article>: A section containing a 10-day forecast with a list of forecast rows.
  • <article>: A section containing air quality information.
  • Other <article> elements represent various weather-related information tiles.

9. <footer>: The footer of the web page contains information about the weather data and map data.

10. Closing tags: The closing tags (</body>, </html>) complete the HTML document structure.

This is the basic structure of our weather app using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the weather app interface is in place, the next step is to add styling to the weather app interface using CSS. CSS allows us to control the visual appearance of the website, including things like layout, color, and typography.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our interface.

Let's break down the code section by section to understand its functionality:

1. Color Scheme and Variables: This section defines CSS custom properties (variables) and sets up color scheme options for the webpage. The :root selector is used to define these variables. There are two color schemes: light and dark, which will be used based on the user's preferred color scheme. Other variables like dimensions, colors, and spacings are defined here.

2. Media Query for Dark Color Scheme: This section uses a media query to switch to the dark color scheme when the user prefers the dark color scheme. It overrides the variables defined in the :root section with new values suited for a dark theme.

3. Base Styles: This section sets up fundamental styles for various HTML elements using the @layer base rule. It includes styles to normalize box-sizing, reset margins for certain elements, and set default fonts. Additionally, it applies styling to lists, headings, paragraphs, and images.

4. Layout Styles: The @layer layout rule defines layout-related styles. It defines styles for creating clusters of elements (cluster class), a flexible stacked layout (flex-stack class), horizontal scrolling elements (x-scroll class), and spacing between stacked elements.

5. Utility Classes: The @layer utilities rule defines utility classes. In this case, it defines a class called .small-caps that applies small-caps font variant to text.

6. Body and Viewport Styles: The body selector sets general styles for the entire page. It applies a grid layout, centers content, and sets the background color, and text color.

The .viewport class is used to style a scrolling area. It ensures that the viewport has vertical scrolling and horizontal overflow is hidden. Padding is added to the sides to prevent content from touching the edges.

7. Media Query for Larger Screens: This media query applies styles when the screen width is at least 600px. It adjusts the styles for the .viewport class to limit its width and height, adds a border, and adjusts the border radius.

8. Header Styles: Styles for the header element are defined. It is centered, positioned relative to the viewport offset, and has a subtle gradient background.

9. Location Styles: Styles for the #location element are defined. It creates a gradient background effect that fades into the page content.

10. Summary Styles: Styles for the #summary element are defined. It is positioned below the header and initially invisible (opacity: 0).

11. Temperature and Main Content Styles: Styles for the temperature display and main content area are defined. The main content is organized in a grid layout with flexible columns. For smaller screens, the main content switches to a single-column layout using a media query.

12. Article Styles: Styles for article elements are defined. They have rounded corners and a light background.

13. Forecast Tile Styles: Styles for forecast tiles are defined. They are centered and use a grid layout for alignment.

14. Footer Styles: Styles for the footer element are defined. It is centered and positioned at the bottom of the page.

15. Scroll-Driven Animations: This section defines scroll-driven animations using CSS custom properties. It includes animations for fading in/out and translating elements on scroll. The animations are controlled based on scroll position using animation-timeline, animation-range, and keyframes.

16. Unsupported Browser Warning: A warning message is provided for browsers that do not support scroll-driven animations. It is styled with a background color and margin to catch the user's attention.

This will give our weather app interface an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

@layer base, layout, utilities;

:root {
  color-scheme: light dark;
  --vp-width: 390px;
  --vp-height: 844px;
  --vp-gutter: 1rem;
  --radius: 1rem;
  --offset: 5rem;

  --bg: hsl(0 0% 100%);
  --surface: hsl(0 0% 92%);
  --surface-2: hsl(0 0% 84%);
  --text: hsl(0 0% 0%);
  --border: hsl(0 0% 0%);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: hsl(245 10% 6%);
    --surface: hsl(245 10% 10%);
    --surface-2: hsl(245 10% 16%);
    --text: hsl(0 0% 90%);
    --border: hsl(0 0% 15%);
  }
}

@layer base {
  * {
    box-sizing: border-box;
  }

  html,
  body {
    height: 100%;
  }

  body {
    margin: 0;
    font-family: system-ui;
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  p,
  figure,
  blockquote {
    margin: 0;
  }

  [role="list"] {
    padding: 0;
    margin: 0;
    list-style: none;
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  p {
    font-weight: normal;
  }

  img {
    max-width: 100%;
  }

  a {
    color: currentcolor;
  }
}

@layer layout {
  .cluster {
    gap: var(--gap, 1rem);
    align-items: var(--align, center);
    justify-content: var(--justify, flex-start);
    flex-wrap: wrap;
    display: flex;
  }

  .flex-stack {
    display: flex;
    flex-direction: column;
  }

  :is(.stack, .flex-stack) > * + * {
    margin-top: var(--space, 0.5rem);
  }

  .x-scroll {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--gap, 1.5rem);
    max-width: 100%;
    overflow-x: scroll;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
  }
}

@layer utilities {
  .small-caps {
    font-variant-caps: small-caps;
  }
}

body {
  display: grid;
  place-items: center;
  overflow: hidden;
  color: var(--text);
  background-color: var(--bg);
}

.viewport {
  overflow-x: hidden;
  overflow-y: auto;
  height: 100%;
  padding-inline: 1rem;
}

@media (min-width: 600px) {
  .viewport {
    width: min(var(--vp-width), 100% - 2rem);
    height: min(80vh, var(--vp-height));
    border-radius: var(--radius);
    border: 3px solid var(--border);
  }
}

header {
  position: relative;
  margin-block: var(--offset);
  text-align: center;
  z-index: 1;
}

#location {
  position: relative;
}

#location::before {
  content: "";
  position: absolute;
  top: calc(var(--vp-gutter) * -1);
  left: 0;
  width: 100%;
  height: calc(var(--offset) + var(--vp-gutter));
  background: linear-gradient(to bottom, var(--bg) 35%, transparent);
  z-index: -1;
}

#summary {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-inline: auto;
  font-size: 1rem;
  opacity: 0;
}

.current-temp {
  font-size: 5rem;
  font-weight: 300;
  align-self: center;
  display: inline-block;
  position: relative;
}

.current-temp::after {
  content: "°";
  position: absolute;
  top: 0;
  left: 100%;
}

main {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: calc(var(--vp-gutter) * -2);
  position: relative;
  z-index: 0;
}

@media (max-width: 320px) {
  main {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
}

/* Trick to hide article on scroll but not article h2 */
main::before {
  content: "";
  position: sticky;
  top: 0;
  z-index: 1;
  grid-column: 1 / -1;
  display: block;
  width: 100%;
  height: calc(var(--vp-gutter) * 2);
  background-color: var(--bg);
}

main > *:not(.tile) {
  grid-column: 1 / -1;
}

.tile {
  width: 100%;
  aspect-ratio: 1;
}

article {
  position: relative;
  border-radius: var(--radius);
  background-color: var(--surface);
}

article > * {
  padding-inline: 1rem;
}

article > h2 {
  position: sticky;
  top: var(--vp-gutter);
  z-index: 1;
  font-size: 1rem;
  font-variant-caps: all-small-caps;
  padding-block: 0.5rem 0.7rem;
  background-color: inherit;
  border-radius: inherit;
}

article > :last-child:not(h2) {
  padding-block-end: 1rem;
}

.forecast-tile {
  display: grid;
  gap: 0.2rem;
  text-align: center;
  font-feature-settings: "tnum";
}

.forecast-row {
  display: grid;
  gap: 1rem;
  align-items: center;
  grid-template-columns: 2.5rem auto 1fr;
  font-feature-settings: "tnum";
}

.range {
  display: grid;
  gap: 0.5rem;
  align-items: inherit;
  grid-template-columns: auto 1fr auto;
}

.meter {
  width: 100%;
  height: 0.4rem;
  background-color: var(--bg);
  border: 1px solid var(--surface-2);
  border-radius: 360px;
}

footer {
  text-align: center;
  margin-block-end: 3rem;
}

footer h2 {
  font-size: 1rem;
  font-weight: bold;
}

/* --------------------------------
✨ Scroll-driven animations
--------------------------------- */

/* Warning for unsupported browsers */
.warning {
  color: black;
  background: papayawhip;
  margin-inline: -1rem;
  padding: 1rem;
}

@supports (animation-timeline: scroll()) {
  .warning {
    display: none;
  }

  header {
    position: sticky;
    top: var(--offset);
  }

  main {
    margin-top: calc((var(--offset) * -1) - var(--vp-gutter));
  }

  main::before {
    top: var(--vp-gutter);
    height: var(--offset);
  }

  article > h2 {
    top: var(--offset);
  }

  header,
  #temperature,
  #condition,
  #range,
  #summary {
    animation: linear var(--animation-name) both;
    animation-timeline: scroll();
    animation-range: entry var(--range-start) entry var(--range-end);
  }

  header {
    --animation-name: title;
    --range-start: 0;
    --range-end: 16rem;
  }

  #range {
    --animation-name: fade-out;
    --range-start: 3rem;
    --range-end: 5rem;
  }

  #condition {
    --animation-name: fade-out;
    --range-start: 5rem;
    --range-end: 8rem;
  }

  #temperature {
    --animation-name: fade-out;
    --range-start: 8rem;
    --range-end: 11rem;
  }

  #summary {
    --animation-name: fade-in;
    --range-start: 11rem;
    --range-end: 16rem;
  }
}

@keyframes fade-out {
  to {
    opacity: 0;
  }
}

@keyframes fade-in {
  to {
    opacity: 1;
  }
}

@keyframes title {
  to {
    translate: 0 calc((var(--offset) * -1) + var(--vp-gutter));
  }
} 

Final Output:

Design Weather App Interface using HTML and CSS.gif

Conclusion:

In conclusion, this guide has taken you through the essential steps of creating a dynamic weather app UI layout using HTML and CSS. By following these steps, you've gained valuable insights into the world of user interface design and development. From the initial setup of your project to the meticulous crafting of UI components, you've learned how to seamlessly integrate structure and style to create a visually appealing and functional weather app interface.

Remember, designing a successful UI is not just about aesthetics; it's about understanding user behavior and creating an intuitive experience. The principles you've learned here can be applied to various design projects beyond weather apps, empowering you to build interfaces that resonate with users and leave a positive impact.

As you continue your journey in UI design, keep exploring new design trends, experimenting with different techniques, and refining your skills. The digital landscape is ever-evolving, and your ability to adapt and innovate will be key to creating UIs that stand out in a competitive environment. So, go forth with confidence, armed with the knowledge you've gained, and continue shaping the digital world with your creative and user-centric designs.

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post