While creating the new TechnologyToolbox.com site, one of my first tasks was to define the structure of the HTML for the blog pages.
I briefly considered using my old MSDN blog as a reference. However, I quickly dismissed that option after viewing my MSDN blog home page with CSS disabled.

Figure 1: My MSDN blog home - CSS disabled
One of the most important concepts I learned a few years ago while reading Transcending CSS is that your HTML content should look good “naked” – in other words, without any CSS rules applied:
…with no distracting layout, the meaningful structure of your naked content becomes clear: Visitors can more easily see headings and hierarchy, and they can more easily identify paragraphs, quotations, and lists.
Such meaningful markup and structure simplifies design. Everyone will benefit from an altogether simpler user experience, one that will be as easy to navigate on any device from a large monitor to a small-screen mobile phone. – Clarke, Andy. “Semantics Is Meaning.” Transcending CSS. Berkley: New Riders, 2007: 65.
Even without clicking the See full-sized image link for Figure 1, it is pretty clear that my MSDN blog does not look very good “naked.” Where are the headings? Why do you have to scroll past the list of tags and the archive list (i.e. posts by month) to see the most recent posts? More importantly, why does each item in the list of most recent posts start with a link to “Random Musings of Jeremy Jameson”?!
Compare Figure 1 with the corresponding “naked” version of my new blog home page:

Figure 2: Technology Toolbox blog home page - CSS disabled
Notice how much easier it is to identify the different sections of the page – thanks to the use of HTML heading elements (which were almost nonexistent on my MSDN blog). Also note that the list of recent posts now appears before the list of tags and the archive list. Each post also includes the metadata (such as date published and number of comments) rendered as an unordered list immediately below the post title.
In addition to looking good naked, my new blog conforms to the hAtom 0.1 microformat.
hAtom 0.1 microformat
Another very useful tip that I picked up from reading Transcending CSS is using
microformats as a way of – as Andy puts it – “squeezing new meaning from
XHTML."
Consequently, shortly after deciding not to use my MSDN blog as a reference, I headed over to http://microformats.org/wiki to see if something already existed so I wouldn’t have to start from scratch. That is when I discovered the hAtom 0.1 microformat:
hAtom is a microformat for content that can be syndicated, primarily but not exclusively weblog postings. […]
…
The hAtom schema consists of the following:
- hfeed (
hfeed
). optional.
feed category
. optional. keywords or phrases, using rel-tag.- hentry (
hentry
).
entry-title
. required. text.entry-content
. optional (see field description). text. [*]entry-summary
. optional. text.updated
. required using datetime-design-pattern. [*]published
. optional using datetime-design-pattern.author
. required using hCard. [*]bookmark
(permalink). optional, using rel-bookmark.- tags. optional. keywords or phrases, using rel-tag.
Excellent! Now all I had to do was mockup a few sample blog pages in my static HTML prototype and subsequently create a custom Subtext skin to render the same HTML for the live site.
HTML markup for blog home page
The blog home page (Figure 2) displays a summary of the most recent blog posts.
The entire list is wrapped in an element with class="hfeed"
and each post is
represented as an element with class="hentry"
. The title of each post (a.k.a.
“entry”) is rendered as an <h2>
element with class="entry-title"
.
<div class="hfeed">
<div class="hentry">
<h2 class="entry-title">
<a href="/blog/jjameson/archive/2011/11/06/feedburner-not-showing-your-latest-blog-post.aspx">
Feedburner not showing your latest blog post? Your feed probably
exceeds 512K.</a>
</h2>
<ul class="post-info">
<li class="published">
<span class="label">Published </span>
<span class="value">November 6, 2011</span>
<span class="label"> at </span>
<span class="value">6:00 AM</span>
</li>
<li class="vcard author">
by <span class="fn">Jeremy Jameson</span>
</li>
<li class="comments none">
<a href="/blog/jjameson/archive/2011/11/06/feedburner-not-showing-your-latest-blog-post.aspx#postComments">
<span class="label">Comments: </span>
<span class="value count">0</span>
</a>
</li>
<li class="categories">
<div class="post-categories">
Categories:
<ul>
<li><a rel="tag" href="/blog/jjameson/category/4.aspx">
Development</a></li>
</ul>
</div>
</li>
</ul>
<div class="entry-summary">
<p>This morning I discovered that Feedburner wasn't showing the blog post
I created last Thursday. No error was displayed. Rather the RSS feed
simply made it look like...</p>
</div>
</div>
<div class="hentry">
<h2 class="entry-title">
<a href="/blog/jjameson/archive/2011/11/03/building-technologytoolbox-com-part-4.aspx">
Building TechnologyToolbox.com, Part 4 (a.k.a. Creating a style guide and
color palette for a Web application)</a>
</h2>
<ul class="post-info">
<li class="published">...</li>
...
</ul>
<div class="entry-summary">
<p>...</p>
</div>
</div>
<div class="hentry">
<h2 class="entry-title">
<a href="/blog/jjameson/archive/2011/10/27/building-technologytoolbox-com-part-3.aspx">
Building TechnologyToolbox.com, Part 3 (a.k.a. Creating a static HTML
prototype for a website)</a>
</h2>
<ul class="post-info">
<li class="published">...</li>
...
</ul>
<div class="entry-summary">
<p>...</p>
</div>
</div>
...
</div>
Similar to the
first example for the hAtom microformat,
I use an unordered list to display the post metadata (<ul class="post-info">
).
The corresponding list items then specify the various class
attributes
according to the hAtom schema (e.g. <li class="published">
).
Note
At this point, I have deliberately deviated from the datetime-design-pattern for the publication date (i.e.
<li class="published">
) due to the known accessibility issues with the Datetime Design Pattern (i.e. using an<abbr>
element to represent the date/time with thetitle
attribute containing the ISO8601 datetime value).Instead, I chose to use a simpler format based on the Value Class Pattern.
The post summaries are rendered as paragraphs inside
<div class="entry-summary">
elements.
By adding the <span class="label">
elements to various pieces of text, I can
easily hide some portions of the content via CSS. For example, notice how the
first blog post in Figure 2 shows the following:
Published November 6, 2011 at 6:00 AM
However, when you view the same page with the corresponding CSS enabled, only the date portion is shown:
November 6, 2011
Since the list of recent posts will likely contain items that were published more than 24 hours ago, showing the time version of the publication date seems superfluous. On the other hand, when viewing an individual blog post, the time portion is shown:
November 6, 2011 6:00 AM
In both cases, the underlying HTML markup is the same – it’s just that different CSS rules are applied.
Similarly, I use CSS rules to conditionally show the “comment bubble” icon along
with a link to view the comments for a particular post. For example, in Figure 3
notice how the Last Day with Microsoft post includes an icon and the
corresponding number of comments on the same line as the publication date,
whereas the first post in the list does not. This is accomplished by adding an
additional class to the list item to indicate that a particular post has no
comments (i.e. <li class="comments none">
).

Figure 3: Blog home page
HTML markup for individual blog post
When viewing a specific blog post, the HTML markup is very similar to the blog
home page. The primary difference is that the <div class="entry-summary">
element is replaced by the <div class="entry-content">
element.
<div id="blogPost">
<div class="hentry">
<h2 class="entry-title">
Feedburner not showing your latest blog post? Your feed probably exceeds
512K.
</h2>
<ul class="post-info">
<li class="published">
<span class="label">Published </span>
<span class="value">November 6, 2011</span>
<span class="label"> at </span>
<span class="value">6:00 AM</span>
</li>
<li class="vcard author">
by <span class="fn">Jeremy Jameson</span>
</li>
<li class="comments none">
<a href="#postComments">
<span class="label">Comments: </span>
<span class="value count">0</span>
</a>
</li>
<li class="categories">
<div class="post-categories">
Categories:
<ul>
<li><a rel="tag" href="/blog/jjameson/category/4.aspx">
Development</a></li>
</ul>
</div>
</li>
</ul>
<div class="entry-content">
<p>This morning I discovered that Feedburner wasn't showing
<a href="/blog/jjameson/archive/2011/11/03/building-technologytoolbox-com-part-4.aspx.aspx">
the blog post I created last Thursday</a>.</p>
<p>No error was displayed. Rather the RSS feed simply made it look like
"<a href="/blog/jjameson/archive/2011/10/27/building-technologytoolbox-com-part-3.aspx">
Part 3</a>" in my series on building TechnologyToolbox.com was the
last post that I created (having written it myself, I knew that
"Part 4" was, in fact, the latest post).</p>
...
</div>
...
</div>
The “trick” to formatting the same HTML differently when viewing individual blog
posts (for example, to show the time portion of the publication date) is to
specify a different “container” element than the blog home page (e.g.
<div id="blogPost">
instead of <div id="blogHome">
).
Tip
I like to specify unique “container” elements like this for all pages in a Web application (e.g.
<div id="companyHome">
). Even though you typically want CSS rules to be very generic (and thus apply to all pages), there may be times when you need to tweak the formatting of some element on a particular page (or set of pages). If each ASP.NET file specifies a unique “container” element, customizing the formatting for specific pages is very easy.
Resist the urge to change your HTML
Once you have defined the structure of your markup – and assuming you have used semantic HTML – you shouldn’t need to change it very much (if at all) during the process of implementing the desired layout and formatting.
Sure, you may have to do some “tweaking” in order to more easily implement your
design (such as adding a few id
and class
attributes here and there) – but,
generally speaking, if you’ve done your job right in defining your markup, it
shouldn’t need to be changed every time a client requests a change to the UI
design.
Whenever you are creating a new website – or adding a new feature to an existing site – I encourage you to start by focusing on the “naked” structure. Once you have defined the meaningful structure for your content, you can then proceed to making it “look pretty.”