Skip to the content

HTML div and span tags, and when to use header, nav, main and footer

Last updated: By Lukas BrandtLesson 12 of 215 min read

Project 1 styled a row of buttons, one element at a time. Project 2 builds something you will reuse on almost every site: the header band at the top of the page, with a site name on one side and a menu of links on the other. Before any CSS goes on it, you need boxes to put the styles on. HTML gives you two generic boxes, <div> and <span>, plus a set of elements that do the same job while also saying what they hold.

Two boxes that mean nothing

A <div> is a block-level container. It starts on a new line and stretches across the width of its parent, the way a paragraph does. A <span> is an inline container. It sits inside a line of text and is only as wide as its content. You saw block and inline behavior in the display lesson; div and span are the plainest examples of each.

Neither one carries any meaning. With no styles, a div shows nothing but its content, and a screen reader passes over it without comment. Their job is to give you something to select with a class.

<div class="spec-box">
  <p>Socket: <span class="value">LGA 775</span></p>
  <p>Front side bus: <span class="value">1333 MT/s</span></p>
  <p>Cache: <span class="value">6 MB</span></p>
</div>
.spec-box {
  max-width: 320px;
  padding: 12px 16px;
  border: 1px solid #c9ced6;
  border-radius: 6px;
}

.spec-box p {
  margin: 4px 0;
}

.value {
  font-family: ui-monospace, monospace;
  font-weight: 700;
}

The div groups three paragraphs so one border goes around all of them. The spans pick out the values inside each line without breaking the line. Swap a span for a div and two things happen: the value drops onto its own line, and the browser quietly closes the paragraph early, because a div is not allowed inside a <p>. That second effect is a good reason to learn which elements are block-level before you nest them.

Elements that say what they hold

HTML5 added elements that behave much like a div (block-level, almost no default styling) but tell the browser and assistive software what kind of content is inside:

  • <header>: introductory content for the page, usually the site name or logo and often the main menu. An article can have its own <header> too.
  • <nav>: a block of major navigation links, such as the main menu or a table of contents. A row of three links in a paragraph does not need one.
  • <main>: the main content of the page, the part that changes from page to page. Use one visible <main> per page.
  • <footer>: closing content, such as a copyright line, a contact link or secondary links.
  • <section>, <article> and <aside>: a themed group with its own heading, a self-contained piece that would make sense on its own, and side content related to the page.

Why bother, if they look the same as divs? Screen readers turn the page-level <header>, <nav>, <main> and <footer> into landmarks, and users can jump straight to the menu or the content with a single key instead of listening to everything in order. (A header or footer placed inside an article or section describes that piece, not the whole page, so it is not a page landmark.) The markup also becomes easier to read for you, six months from now.

Here is the markup Project 2 will style. Every element in it has a reason to be there:

<header class="site-header">
  <a class="logo" href="index.html">Bench Notes</a>
  <nav class="main-nav" aria-label="Main">
    <ul class="menu">
      <li><a href="index.html" aria-current="page">Home</a></li>
      <li><a href="guides.html">Guides</a></li>
      <li><a href="tools.html">Tools</a></li>
      <li><a href="contact.html">Contact</a></li>
    </ul>
  </nav>
</header>
<main>
  <h1>Welcome to the bench</h1>
  <p>Notes on old hardware, kept in one place.</p>
</main>

The <header> holds the site name and the menu. The <nav> marks the menu as navigation, and its aria-label gives the landmark a name, which helps once a page has more than one nav. The links sit in a <ul> because a menu is a list of choices, and screen readers announce how many items it has. On a full site, a <footer> would follow <main>.

When a plain div is still right

Semantic elements are not a ban on divs. Reach for a div when the box exists only for layout or styling and has no meaning of its own:

  1. A wrapper that limits the width of the content and centers it, such as <div class="wrap"> inside the header.
  2. A group of elements that a flex or grid layout should move as one unit, like a logo image and a tagline that always sit together.
  3. A styled box such as the spec box above. It has no heading and is not a separate piece of content, so <section> or <aside> would claim more than is true.

The same thinking applies to span. If the words are stressed, <em> or <strong> says so. If they are code, use <code>; if they are a date, <time>. A span is the right pick when you only want a different look, like the bold values in the spec box.

A simple rule of thumb: pick the element that describes the content. If nothing fits, use a div or a span, and do not feel bad about it. Wrapping everything in <section> just to avoid divs adds landmarks nobody asked for.

Parts links can earn us a commission. As an Amazon Associate I earn from qualifying purchases.

Try it

Paste the Project 2 markup into the online HTML editor and add a <style> element above it with one rule, * { outline: 1px solid red; }. Every box on the page gets a red outline, so you can see that the header, nav and list are each separate boxes, while the links are inline boxes sitting inside the list items. Delete the rule when you are done; lesson 16 starts styling this exact markup, and the CSS tutorial index lists everything in between.