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.