This article provides a tour through the elements available in HTML to structure and group content, from old favourites like <div> to new HTML5 additions such as <article> and <aside>.
IntroductionNow we’ve gotten to grips with the basics of HTML, what is contained inside the document <head>
, and the different building blocks most commonly used to structure different items of content inside the <body>
, we can look at the overall structure of the HTML content, and what distinct sections the page contains.
Before you read any further, go and have a look at some of your favourite websites. They will have vastly differing content, functionality, and look and feel, but they will all have common structural elements. There are very few sites that don’t at least loosely follow this pattern:
Lets visualise this a bit more with a specific example. The website of the band “Conquest of Steel” looks like this:
Figure 1: A typical example website.
We could break this up into the sections we have just discussed:
Figure 2: the example site with distinct sections overlaid.
These sections could contain any number of different nested elements; for example, a footer could include a list full of links, a couple of paragraphs and an image. But how do we mark up these distinct sections, and group them together as single entities that can be laid out later using CSS? Let’s have a look.
Structuring a page with HTML 4HTML4 contains two generic container elements:
<div>
is a block container that you can use to group sections of block level content together.<span>
is an inline container that you can use to group pieces of inline content together.Note that <div>
and <span>
elements have no inherent content or dimensions, only that of their contents, until they are styled via CSS or manipulated by JavaScript. They also have no semantics, and the only way you can identify them is by giving them a class
or id
attribute.
You should only use these elements when there isn’t a more appropriate, semantic element to use for marking up content. Marking up paragraphs and headings with <div>
s is bad practice; although it might look okay at first, the page will be inaccessible to those using screen readers (screen readers need a good structure of headings to navigate by), and it will be more bloated, harder to read, and less efficient to style with CSS. Try to cut down on the number of <div>
s and <span>
s used when possible: an abuse of these elements leads to what is often called "div-itis".
So, to mark up the example site with HTML4, you could use the following elements:
Figure 3: The example site with appropriate HTML4 elements indicated for different major structural sections.
The markup would look something like this:
<body>
<div id="header">
</div>
<div id="nav">
</div>
<div id="sidebar1">
</div>
<div id="main">
</div>
<div id="sidebar2">
</div>
<div id="footer">
</div>
</body>
It’s that simple, really. Of course, it is not going to look like a properly laid out site until you apply CSS to the HTML, but it does give you the structural integrity you need to get the site laid out.
Enter HTML5 structural elementsThe HTML4 way of doing things is all well and good, but semantically it could be so much better.
Humans can tell the different content apart, but machines can’t — the browser doesn’t see the different divs as header, footer, etc. It sees them as different div
s. Wouldn’t it be more useful if browsers and screen readers were able to explicitly identify, say, the navigation menu so that a visually impaired user could find it more easily, or the different news items on a bunch of blogs so they could be easily syndicated in an RSS feed without any extra programming?
Even if you do use extra code to solve some of these problems, you can still only do it reliably for your websites, as different web developers will use different class and ID names, especially when you consider the international audience — different web developers in different countries will use different languages to write their class and id names.
It therefore makes a lot of sense to define a consistent set of elements for everyone to use for the common structural blocks that appear on so many websites, and that is exactly what is defined in HTML5.
The new HTML5 elements we will cover in this article are:
<header>
: Used to contain the header content of a site.<footer>
: Contains the footer content of a site.<nav>
: Contains the navigation menu, or other navigation functionality for the page.<article>
: Contains a standalone piece of content that would make sense if syndicated as an RSS item; for example, a news story.<section>
: Used to either group articles into different purposes or subjects, or to define the different sections of a single article.<aside>
: Defines a block of content that is related to the main content around it, but not central to the page flow.We will discuss these in a moment, but for now let’s look at how our example could look when structured using HTML5 elements:
Figure 4: The example site with appropriate HTML5 elements indicated for different major structural sections.
In code, that looks like this:
<body>
<header>
</header>
<nav>
</nav>
<section id="sidebar1">
</section>
<section id="main">
</section>
<aside>
</aside>
<footer>
</footer>
</body>
Let’s explore some of the HTML5 elements in more detail.
<section>The <section>
element is for containing distinct different areas of functionality or subjects, or for breaking up an article or story into different sections. So in this case:
It is a fairly generic element, but still has far more semantic meaning than the plain old <div>
.
<article>
is related to <section>
, but is distinctly different. Whereas <section>
is for grouping distinct sections of content or functionality, <article>
is for containing related individual standalone pieces of content, such as blog posts, videos, images, or news items. Think of it this way: if you have a number of items of content, each of which would be suitable for reading on their own, and would make sense to syndicate as separate items in an RSS feed, then <article>
is suitable for marking them up.
In our example, <section id="main">
contains blog entries. Each blog entry would be suitable for syndicating as an item in an RSS feed, and would make sense when read on its own, out of context; therefore <article>
is perfect for them:
<section id="main">
<article>
</article>
<article>
</article>
<article>
</article>
</section>
Simple, yes? Be aware, though, that you can also nest sections inside articles where it makes sense to do so. For example, if each one of the blog posts (articles) has a consistent structure made up of distinct sections, then you could put sections inside the articles as well. It could look something like this:
<article>
<section id="introduction">
</section>
<section id="content">
</section>
<section id="summary">
</section>
</article>
<header> and <footer>
As we mentioned above, the purpose of the <header>
and <footer>
elements is to wrap header and footer content, respectively. In our example the <header>
element contains a logo image, and the <footer>
element contains a copyright notice, but you could add more elaborate content. Also note that you can have more than one header and footer on each page; in addition to the top level header and footer, you could also have a <header>
and <footer>
element nested inside each <article>
, in which case they would just apply to that particular article. Adding to the above example:
<article>
<header>
</header>
<section id="introduction">
</section>
<section id="content">
</section>
<section id="summary">
</section>
<footer>
</footer>
</article>
<nav>
The <nav>
element is for marking up the navigation links or other constructs (e.g., a search form) that will take you to different pages of the site, or to different areas of the current page. (Other links, such as sponsored links, are not usually included here.) You can of course include headings and other structural elements inside the <nav>
, but it’s not compulsory.
You may have noticed that we used an <aside>
element to mark up the second sidebar, the one containing latest gigs and contact details. This is perfectly appropriate, as <aside>
is for marking up pieces of information that are related to the main flow, but don’t fit into it directly.
Other good choices for an <aside>
would be information about the author of the blog post(s), a band biography, or a band discography with links to their albums.
With all these great new elements to use on our pages, surely the days of the humble <div>
are numbered. But no! In fact, <div>
still has a perfectly valid use. You should use it when there is no other more suitable element available for grouping an area of content, which will often happen when you are grouping content together for styling/visual purposes. A common example is using a <div>
to wrap all of the content on the page, and then using CSS to centre all the content in the browser window, or to apply a specific background image to the content.
At this point we should discuss support. There is currently not full support for the HTML5 structural elements in today’s selection of web browsers, but it is getting better all the time. Support for these features across browsers may be less than ideal, but for our purposes it doesn’t matter very much. Here’s why.
The way the elements work in general between HTML4 and HTML5 is exactly the same — it is just the element names that are different. You can get HTML5 elements working across all browsers today with a minimum of effort.
First of all, if you put an HTML5 element into a web page that the browser doesn’t recognise, by default the browser will just treat it like a <span>
, i.e., just an anonymous inline element. But most of the HTML5 elements we have looked at in this article are supposed to behave like block elements; therefore, the easiest way to make them behave properly in older browsers is by setting them to display:block;
in your CSS. You can do this by including the following CSS rule at the top of your CSS, whether it is contained in the head of your HTML file or in an external CSS file:
article, section, aside, hgroup, nav, header, footer, figure, figcaption {
display: block;
}
This solves your HTML5 element problems for all browsers except one. Older versions of Internet Explorer refuse to allow styling of unknown elements, but this can be fixed by inserting a small section of JavaScript into the head of your document that declares each element:
<script>
document.createElement('article');
document.createElement('section');
document.createElement('aside');
document.createElement('hgroup');
document.createElement('nav');
document.createElement('header');
document.createElement('footer');
document.createElement('figure');
document.createElement('figcaption');
</script>
IE will now happily apply styles to those elements. It’s kind of a pain having to use JavaScript to make your CSS work, but hey, at least we have a way forward! There is also a problem with these styles STILL not being carried through to the printer when you try to print HTML5 documents from IE. However, the print problem can be solved using the HTML5 Shiv JavaScript library, which also handles adding the document.createElement
lines for you. You should wrap it up in conditional comments for IE versions lower than 9, so that modern browsers don’t execute JavaScript they don’t need to.
You may be wondering which style of structural elements to choose, now you’ve had a tour of the two options. We’d advise that you learn both, and use the HTML5 elements where you can, falling back to the HTML4 elements for projects where you are worried about the site’s audience having JavaScript support (remember that the HTML5 fix discussed above requires JavaScript to work), or where you can’t use HTML5 (e.g., because a client specifies HTML4, or because you are using some kind of content management system that won’t work with HTML5).
This way, you can work with whatever is thrown at you on different projects, plus your HTML5 sites will be nicely future-proofed for when browsers do all support HTML5 structural elements.
See also Exercise questionsRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4