Creating Effective Semantic Markup
Mani Sheriar | November 13, 2009
When I was first approached about writing this article, I thought, "Doesn't everyone know how to create effective semantic markup already?" I’ve been immersed in Web standards for nearly seven years, and it's easy to think that everyone just gets it at this point—especially when most of where I go on the Web is to the blogs of other Web designers immersed in Web standards, or the CSS Zen Garden, or the numerous CSS showcase sites, or the sites of my colleagues (okay, and Flickr and Facebook, but I don't like to look under the hood on those sites).
But when I dug a little deeper into my own experience working with other developers, both front-end and back-end, I realized that there is still a lot to learn and a lot of room for growth. Some specific groups came to mind, and I started getting pretty excited about the idea of being able to talk to them about how to create high-quality markup and why they should care. These groups include folks new to coding who could benefit a great deal from learning best practices from the start, and also old-timers (which probably means anyone thirty-something or older, like me) who might be a bit stuck in their ways and not convinced about why they need to change. But most of all, I got excited about talking to back-end developers, the kind I need to work with to get larger projects done—the kind writing Ruby on Rails, ASP.NET, PHP, Python, or any other language that basically looks like Klingon to me.
What Are Web Standards?
One of my favorite descriptions of Web standards comes from Russ Weakley, of MaxDesign:
"The term web standards can mean different things to different people. For some, it is “table-free sites”, for others it is “using valid code”. However, web standards are much broader than that. A site built to web standards should adhere to standards (HTML, XHTML, XML, CSS, XSLT, DOM, MathML, SVG etc) and pursue best practices (valid code, accessible code, semantically correct code, user-friendly URLs etc).
In other words, a site built to web standards should ideally be lean, clean, CSS-based, accessible, usable and search engine friendly.."
To me, more than anything else, Web standards mean a total separation of style and content, as well as content that is accessible across all platforms, browsers, and devices and available to the widest possible spectrum of users and user agents.
Why Should You Care?
As a person writing front-end or back-end code, you have several reasons to care about the quality of the (X)HTML you create. Among them, writing high-quality code can do the following:
- Make it easier (and thus faster and cheaper) for yourself or others in the future to update, add on to, or redesign the site or application you're working on
- Reap the well-touted benefits of faster downloads, higher SEO rankings, better accessibility, and future-proofing
- Gain the respect of your colleagues and clients (which, you know, can help you make a living)
And, my personal favorite if you are a back-end person:
- Make front-end colleagues love you and love working with you (which, again, can translate into more work and thus more money, because folks like me are going to be much more stoked about working with you again).
How Do You Do It?
I like to try to write my code as if I might get hit by a bus tomorrow. I enjoy the idea that anyone with a modicum of coding knowledge could come in, get up to speed, and take over where I left off in a minimal amount of time (and with minimal frustration). I accomplish this in a few ways …
Envision the Unstyled Document
When I am writing my (X)HTML and I come across any question in my mind about the best way to code something (whether to use a blockquote or a div, a definition list or a table, a heading or bolded text), I ask myself one surprisingly simple question, which almost always yields the proper response: "How would I code this if I were doing so for a text-only browser?" Of course, on some level you need to consider your design, but as a designer, I say to you consider it very little when you are writing your markup. Consider it in terms of the containers and the minimal hooks for CSS that you might need to accomplish your layout, but otherwise, when it comes to figuring out the semantics of your actual tags, don't consider it at all.
The Markup
Here is the main content area on the home page of my website:
A lot goes on visually that you might think requires markup to achieve. For instance, the page includes the icons on the left, the dashed-outline background boxes, the headings, the text, and the big buttons on the right. Plus, you need a way to make the entirety of each section a link that changes all the graphics on hover.
So, you might think that you need a lot of wrapper divs or spans or other extra markup to accomplish all this, but when you think about it in terms of the unstyled document, the markup required is actually pretty minimal, even with enough CSS hooks to work some magic later. It includes an unordered list, some linked titles, and some text, and it looks like this:
<ul>
<li class="portfolio">
<h3><a href="portfolio/index.htm"><span>Portfolio</span></a></h3>
<p>See how I put both my artistic and geeky sides to good use creating websites that inspire.</p>
</li>
<li class="about">
<h3><a href="about/index.htm"><span>About</span></a></h3>
<p>Learn how to pronounce my name and other things you might want to know about me.</p>
</li>
<li class="photography">
<h3><a href="photography/index.htm"><span>Photography</span></a></h3>
<p>Check out my passion for combining formal training in art with years of digital design experience.</p>
</li>
<li class="contact">
<h3><a href="contact/index.htm"><span>Contact</span></a></h3>
<p>Get in touch to talk with me about potentially working together or anything else.</p>
</li>
</ul>
This gives me an unstyled document that looks just as I want it to:
To give you a fuller sense of what I mean when I tell you to write your markup for the unstyled document, I have created a completely unstyled, and non-JavaScript version of my site. I didn't alter any of the HTML; I just got rid of CSS and JavaScript calls. I hope you can see that it is well organized and easy to read. Notice that all presentational images are gone and only portfolio and photography images (which are actually part of the content) remain.
Of course, you also want to keep your code organized and well commented. At the very least, in terms of comments, I like to put something at the end of each div closure, something along the lines of <!-- end sidebar -->,
so that it's easy to tell what it is that's being closed. Also, if I’m using Dreamweaver, I find that going to Commands > Apply Source Formatting can do wonders for keeping everything properly indented and lined up and easy to scan.
The Style
I now have everything I need to style this up, so let's go to it! The CSS for this section looks like this:
#bd-home #maincol ul {
margin:0;
list-style-type:none;
}
#bd-home #maincol ul li {
margin:0 0 23px 0;
width:648px;
height:109px;
position:relative;
}
#bd-home #maincol ul h3 span,
#bd-home #maincol ul p {
display:none;
}
#bd-home #maincol ul h3 a {
display:block;
width:648px;
height:109px;
position:absolute;
top:0;
left:0;
}
#bd-home #maincol ul li.portfolio a {
background:url(../_images/home/portfolio.gif) no-repeat 0 0;
}
#bd-home #maincol ul li.portfolio a:hover {
background:url(../_images/home/portfolio.gif) no-repeat -648px 0;
}
#bd-home #maincol ul li.about a {
background:url(../_images/home/about.gif) no-repeat 0 0;
}
#bd-home #maincol ul li.about a:hover {
background:url(../_images/home/about.gif) no-repeat -648px 0;
}
#bd-home #maincol ul li.photography a {
background:url(../_images/home/photography.gif) no-repeat 0 0;
}
#bd-home #maincol ul li.photography a:hover {
background:url(../_images/home/photography.gif) no-repeat -648px 0;
}
#bd-home #maincol ul li.contact a {
background:url(../_images/home/contact.gif) no-repeat 0 0;
}
#bd-home #maincol ul li.contact a:hover {
background:url(../_images/home/contact.gif) no-repeat -648px 0;
}
I use CSS to give the list items fixed width and height with a relative position (which is important because you want to absolutely position the links within them), to hide the H3 text and the paragraphs, and to turn the links into block-level elements that are the same size as their containers and positioned absolutely within them. Now I can simply set a background for each link. The four backgrounds look like this:
By creating the off and the hover states in one image, the hover state is preloaded (no annoying flicker on-hover as we wait for the image to load). I simply change the background position to have it appear on rollover.
Make Use of the Cascade
They're called cascading style sheets for a reason, and one of the most helpful things to do to keep your markup lean, mean, and flexible is to ensure enough hooks for CSS, but to move away from creating unnecessary classes and IDs by making better use of the cascade. I remember the first time I used CSS for a Web site. I think I gave every <p> tag a class of "text" and every <a> tag a class of "link." Oh, the shame!
The Markup
In each main section of my Web site I have a different image-based title for the main H2 of the page:
You might think that you need to add a unique class or ID to the H2 of each of these pages, but if you've given a unique ID to the <body> of each page, there's no need because you can simply make use of the cascade.
<body id="bd-portfolio">
<div id="container-wrapper">
<div id="container">
<div id="header">
...
<h2><span>Selected Projects</span></h2>
</div>
<!-- end header -->
The Style
With a unique body ID in place, you can go ahead and attach the styles. First I define the basic styles for the main H2:
/* --
***** Page Title
---------------------------------------------------------------------*/
#header h2 {
position:absolute;
top:109px;
left:279px;
margin:0;
height:65px;
width:653px;
}
#header h2 span { display:none;
}
Then I define the images for each individual page:
#bd-portfolio #header h2 {
background:url(../_images/portfolio/title.gif) no-repeat 0 0;
}
#bd-about #header h2 {
background:url(../_images/about/title.gif) no-repeat 0 0;
}
#bd-photography #header h2 {
background:url(../_images/photography/title.gif) no-repeat 0 0;
}
#bd-contact #header h2 {
background:url(../_images/contact/title.gif) no-repeat 0 0;
}
Of course, this example is pretty simple, but if you can carry this idea forward into more complex scenarios, you can save yourself a lot of unnecessary work. I usually ask myself before creating a new ID or class, "Is this really necessary, or can I target this element using hooks that are already in place?" If you give a unique ID to each page or page type, and unique IDs to all main page sections, you'll be surprised about how few classes you can get away with.
Meaningful ID and Class Names
You might think this is a no-brainer. I certainly do! But you'd be amazed how many times I've had to style elements with classes called things like "block-block-block-47" (yes, I'm talking to you, Drupal!) or other almost equally meaningless names. These kinds of ridiculous classes and IDs can create a real headache for the poor front-end person, so back-end people, I beg of you, think about us for a second when you are creating the code that will be spit out by your respective programming languages, and be sure it makes sense.
Also, if something is always going to be side content, call it "sidecol" or "sub-content" or something that isn't "left-column" or the like. What if I want to move that column to the right on a subsequent redesign? Imagine the dicey find-and-replace that would create? (Unless you just live with a left side column referred to everywhere as "rightcol", causing anyone who works on the site to figure that out every time.) Think ahead when you're naming things and ask, "Does this describe the function or the style of an element?" If it's the style, rethink it.
No Shortcuts
Some of the really smart programmers I've worked with don't understand why it's a problem to have empty paragraph tags to create extra space in a document, or why it's a bad idea to use <br / ><br /> to create that same space. These are valid tags, right? And the markup will validate, so what's the problem? Maybe they know that it's a little less than ideal, but when they're pressed for time and it's the quickest solution, they just don't get what the big deal is. Let me try to explain why this can create some very real problems.
Let's say you've thrown some empty <p> tags into your markup to create additional space at the bottom of article pages. First of all—and this is key—if you are not the designer (or at least a designer), the chances are that you aren’t able to notice that the space is much too big (or perhaps not big enough). But I will notice this, and quite likely our client and some of our users will notice it too. Now I've been tasked to "fix it," but I can't go into the CSS and adjust the space, because I can't target all paragraphs, right? I'm left having to find the element that always comes after the space (if I'm lucky enough for it to be that consistent) and give it a negative top margin to tighten up the space (inevitably only to discover that this causes that element to visually overlap others when that empty tag isn't present), or I need to do some sort of JavaScript wizardry to find all empty <p> tags in article pages, give them a class of "empty", and then I can style the space. I might find some other convoluted way to target the empty <p> tags, if possible, but if not, I have to ping you and try to explain why you need to take those out (and you’d be surprised at what an awkward conversation that can be).
Or ... you could not put in an empty <p> tag, and I could simply add more padding to the bottom of article containers via CSS. Yes, please!
Remember the unstyled document question, and you'll soon see that empty <p> tags or multiple <br /> tags don't belong. In an unstyled document they would create awkward space.
Again, I know this example is relatively simple, but it is the one that came to mind as perhaps the most ubiquitous I've come across. If you can extract this principal— that semantic code is more than just for validating and that how well you write it can have profound effects on development time—we'll have made a big leap forward together. Front-end and back-end unite!
Well-Organized Style Sheets
I've worked on some fairly large sites, and the style sheets can get quite long! When you are working with a style sheet that has thousands of declarations, it can be easy to become overwhelmed just figuring out where to go to target an element. The best way to avoid this is to get really organized. I have a protocol I always follow that makes sense to me and I hope will to others. My style sheets usually start off with some sort of basic structure like this:
/****************************************************************
-------------------------- GENERAL ------------------------------
****************************************************************/
html {}
body {}
a {}
/****************************************************************
-------------------- MAIN STRUCTURE -----------------------------
****************************************************************/
#container {}
#header {}
#content {}
#maincol {}
#sidecol {}
#footer {}
#copyright {}
/****************************************************************
----------------------------- HEADER ----------------------------
***************************************************************/
/* -- ***** Main Navigation
---------------------------------------------------------------*/
#mainnav {}
/* --***** Secondary Navigation
---------------------------------------------------------------*/
#subnav {}
/****************************************************************
----------------------- MAIN COLUMN -----------------------------
****************************************************************/
#maincol {}
/* -- ***** Home Page
---------------------------------------------------------------*/
#bd-home {}
/* --***** About Page
---------------------------------------------------------------*/
#bd-about {}
/* --***** Photography Page
---------------------------------------------------------------*/
#bd-photography {}
/* --***** Contact Page
---------------------------------------------------------------*/
#bd-contact {}
/****************************************************************
-------------------- SIDE COLUMN --------------------------------
****************************************************************/
#sidecol {}
/****************************************************************
-------------------- FOOTER & COPYRIGHT-------------------------
****************************************************************/
/* --***** Footer
---------------------------------------------------------------*/
#footer {}
/* --***** Copyright
---------------------------------------------------------------*/
#copyright {}
/** -------------Third Level ---------- **
/* -- fourth level-- */
I make big, huge, obvious section dividers that I can spot and search for easily. I put all page-specific styles in their own sections, and I always name them "Something Page" so that if I'm working on a really long style sheet and I want to find the styles for, say, the checkout page, I can do a search for "checkout page" and go right to them. I also write the styles in the same order as the markup. For example, if the side column markup comes before the main column, I put it first in the style sheet, too. Footer and copyright info is always last—the flow makes sense relative to the markup. I even put page sections in the order they appear in the nav. This also makes it easier for me to find things.
Building a Sturdy Foundation
Remember the buildings in Dr. Seuss stories, how they were always teetering, built too high on awkward stilts and such, and looked like they could never really remain standing? Even though their foundations weren’t at right angles, the buildings seemed sturdy enough at the start, but they became less and less structurally sound with each addition. This is exactly what happens to our code when we're not intentional about writing it carefully and correctly. We are a little sloppy at first, which creates a butterfly effect throughout our team and over time. Eventually, small changes or updates take more time than we could have imagined because so much energy is required just to decipher disorganized style sheets, work around code that is inadequate for styling, or pinpoint the code that is causing problems.
It starts with an empty <p> tag, a nondescriptive class name, a lack of hooks for CSS. Then the coding gymnastics performed to overcome these issues simply compound the problem—and on and on. Correcting problems like these becomes increasingly challenging or even impossible, but it is relatively easy to avoid these pitfalls from the start. All you really need is an understanding that markup matters. It is the foundation for any Web site or Web application. Build it clean, lean, and organized, and you will set up yourself, your team, and ultimately your project for success!
About the Author
The Girl With Many Hats
Mani Sheriar is a 30-something year old web designer hailing from the Northern California Bay Area. Her intense need to express creativity led her to a Bachelors degree in Fine Arts from The Corcoran College of Art and Design in Washington D.C. in 1995.
After a few years trying to make it as an artist, and then another few trying to make it in the business world, she threw in the towel on each only to discover her true love for both in the form of founding and running her own web design business, Sheriar Designs.
As a web goddess she found a perfect synergy for her outgoing, friendly personality, her highly cultivated sense of aesthetics, her love of (yes, she actually LOVES it) coding, and her maddening need for perfect order in all things.