Building an accessible weather forecast with HTML and CSS
This summer I spent some time visiting weather forecast websites. Many of them had a multi-day weather forecast, usually for the next seven days. Many of the seven-day weather forecasts were displayed with an accordion where each day had its own accordion tab you could open and close. A lot of them also had in common that the accordion was built with a lot of unnecessary HTML and JavaScript. But what scared me the most was that none of them were accessible and operable via keyboard.
So I thought about if it was possible to create a weather forecast with HTML and CSS only. To build the accordion tabs, I used the HTML tags <details> and <summary>.
HTML
To display the weekday, weather, temperature and wind force, I used <span> tags as child elements of the <summary> tag. To display the weather details for each weekday, I used further information inside the <details> tag. For the headline and a brief text, I used the <h2> and <p> tags.
Check out the complete HTML code below:
<h1>Accessible Weather Forecast</h1>
<div class="forecast">
<details>
<summary>
<span class="weekday">Mon</span>
<span class="weather" role="img" aria-label="Sun behind small cloud">🌤️</span>
<span class="temperature">24°/13°</span>
<span class="wind">17 km/h</span>
</summary>
<h2>The local weather for Monday</h2>
<p>The weather will be quite hot with temperatures reaching 24°C. During the evening and night time the temperatures will drop to 13°C.</p>
</details>
<details>
<summary>
<span class="weekday">Tue</span>
<span class="weather" role="img" aria-label="Cloud with rain">🌧️</span>
<span class="temperature">16°/15°</span>
<span class="wind">16 km/h</span>
</summary>
<h2>The local weather for Tuesday</h2>
<p>The weather will be comfortable with temperatures around 16°C. During the evening and night time the temperatures will drop to 15°C.</p>
</details>
<details>
<summary>
<span class="weekday">Wed</span>
<span class="weather" role="img" aria-label="Sun behind rain cloud">🌦️</span>
<span class="temperature">22°/15°</span>
<span class="wind">12 km/h</span>
</summary>
<h2>The local weather for Wednesday</h2>
<p>The weather will be quite hot with temperatures reaching 22°C. During the evening and night time the temperatures will drop to 15°C.</p>
</details>
<details>
<summary>
<span class="weekday">Thu</span>
<span class="weather" role="img" aria-label="Sun behind rain cloud">🌤️</span>
<span class="temperature">27°/15°</span>
<span class="wind">6 km/h</span>
</summary>
<h2>The local weather for Thursday</h2>
<p>The weather will be hot with temperatures reaching 27°C. During the evening and night time the temperatures will drop to 15°C.</p>
</details>
<details>
<summary>
<span class="weekday">Fri</span>
<span class="weather" role="img" aria-label="Cloud with rain">🌧️</span>
<span class="temperature">21°/15°</span>
<span class="wind">9 km/h</span>
</summary>
<h2>The local weather for Friday</h2>
<p>The weather will be quite hot with temperatures reaching 21°C. During the evening and night time the temperatures will drop to 15°C.</p>
</details>
<details>
<summary>
<span class="weekday">Sat</span>
<span class="weather" role="img" aria-label="Cloud with rain">⛈️</span>
<span class="temperature">20°/16°</span>
<span class="wind">15 km/h</span>
</summary>
<h2>The local weather for Saturday</h2>
<p>The weather will be quite hot with temperatures reaching 20°C. During the evening and night time the temperatures will drop to 16°C.</p>
</details>
<details>
<summary>
<span class="weekday">Sun</span>
<span class="weather" role="img" aria-label="Sun">☀️</span>
<span class="temperature">23°/15°</span>
<span class="wind">7 km/h</span>
</summary>
<h2>The local weather for Sunday</h2>
<p>The weather will be quite hot with temperatures reaching 23°C. During the evening and night time the temperatures will drop to 15°C.</p>
</details>
</div>
CSS
I tried to keep the CSS part as simple as possible. I set the <summary> tag to display: flex;, flex-direction: row;, align-items: center; and justify-content: center; to position the four <span> tags. And for the animated arrow at the end of the <summary> tag I used the ::after pseudo-element. The rest of the CSS is just basic styling.
Check out the complete CSS code below:
* {
box-sizing: border-box;
}
body {
background-color: #2b5876;
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, Adwaita Sans, Cantarell, Ubuntu, roboto, noto, helvetica, arial, sans-serif;
font-size: 100%;
}
h1 {
color: #fff;
font-size: 30px;
text-align: center;
}
h2 {
color: #062c45;
font-size: 18px;
margin: 0;
padding: 24px 24px 0 24px;
}
p {
color: #062c45;
font-size: 16px;
line-height: 1.5;
margin: 0;
padding: 12px 24px 24px 24px;
}
.forecast {
border-top: 1px solid #d3e3ec;
border-right: 1px solid #d3e3ec;
border-left: 1px solid #d3e3ec;
margin: 0 auto;
max-width: 640px;
}
.forecast details {
background-color: #fff;
font-size: 18px;
}
.forecast details[open] {
border-bottom: 1px solid #d3e3ec;
}
.forecast details[open] > summary:after {
transform: rotate(90deg);
}
.forecast summary {
align-items: center;
background-color: #f3f8fb;
border-bottom: 1px solid #d3e3ec;
color: #062C45;
display: flex;
flex-direction: row;
font-weight: bold;
height: 72px;
justify-content: space-between;
padding: 24px;
}
.forecast summary::after {
border-color: transparent transparent transparent #062c45;
border-style: solid;
border-width: 6px;
content: '';
transform: rotate(0);
transform-origin: .2rem 50%;
transition: .25s transform ease;
}
.weather,
.weekday {
width: 40px;
}
.weather {
font-size: 28px;
line-height: 1;
text-align: center;
}
.temperature,
.wind {
text-align: center;
width: 100px;
}
Result
Feel free to check out the complete accessible weather forecast below or on CodePen:
See the Pen Accessible Weather Forecast by Thorsten Beeck (@thorstenbeeck) on CodePen.