---
title: Writing Semantic Markup
teaser: Writing semantic markup for the web.
tags: design
author: Joshua Ogle
published_on: 2017-03-28
---

The history of front-end development
is not a short one
as computer history goes,
but it wasn't until recently
that it has started to get
the tools and attention it deserves.
Writing markup was mostly ignored
as being both cumbersome
and yet simplistic.
The practice of crafting "the view layer"
is more enjoyable and exciting now
than it ever has been
and it is giving us
better user experiences.

Traditionally, most layout in HTML
has been done with only a handful of tags:

* `<table>` :
  Misused for years
  to get around the shortcomings
  of CSS layouts,
  the backlash against them
  has led some designers
  to stop using them altogether.
  Tabular data belongs in tables.
  Don't be afraid to use them.

* `<div>` :
  This is the catch-all element
  and used as a default
  when other tags won't do.

* `<span>` :
  Similar to `div`,
  but this is an inline-level
  element useful for text.

As you can imagine,
these few elements
don't give us a lot
of differentiation
and don't reflect
the structure of the application
and the purpose of their parts.
They do get the job done,
but it could be better.

### HTML5 to the rescue

In 2014,
HTML5 brought us a cornucopia
of new tags
that help make it easier
to differentiate content
and to create meaningful relationships
between elements.

In all there are [25 new elements],
but these are the elements for layout
and will be the most common
that you will come across.

* `<main>` :
  Wraps around your main content.
  This tag often goes unused
  by designers,
  but is especially helpful
  for single-page applications
  that replace content.

* `<article>` :
  Specifies self-contained content,
  such as a blog articles.

* `<section>` :
  Pieces of content
  such as chapters,
  or even just areas of content
  that are broken up visually.

* `<header>` :
  Introductory content.
  Might be a masthead
  with a logo and navigational links
  or even used inside
  a small piece of content.

* `<footer>` :
  Contains information
  about the containing element,
  such as meta data for a blog post
  or as a site footer.

* `<nav>` :
  Contains navigational links.

* `<aside>` :
  Content related to the main content
  but in an area
  like a sidebar or suggested content.
  Side navigation should instead
  use the `nav` element.

* `<figure>` and `<figcaption>` :
  Contains media
  like illustrations and photos.
  The `figcaption` tag
  is nested inside `figure`
  to give additional information.

These tags are meant to be meaningful
but also flexible in their usage.
You may notice that the definitions
of these elements
are somewhat vague,
and that is intentional.
They don't have any inherent styles
of their own
and can be used in any combination
that makes sense to you.
These elements have great browser support,
but you may need a *[polyfill]*
to enable support in older browsers
(such as Internet Explorer 8 and below).

To get an idea of
how this looks in practice,
let's look at a few examples.

1. A blog article can use a header and footer
    to separate the title and meta information
    from the post itself.

```html
<main class="content">
  <article class="post">
    <header>
      <h2 class="title">Article Title</h2>
      <time datetime="2015-01-30 13:00">Jan 30th</time>
    </header>
    <section>
      <h3>Section Title</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
        eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
        enim ad minim veniam, quis nostrud exercitation ullamco laboris
        nisi ut aliquip ex ea commodo consequat.</p>
    </section>
    <section>
      <h3>Section Title</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
        eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
        enim ad minim veniam, quis nostrud exercitation ullamco laboris
        nisi ut aliquip ex ea commodo consequat.</p>
    </section>
    <footer>
      <span class="post-comments" data-show="#comments">24 comments</span>
    </footer>
  </article>
</main>
```

2. A header can provide clear navigation links
    in a nav tag.

```html
<header class="site-header">
  <a href="/" class="logo">Logo</a>
  <nav>
    <ul>
      <li>
        <a href="/register">Register</a>
      </li>
      <li>
        <a href="/login">Log In</a>
      </li>
    </ul>
  </nav>
</header>
```

3. These elements can be nested.
    this is especially helpful for `section` tags.

```html
<section>
  <h1>Pangolins</h1>

  <section>
    <h2>Habitat</h2>
    <p>Pangolins live in two regions: Southern Africa and South-East Asia</p>
  </section>

  <section>
    <h2>Diet</h2>
    <p>They are insectivorous, mainly eating ants and termites.</p>
  </section>

  <section>
    <h2>Conservation</h2>
    <p>Pangolins are endangered and protected under international laws.</p>
  </section>
</section>
```

4. Headers and footers can be used
   for global elements
   and also inside other elements.

```html
<header class="site-header">
  <a href="/" class="logo">Logo</a>
</header>
<main class="content">
  <article>
    <header>
      <h1>The Robot Uprising and You</h1>
    </header>
    <section>
      <p>
        ...
      </p>
    </section>
    <footer>
      Posted by Ralph Bot on August 29th
    </footer>
  </article>
</main>
<footer class="site-footer">
  &copy; 2015 Businesscorp
</footer>
```

![](https://images.thoughtbot.com/cp-design-for-the-web/HLyRTWdhTsaa2JtqtzHK_layout-html5.png)

### Inline and block-level elements

We should take a moment
to talk about [the difference]
between *block-level* and
*inline-level* elements.
Inline-level elements are used for text
and will not (by default) add a line break before and after.
These are tags like `<a>`, `<strong>`, and `<img>`.
Block-level elements are your more typical layout tags
like `<div>`, `<header>` and `<h1>`.
Each can be styled like the other
by using the `display` property in your styles.

```css
a {
  display: block;
}
```

There is also a hybrid between the two
called `inline-block`.
This will cause the element
to remain inline,
but accept things like top and bottom padding.
In some situations,
this is a simpler approach
than using floats
and can be very helpful
when aligning elements with text.

```css
img {
  display: inline-block;
  vertical-align: middle;
}
```

[25 new elements]: http://www.w3schools.com/html/html5_new_elements.asp
[polyfill]: https://github.com/aFarkas/html5shiv
[the difference]: https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
