Generic containers - the div and span elements

From W3C Wiki
Revision as of 22:30, 21 July 2011 by Plehegar (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Introduction

In this Web Standards Curriculum article, I am going to explain to you how and when to use the two elements in HTML that are not used to describe the content. The span and div elements do not actually confer any meaning to the content they envelop; instead, they are a generic mechanism that allows you to create custom structure or groupings of elements where no other HTML element is really appropriate, and that can be then styled with CSS or manipulated via JavaScript. Although divs don’t add any semantic meaning, they could be considered to represent a structural division of the mark-up, along with the appropriate semantic class or ID name.

They are the “tag of the last resort” and should only be used where no other HTML element fits the bill, because they have no meaning to assistive techologies, search engines, etc.

Semantically neutral

Most elements in HTML exist to describe the content, such as images, lists, headings, or assist in setting up the document—head, body, link, meta, etc. There are two elements however that have no assigned meaning. From the HTML spec:

The div and span elements, in conjunction with the id and class attributes, offer a generic mechanism for adding structure to documents.

These two elements can be considered the scaffolding of HTML. They give you the ability to group content, add extra information around content and hooks for adding styling and interactivity. They do not however add any new semantic meaning to the document, in and of themselves.

Inline versus block

As you learned earlier, block elements are elements that help inform the structure of a document. The div element, short for division, is the block level generic container. It is normally used to wrap around other block level elements, to group them together (see the next section for more of an exploration of this). It can also be used to collect together a bunch of inline elements and/or text that otherwise don’t logically fit under another block level element, but this should be a last resort.

The span element is the inline level generic container. It also helps to inform the structure of document, but it is used to group or wrap other inline elements and/or text, rather than block level elements.

The line between the two different types might seem fairly arbitrary at first. The difference to bear in mind is the type of content, and how it would appear when written down without any styling. A div is placed around a group of block level elements—for example, to wrap a heading plus a list of links to make a navigation menu. A span wraps a group of inline elements or (most usually) plain text. The key word is “group”: if a div wraps just one block-level element, or a span just one inline element, it's being used unnecessarily. For example, check out the way the div and span elements are used in the following simple markup:

<body>
  <div id="mainContent">
    <h1>Title of the page</h1>
    <p>This is the first paragraph of content on my example page.</p>
    <img src="example.gif" alt="This image is merely an example, nothing special">
    <p>This is the second paragraph of content on my example page. It is very
    similar to the first, but there is a <span id="specialAlert">special alert here
    that we want to colour and increase text size using CSS</span>.
    It's not really standard emphasis - it's more just styling, so <em> and <strong> are not really appropriate.</p>
  </div>
</body>

You could now select the content inside the div and span using their id attributes, and apply special styling and positioning to them using CSS.

More exploration of grouping content

Viewing the source of many pages on the internet will reveal a nest of div elements including common metaphors in the classes and/or ids of the elements—for example header, footer, content, sidebar, and so on.

Your class and id names should always be semantic, meaning they should refer to the meaning/role of the content, rather than just referring to its visual appearence. So for example, sidebar and alertMessage are good class names, whereas redLefthandColumn and blueFlashingText are not. What if you wanted to change the colour of the sidebar from red to blue at a later date, or switch its position on the site from left to right? What if you wanted your alerts to be changed from blue and flashing to green and not flashing?

These divisions provide predictability when creating page structures, and, perhaps most importantly, when looking at the HTML again later, they provide clues as to which part of the page you are in. A well divided page is almost self documenting as to its intent and contents.

To hopefully make this a little bit clearer, let’s look at a div structure from a real site—the home page of dev.opera.com to be exact. Bear in mind that the below code example contains no content at all, apart from a few other elements I’ve included because they are important for the site structure. I’m mainly looking at reproducing just the actual site structure as defined using div elements. In the code below, read the HTML comments carefully—I’ve inserted these to explain the site structure. As you look through the code, open the main page of dev.opera.com inside a new tab or window in your browser so you can refer to the look of the site as you explore its structure.

<body>
<!-- First up we have a wrap div, which wraps the entire page, and allows more precise control of it as a whole -->
  <div id="wrap">
  <!-- This unordered list contains the list of links to all Opera's different sites, which you can see across the very top of the page -->
    <ul id="sitenav" class="hidemobile">
      ...
    </ul>
      ...
    <!-- This is the search form - the search box you see at the top right of the page -->
    <form action="/search/" method="get" id="search">
      <div>
        ...
      </div>
    </form>
    <!-- This unordered list contains the main navigation menu of the site - the horizontal tab menu you see just below the main title graphic -->
    <ul id="menu">
      ...
    </ul>
    <!-- This nested div forms the structure of the login box, where you enter your user name and password to log in to the site. You will only see this if you are currently logged out. -->
    <div id="loginbox">
      <div id="login">
        ...
      </div>
    </div>
    <!-- This series of nested divs is where the main content of the page is contained - all of the article summaries that form the main bulk of the page content -->
    <div id="content2">
      <div id="main">  
        ...
        <div class="major">
          ...
        </div>
        <div class="major">
          ...
        </div>
        ...
      </div>
    </div>
    <!-- This div contains the sidebar of the page - the article categories, the latest comments, etc -->
    <div id="side">
      ...
    </div>
    <!-- This div contains the page footer, which is where you'll see the copyright message, and various links at the bottom of the page. -->
    <div id="footer">
      ...
    </div>
  <!-- The end of the page - this is the closing tag for the wrap div -->  
  </div>
</body>

Extra information

Some content has extra information that is of use to user agents and other parsers, and this needs to be conveyed through an attribute. span elements are often a good way to attach such information to content on a web page, as you will see below.

A good example is a different language appearing within a document. For example:

<code><p><q>Plus ça change, plus c'est la même chose</q> she said.</p></code>

Although the language of the main document is English, the quote is actually French. This would be indicated through the use of the lang attribute, like so:

<code><p><q lang='fr'>Plus ça change, plus c'est la même chose</q> she said.</p></code>

Now, in that example, it was easy to mark the change in language as it all appeared within a quote, so the q element was perfect to use to wrap the content. There are some cases however where there isn’t an appropriate semantic element easily available, so you would instead have to resort to a span or div. For example:

<code><p>A screen reader will read the French word chat (cat) as chat (to talk informally) unless it is properly marked up.</p></code>

In this example, the first instance of the word chat, being an example of French within an English document, should have the difference indicated so it isn’t just interpreted as the English word chat. In this case, a span around the word chat is the right way to go about it, as there is no other HTML element appropriate to wrap the French word (we do not want to emphasise the word, it is not a quote, or a piece of code, etc). And being a single word in a sentence, it is inline level. The example would therefore be better written as:

<code><p>A screen reader will read the French word <span lang='fr'>chat</span> (cat) as chat (to talk informally) unless it is properly marked up.</p></code>

This is the same technique used in microformats for marking up common data formats within web pages. You can find a lot more about microformats in some of the more advanced HTML articles on dev.opera.com.

Hooks for JavaScript, as well as CSS

I’ve already talked about how you can use div and span along with id and class attributes to provide hooks with which to apply CSS styles and positioning to certain parts of your content. The same thing can be done to apply JavaScript to your document too.

If a given element needs to be found and manipulated by JavaScript, it is common to apply an id to it, and then use the getElementById function to find it. You’ll learn a lot more about JavaScript in the last part of the course.

“div-itis”

One thing to be aware of is an effect commonly referred to as “div-itis” in the web development community.

Whilst it is easy to add styling via a lot of nested div or span elements, it is a temptation best avoided as much as possible. In most cases, it is possible to attach the styling or JavaScript functionality to existing elements in the document. A generic container should be a last resort—it is better to try to write web pages by starting with just the semantic elements, and adding the containers only when necessary.

Inappropriate semantics

In this section I explore some common mistakes to be aware of when marking up content using HTML, to be avoided if at all possible.

Generic “paragraphs”

Sometimes, it is tempting to throw a p (paragraph) element around any block of text, but this isn’t really correct. As stated in my earlier article on marking up content:

If it is just a few words and not even a proper sentence, then it should probably not be marked up as a paragraph.

A div or span (depending on the exact situation) is the correct element to wrap around disjointed textual content that has no other semantic relationship covered by other HTML elements.

Presentational elements

One notably bad piece of advice sometimes found on the internet is the practice of using short, presentational elements such as b or i as generic containers in place of span. The reasoning provided is commonly one of two things:

  • The elements are three bytes shorter, and so save bandwidth in both the HTML and the CSS.
  • The styling required is for appearance only, so using “presentational” elements is actually ok in this circumstance.

The first one is true, but the saving is almost always negligible (unless you are doing an incredible amount of presentational effects), especially given modern compression applied by web servers to documents before sending them over the internet to the browser. This makes documents much shorter than any human short-hand can achieve.

The second reason betrays a lack of comprehension as to what presentational actually means in the context of HTML. Presentational elements describe what their content should look like (b means simply “text within is bold”). They do not represent generic hooks for styling what is within.

If a small section of text within a paragraph needs styling or targeting by JavaScript and there is not already an applicable semantic element to wrap around it, the only correct element to use is a span.

Summary

This draws my exploration of the span and div elements to a close—you should now understand their purpose much better, and be able to use them with confidence. Later articles on CSS will go much more deeply into using them to create page layouts, and other uses.

Exercise questions

  • What is the difference between div and span?
  • Name 2 main uses of these elements on web pages.
  • Have a look at the source code of one of the pages of your favourite web site. Consider the structure of it. Does it use a lot of div and span elements? Can you see anything bad or inappropriate about the way they are used? How could it be improved?

Note: This material was originally published as part of the Opera Web Standards Curriculum, available as 22: Generic containers—the div and span elements, written by Mark Norman Francis. Like the original, it is published under the Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.