Creating a WordPress Theme HTML Structure

Now we’re starting to get into the real meat of WordPress Theme development: coding the HTML structure.

The Goals of Any HTML Structure

When coding a web site, you should have 2 goals in mind: lean code and meaningful code. That is, using as little markup (HTML tags) as possible and making sure that the markup is meaningful by using semantic class and ID names that refer to their content, not how they “look” (class=”widget-area” instead of class=”sidebar-left”).

Now, when coding a WordPress Theme (or any template for any Content Management System) a balance is going to have to be struck between lean markup, with very little structure, and what’s called Divitis; including too many unnecessary div elements in your code. In other words, too much meaningless structure. You’ve probably seen the div tag before if you’ve looked at the code for a website or any WordPress Theme. Think of them as containers for HTML code—containers that are very handy for manipulating HTML code with CSS. Obviously we’re going to have some. But we don’t want too many or ones without meaning.

HTML5 has made our quest for meaningful markup much easier with the addition of structural tags such as header, nav, and footer. These new elements are similar to the div tag in that they can also serve as containers for HTML code. At the same time, they allow us to create a much more descriptive outline for our HTML.

Ultimately, we want enough structure—using the new tags in HTML5 as well as the div tag—that we can reuse our code for multiple blog and site layouts. We want to code something we can come back to and use again.

The HTML Structure for Your WordPress Theme

Let’s take a look at the HTML structure we’ll be using for the body of our WordPress Theme.

<div id="page" class="hfeed site">
     <header id="masthead" class="site-header" role="banner">
          <nav role="navigation" class="site-navigation main-navigation"></nav><!-- .site-navigation .main-navigation -->
     </header><!-- #masthead .site-header -->
     <div id="main" class="site-main">
          <div id="primary" class="content-area">
               <div id="content" class="site-content">
               </div><!-- #content .site-content --></div>
          <!-- #primary .content-area -->
          <div id="secondary" class="widget-area">
          </div><!-- #secondary .widget-area -->
          <div id="tertiary" class="widget-area">
          </div><!-- #tertiary .widget-area --></div>
     <!-- #main .site-main -->
     <footer id="colophon" class="site-footer" role="contentinfo">
          <div class="site-info">
          </div><!-- .site-info -->
     </footer><!-- #colophon .site-footer -->
</div> <!-- #page .hfeed .site -->

Actually, this HTML forms the backbone of _s (pretend it’s an x-ray). Go ahead and paste this code into your text editor and save it somewhere handy. We’ll be using it later when we build the file structure for our theme. But before we do that, there are a few things we’ll want to take a look at here.

A Quick Tour Through Your WordPress Theme HTML

Visualization of HTML Structure
Visualization of a sample implementation of the HTML structure. Click for a larger view.

Check out the visualization of the HTML structure above. The darker a block, the deeper it is nested. The arrangement of these blocks are determined largely by CSS, which we’ll cover in a later lesson.

You can also modify the HTML structure itself to suit your needs. For example, you can move the navigation block outside of the header block, or move one of the widget areas into the footer block. For the purposes of this tutorial, though, we’ll keep the HTML structure as is, and when we get to it, use CSS to arrange our content and widget areas.

All right, let’s walk through the code a bit.

Firstly, the class attribute on the wrapper, hfeed. hfeed is part of the hatom Microformat schema. In plain English, this means that adding that hfeed class to our page tells any machines reading our site (like search-engine bots or some other service) that our site publishes syndicated content, like blog posts. You’ll be seeing a lot of class names like this as we go along.

Looking at the structure for the header and footer, you’ve probably noticed the new HTML5 structural tags, header and footer, respectively. These tags describe the broad sections of the document. By borrowing class names from the publishing world (WordPress makes us content publishers, right?), I’ve tried to add further meaning to the markup that will be resting in these containers as well as the containers that fall within them.

You’ll also notice the ARIA “role” attribute on the structural HTML tags. The role attribute helps make it easier for those using assisitive technology devices to navigate through your site. To learn more, check out HTML5 Accessibility Chops: When to use an ARIA role.

In the main area of our HTML, note that our widget areas come after our content area. And you may also have noticed that our content rests inside a container div (with the class name of “content-area”). These points are key. This not only lets our main content come before the sidebars in the eyes of search engines (and screen readers) but by using a CSS technique involving negative margins, we can make this into a 1- or 2-column theme with only a few lines of CSS.

This HTML structure is going to future-proof your WordPress Theme and give you the opportunity to do powerful stuff with CSS. It’s a good one.

How To Create a WordPress Theme

This post is part of the The ThemeShaper WordPress Theme Tutorial: 2nd Edition that will show you how to create a powerful WordPress Theme from scratch. Read it from the beginning and code yourself up something awesome.

  1. WordPress Theme Tutorial Introduction
  2. Developing Theme Sense
  3. Theme Development Tools
  4. Creating a Theme HTML Structure
  5. Template and Directory Structure
  6. Setting Up Your Theme Functions
  7. Secure Your WordPress Theme
  8. The Header Template
  9. The Index Template
  10. The Single Post, Post Attachment, & 404 Templates
  11. The Comments Template
  12. The Search Template & The Page Template
  13. The Archive Template
  14. The Sidebar Template & The Footer Template
  15. Reset-Rebuild Theme CSS & Define Your Layouts
  16. Custom Background & Custom Header
  17. Distributing Your WordPress Theme

26 thoughts on “Creating a WordPress Theme HTML Structure”

  1. Thanks for the introduction, Ian! I love _s already and look forward to follow the tutorial and learn. Since this seems to be a good opportunity to get a first-hand answer on something I’ve been wondering about working with _s:
    Is there a particular reason why only divs are used inside the #main container, and not i.e. section elements?

    From my (rather basic) understanding of HTML5, a semantic element like section would be appropriate at least for #content, maybe even for .content-area and both .widget-area? Why do you prefer divs?

  2. This is great. I have been on the lookout for a series like this.
    It might just save my life. Being in real estate isn’t going to pay the bills, so I’m off into the WordPress sunrise…

  3. Pretty great introduction for creating a wordpress theme. this helps me to understand the html structure very well. thanks and cheers.


  4. Opps, didn’t even think about the html filter. Basically the line
    div id “tertiary”
    does not have a class attribute but the closing comment makes me think it should?
    #tertiary .widget-area

  5. Nice tutorial. You’ve got most of the bases covered. It would be helpful if we could see the final, finished files. I ran into some problems, and wanted to compare my files with what they should look like.

    Also, I notice in your Thematic theme (which I chose for testing), you name a lot of hooks based on location, not function. For example, thematic_abovecontent();, thematic_navigation_above();, thematic_below_indexloop();. I understand why, but I’m just curious about your take on best practices for when to use names that reference location. (Naming things drives me crazy, for sure.)

    Thanks again for a helpful tutorial.

    1. Hi Erin!

      You can download the finished files here. If you’re interested in a sample CSS file for the theme, you can grab that here.

      This tutorial is not related to Thematic, so some of the things you read here may not apply to Thematic (the Thematic theme was also originally written earlier than this tutorial, and conventions may have changed since then).

      Different people have differing opinions, but in my opinion, naming hooks is a bit different from naming document sections. Hooks are intended for developers to insert custom code inside various parts of the theme via functions. Naming hooks based on location makes it easier for developers to find where they want to insert their code.

  6. Thanks Stewart, this is very essential tutorial for all those who are trying to build a custom wordpress theme. And you wrote to it so well that its easy to follow steps

  7. Any reason why you couldn’t have <body id="page" class="hfeed site">, rather than an otherwise redundant div element?

  8. “Let’s take a look at the HTML structure we’ll be using for the body..” Ok but what file? I am using the Shape theme, where is this “body” you are showing, I looked in page and index and it looks nothing like the code you posted.

    1. Actually, this HTML forms the backbone of _s (pretend it’s an x-ray). Go ahead and paste this code into your text editor and save it somewhere handy. We’ll be using it later when we build the file structure for our theme. But before we do that, there are a few things we’ll want to take a look at here.

      It’s just the HTML structure (so no PHP) of the theme (index/page+footer).

  9. Thank you – was confusing at first, I am used to seeing tutorials that follow source code and I was expecting just that.

  10. Any chance of updated info-graphic for WordPress anatomy? 3.6.1
    As I understand html structure and file request logic in loop has changed also in latest underscore _S.

  11. is there a way to change path of background image? instead of selecting background image from Upload folder can it be set so it sees images from within images folder of the theme?

    1. If you’d like to add a way for users to select a background image from a set of graphics that you’ve bundled with a theme, it would be better to add that as a theme option instead, so you’re not modifying a core WordPress function. Here are some resources for how to create theme options within the customizer:

  12. I still don’t understand the need for a semantic class such as class=”widget-area”. Does it have any impact on the look or is it merely a guide? I can’t find any reference in style.css to widget-area. Pray explain. I have searched the net and am still no wiser

    1. Hi Steve – that’s a “hook” in the HTML so that if you wanted to style all widget areas with CSS, you could – all you’d need to do is add the class to your style.css and assign some styles to it.

Comments are closed.