Exercise: From Div Soup to Semantic HTML

Rewrite the Maple Street Library's div-soup news page with header, nav, main, article, section, aside and footer, without changing a word, and watch its ready-made stylesheet and its checks reward every region you mark up.

Apprentice · HTML · Updated

The Maple Street Library's news page was built years ago, entirely from <div> elements. It has everything a visitor needs: the library's name, a menu, three news stories, the opening hours, upcoming events and the address. But a screen reader finds no landmarks and no headings on it, and the library's new stylesheet can't find anything to style. Your job is to rewrite the page with elements that say what each part is, without changing a single word, and let the checks tell you when every part is right.

This is the kind of job web developers really get: an old page that works, but that nobody can find their way around except by looking at it.

Get the exercise code

In the Exercise box beside the lesson, choose Get the starter on GitHub to open its GitHub repository. Click Code, then Download ZIP, and unzip it into the folder where you keep this course's projects.

The folder holds:

  • index.html: the library's news page, built from <div> elements. This is the file you rewrite.
  • style.css: the ready-made stylesheet. It styles elements by what they are (header, nav, article and so on), so it has almost nothing to style yet. You don't need to change it.
  • page.test.js and package.json: the checks. You don't need to change these.
  • README.md: the same steps as this lesson.

Open the folder in VS Code, right-click index.html and choose Open with Live Server. The page is one plain column, with no colors and no menu bar. Keep it open: it changes as you work.

What to do

Every part of the page is a <div> named with an id or a class, such as the top of the page:

<div id="header">
  <div class="site-name">Maple Street Library</div>
  <p>Books, classes and a makerspace, free with your library card.</p>
</div>

Replace each one with the element that says what it is, one region at a time:

  1. The top of the page becomes the page's <header>, and the library's name inside it the page's one <h1>.
  2. The menu becomes a <nav>.
  3. The main content becomes the page's one <main>.
  4. The news group becomes a <section> with an <h2>, and each news story an <article>, with its headline as an <h3>.
  5. The opening hours become a <section> with an <h2>.
  6. The upcoming events become an <aside> with an <h2>.
  7. The bottom of the page becomes the page's <footer>.

Two rules while you work:

  • Keep every word. Change the elements around the words, never the words.
  • Keep every id. The menu links jump to #news, #hours, #events and #visit. When you replace an element that has an id, give the new element the same id, or its menu link stops working.

Check your work

Open VS Code's terminal (Terminal > New Terminal). The first time only, install the checks' helpers:

npm install

Then run the checks, as often as you like:

npm test

At the start, 3 checks pass and 7 fail. That's expected. The 3 that pass check what the page already does right: all its words are there, its menu links go somewhere, and the validator finds no errors. They make sure your changes don't break any of that. Each region you mark up turns more checks green. A failing check's message says what it looked for, for example The events are related to the news but not part of it: put them in an <aside>.

Hints

  • Change both tags of a pair. When <div id="main"> becomes <main>, its closing </div> becomes </main>. Click on a tag in VS Code and it highlights its partner, so you can find the right closing tag.
  • Save and look after each region. The stylesheet styles elements by what they are, so the page picks up its menu bar, its story cards and its two columns as you go.
  • Is it a story, a group or an extra? Run the four questions from Article, Section and Aside on each part of the main content.
  • Headings, not boxes. A <div class="headline"> looks like a heading only because of CSS. A screen reader lists the real headings, <h1> to <h6>, and reads everything else as plain text.
  • A header inside a story is the story's. The page's own <header> and <footer> sit outside <main>, as in Header, Nav, Main and Footer.
  • If the validator check fails, read the line number in its message. It's usually a closing tag that didn't change along with its opening tag.

When you're done

Every check is green. Each line also ends with how long the test took, which is different on every computer:

✔ 1) words: every word of the page is still there
✔ 2) links: every menu link still has somewhere to go
✔ 3) h1: one, the library's name, in the page's header
✔ 4) nav: the menu links are in a nav
✔ 5) main: exactly one, holding the news
✔ 6) header and footer: the page's own, outside main
✔ 7) articles: each news story is an article with its own heading, inside main
✔ 8) aside: the upcoming events are in an aside
✔ 9) no div soup: no div is named after a region any more
✔ 10) validator: no errors
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0

In the browser, the page now has a colored header, a menu bar, the news stories as cards and the events in a column beside them. You didn't change a single line of CSS: the stylesheet was waiting for elements with a meaning.

Now look back at your page: is there a <div> left anywhere? If there is, ask the question from Div and Span: Boxes with No Meaning: is there an element that says what this is?

So what

Turning div soup into semantic HTML is a real task on real teams, and it pays off three ways at once: screen-reader users get landmarks and headings, search engines can tell the news from the menu, and the CSS gets simpler. You can do it to any page now.

Key terms

Related