• Writing Semantic HTML

    Feb 22 2006

    Semantic HTML means using HTML tags for their implied meaning, rather than just using (meaningless) div and span tags for absolutely everything. Why would you want to do this? Depending on the tag, the content in the tag can be interpreted in a certain way. Here are some examples.

    Header tags

    If you use <h1> instead of <div class="header">, and <h2> instead of <div class="subheader">, et cetera, Google and other search engines will interpret your headers as being important titles in your page. This way, when people search on the words in your headers and sub-headers, your page will be considered more relevant (and rank higher). Plus, it's much shorter and cleaner.

    This works both ways: don't use header tags for anything except headers, especially not increasing your font size or outlining your search engine keywords. This way, your page can be parsed for structure (you can do this with the W3C HTML Validator). This structure can then be used by screen readers or other tools to build a table of contents for your page.

    Form labels

    The <label> tag is so sadly forgotten. It's not immediately clear what the point of using it is, so very few web pages take advantage of it. The label tag is used to identify a label for an input field, for example "E-mail Address". It can either be used be wrapping it around the text and input field like: <label>First Name: <input name="fname"/></label>, or it can be used with the for attribute like so: <label for="fname">First Name:</label> <input id="fname" name="fname"/>.

    Why use the label tag instead of <div class="label">? Well, it's shorter and cleaner. But it also let's screen readers and other tools identify the text associated with an input field. Without using the label tag, it can be very difficult for some people to know what is supposed to go into your form fields.


    These days, everyone's moving away from using tables. This is great because tables aren't intended for structuring the way your web page looks. But tables still have a very important purpose. Any time you need to display data that would go in a spreadsheet, tables are here to help.

    When using tables, there are a number of tags and attributes that aren't widely used, but are very important for accessibility. Use the summary attribute to give a longer summary of the data in the table. Use the <caption> tag to give a brief title to the data. Use <th> tags to identify the column and row headers in your table. Then, you may want to use the headers attribute on the <td> tags to identify which headers apply to that cell. For more examples and details on accessibility with tables, see the W3C's Accessibility Guidelines.


    Lists are the new tables. Whereas tables are intended for grids of data, lists are intended for lists of content. This is great for us, because most web pages are essentially lists of different things. For example, look at this site. On the front page, I have a list of blog entries in the centre. On the sides, I have lists of links (archive, categories, et cetera), and the sides themselves are lists of lists. If I had used tables, I would've been saying "this stuff on the left has something to do with the stuff in the middle", but it doesn't, really. By using lists, I'm simply saying "this stuff is a list of items that have something to do with each other", which they do.

    You have three types of lists to choose from, but choose wisely. There are Ordered Lists (<ol>), Unordered Lists (<ul>), and Definition Lists (<dl>). Only use Ordered Lists when the entries have some kind of order. Only use Definition Lists for definitions (eg. for a glossary). Use Definition Lists any time you need name/value pairs, or when you need to break your list up into sections. The rest of the time, Unordered Lists are a safe bet.

    Lists not only give structure to your page, they're incredible handy for styling. You can just put an id or class on the outer tag (eg. <ul>), then style both the outer tag, and the inner <li> tags.


    Try to use the full variety of HTML tags whenever possible. Sometimes you'll be stuck with using <div> tags, but try to limit them to whenever you can't find a suitable HTML equivalent. At the same time, try to avoid using HTML tags for anything except their intended purpose. By doing this, your HTML will be cleaner, and its structure will be more readable and understandable -- not just to people but to screen readers, search engines, and other programs and tools.

  • Comments

    1. Jero at 8:06pm on February 24, 2006

    I obviously agree with you here, but your article does have some errors. For instance, you keep saying "div tags" or "li tags". These things are called <em>elements</em>, not tags. A tag is &lt;tag&gt;, however, an element is &lt;tag&gt;content&lt;/tag&gt; (hopefully this is formatted correctly). And according to the HTML 4.01, one should use the term element to refer to one.

    Another thing I noticed was the fact that you used the argument "it's much shorter and cleaner" multiple times. I could use a P element and put a bunch of link in there instead of a UL element. That's shorter, but it isn't better. Therefore the argument isn't valid.

    And one final thing: you said that the DL element should only used for definitions. Guess what, it doesn't: http://jero.net/blog/2005/08/the-wonder-called-the-dl-element/

    Now don't get me wrong. The more people support semantical markup, the better, so don't think I placed this comment just to hate on you. It's a fact that using semantical markup isn't easy, so you can easily make a mistake. So keep up the good work!

    2. Jero at 8:08pm on February 24, 2006

    Okay, it appears my explaination of the difference between tags and element didn't quite show up as I hoped it would, but I guess you get the point. >_>

    3. Jesse Skinner at 5:21am on February 25, 2006

    You're absolutely right that the technically correct term is "element". I'm writing about authoring HTML, though. And when you come to the part of the document where you need a label, then the thing you're going to type is a label tag: <label>. And where there's a tag, there's an element. Besides, if I talked about "alt tags" I'd be even further from the truth, but everyone would know what I'm talking about.

    With "shorter and cleaner" I was simply pointing out a benefit to using semantic tags instead of classes when possible. I wouldn't suggest everyone use text files for their web pages, even though they're the shortest and cleanest.

    You're right about definition lists being for more than definitions. I updated the article on this point.

    I also added a warning, to prevent people from mucking up their comments with HTML enitities. Sorry about that.

    4. Natalie at 7:42am on March 3, 2006

    Jesse, I really like this article. I won't nit-pick it at all. Tags or elements, it doesn't really matter unless you're actually writing a manual on the subject. A good writer makes good use of the language his readers use. I'm sure your readers know what you mean without you talking over their heads. Some of us happen to know the technical terms for something, but sometimes it's better to generalize for those who are beginning. I had a really difficult time when I was first learning CSS.

    I'm glad you said what you did about tables too. Far too many people still see tables as an adequate layout tool. I heard someone say awhile back that using tables in that way was actually just another "hack" that popped up in the 90s to help people arrange their stuff - and before CSS that was fine. It's good for people to know there's a better way.

    BTW: I marked this in ma.gnolia. ;)

    5. thewebguy at 8:29pm on March 16, 2006

    good call on the label tags. there is also the added functionality of ease of clicking, i.e. on something like this for a radio button

    (  ) item

    you can click the word 'item' as well as the button itself. i really hate getting real specific about my cursor when i am on my laptop so subtle things like that are nice.

    6. Dwight Spencer at 4:05pm on February 2, 2007

    Semantic HTML is another one of those many spurious coding fads that will move on in a few years. Here's a simple observation to show how flimsy the "intentional semantics" argument towards using Semantic HTML is: suppose the inventor of HTML - actually SGML - a European researcher back in the '80's whose name I've long forgotten - had just conceptualized the <table> tag ... but instead of leaving it that way, he realized that this tag was really meant (i.e. semantic meaning) structurally to be more general, and ended up instead calling it the <columnarDAG> tag. If he had done that, semantic HTML would now have no foundation at all to stand on. In other words, my concept of "table" has always been far more abstract and generic - and useful - than probably of  that held by many web page designers. So why should I be letting others tell ME what a "table" is? Sorry, religion has no place in good engineering practices.

    7. Jesse Skinner at 4:14pm on February 2, 2007

    I agree, and I've discussed this in an article:

    Who will read your Semantic HTML?

    However, there are practical benefits of using HTML in a more semantic way. For instance, I don't miss debugging issues with messed up colspans. And labels and header elements have clear benefits as well. But I remain sceptical about how usable the semantics of a list are.

    8. Jen at 4:17pm on April 21, 2007

    "How to write classy code : 101".  As a programmer who had STYLE of code drilled into me from the start, this is the sort of article I like to see.  Well done.

    9. Kula bácsi at 8:37am on May 2, 2007

    Dwight Spencer you are a moron.

    10. Dwight Spencer, Ph.D. at 10:24pm on May 20, 2007

    Kula, no wonder you can't get a decent job anywhere, even in your native Hungary  ... you apparently spend all your time making countless inane comments on blogs everywhere - such as calling the IPhone an "overhyped turd". Thanks again for your wisdom.

    11. suraj d naik at 9:30am on July 3, 2007

    Hi...yes this is all true...working with Div's is real fun & over all layout becomes so strong...that even sometimes you dont need to check the cross browser compatibility...


    12. Jeff Brown at 12:39pm on September 6, 2007

    Nice!  Well done. 

    We need to get away from Classitis and Divitis.  Will we ever?

    13. Nestor Toro at 2:46am on September 7, 2007

    Just FYI, According to the HTML 5 specification, DL DT DD should be semantically interpreted as a list of general name value pairs. Refer to http://www.whatwg.org/specs/web-apps/current-work/ or http://www.w3.org/html/wg/html5/

    14. Shalltell at 4:39pm on October 16, 2007

    Great article Jesse! I'm currently taking the painful (and unpleasant) switch from tables to css and I practically put everything in a class... I'm cleaning it up, too many divs before lunch is terrible, especially when looking for a mistake.

    Semantic HTML is much easier in my opinion, especially for repetitiveness...

    15. olly killick at 1:11pm on November 1, 2007


    just a question, I've been designing and building sites for about 8 months so I'm still a bit new at this.

    When I use a <H1> tag or something similar like a <p> tag, it creates a blank line above the line of text I want to be displayed in the browser, for instance' <h1>Heading</h1>' and I have to place the word 'Heading' to line up next to an image, the text will appear to be a line height lower than the picture when viewed in a browser.

    I want to use code semantic websites, but will not allow anything to compromise my layout. I've been using <span> tags, but this obviously isn't best practice. Can anyone help?


    16. Jesse Skinner at 1:16pm on November 1, 2007

    @Olly - CSS to the rescue! Try this:

    <h1 style="margin:0">Heading</a>

    17. Olly Killick at 5:37am on November 2, 2007

    Thanks Jesse,

    that works a treat, I look forward to coding entirely semantic websites in future.

    Best regards,


    18. Marcus @ TCA at 4:05pm on May 21, 2008

    Very interesting topic, in my opinion all webmasters should really adhere to building well structured web pages and concentrate in using the new technologies available to deliver more readable content by both search engines and humans.

    Something nteresting to read as well: http://dev.opera.com/articles/view/semantic-html-and-search-engine-optimiza/

    19. Div Hater at 12:39pm on June 5, 2008

    hell yeah!!! Let's finally kill div. Those are useless for my site!
    by the way, I will now use the old [label] elements ( I still don't get it).

    you can visit my hosted website. I think I would learn how to use Apache so that I would not be restricted in any way (e.g. content, size, bandwidth, vendor scripts, and so on).

    20. keobs at 6:58pm on June 24, 2008

    some will read to find mistakes, other will ignore the imperfections and grasp a good point... the argument is clear, but it can be presented better the point of this is that u get the point of the article which is what the new era of web design is all about.

    try not to leave your mark by showing u better than others, do what is right and do it right, that will leave a greater mark.

    21. alex at 1:53am on June 30, 2008

    <label> has another useful function too. clicking it (in FF2 at least) will set focus to the form element. can be handy!

    good article, i've switched only recently to true semantic markup..

    22. JB Design and Photo at 3:05pm on September 2, 2008

    As Alex mentioned if you use the label tag then your visitors will be able to use the label to activate the form element, but you must use explicit labels for this to work in IE.

    <label>First Name: <input name="fname"/></label>

    <label for="fname">First Name:</label> <input id="fname" name="fname"/>

    23. Olly at 9:13am on October 28, 2008

    Can I use &nbsp; in a navigation menu? I have to build a layout that requires a fair amount of space between the nav items and HTML will not allow more than one space. The reason I can't use a margin-left etc is that there needs to be a forward slash centered between the menu items. I was wondering if there was another, cleaner way?

    Here is an example of what I'm talking about...

    <li><a href="#">Home &nbsp;&nbsp;/&nbsp;</a></li>
    <li><a href="#">The Course &nbsp;&nbsp;/&nbsp;</a></li>
    <li><a href="#">The Qualifications &nbsp;&nbsp;/&nbsp;</a></li>

    Please help!

    24. JB Design and Photo at 9:42am on October 28, 2008

    The nbsp; is unnecessary markup in your case Olly. You would probably need to use css in this case:

    li {
    border-left: solid 1px #000000;

    ul li:first-child {
    border-left: none;

    Unfortunately the only other option that I know of is the <seperator> element, but it's still just a proposal for XHTML 2.0.

    25. hirakumar at 5:10am on November 25, 2008

    I think you for got to specify for "img" element. Just as title and alt is used to description for image. It is far better or screen reader too.

    26. Olly Killick at 6:56am on January 13, 2009

    Help, I have a container DIV that refuses to scale with all the other scalable elements in it! I haven't assigned a height value as I want it to stretch depending on what is contained in it. Assigning a height value of 'auto' just does the same thing.The browser seems to be reading it as a height value of 0px, even when the elements inside it scale just fine! I'm left with a bunch of white boxes against the coloured background when it should just be one big white rectangle with stuff in it! Help!

    27. capi at 9:28am on February 27, 2009

    You probably need to clear your floats.

    28. Jason Grant at 11:47am on April 7, 2009

    I don't agree that definition lists should be used for any instance where there are key-value pairs in question, unless we are talking about definitions.

    The reason for this is because semantically definitions are definitions and other key-value pair types may be significantly different data types in nature.

    I explain this more on my emerging book on Best Practices in Semantic Development.

    29. Ben Tyers at 9:31am on April 18, 2009

    Useful and informative, many thanks.

    30. Spenser at 10:41am on December 1, 2009

    For others that stumble into this site later:

    @Olly, adding space around a given <li> is padding as opposed to margin.  Margin is the distance between the outer edge of one element to the outer edge of another.  Imagine two boxes, both are the same height and width, increasing margin will separate the two from each other.  Padding on the other hand will increase the interior volume of the box.  So two boxes could be side by side but by increasing padding, the interior contents would still look spaced.  Just a thought.  Oh and remember to write all this is short-code.  #element {margin: top right bottom left; padding: top right bottom left;}

    31. Kent Tan at 4:33am on June 18, 2010

    Great article - well written, unfortunately not well practiced by a lot of web designers.  Many designers work with just photoshop and their "PSD to HTML" process is simply exporting the slices into one huge messy table with images!

    32. Sagar Ranpise at 2:24am on May 25, 2011

    Great Article for anyone! Although I know all of them but understanding it again was good.

    Commenting is now closed. Come find me on Twitter.