12 Principles For Keeping Your Code Clean


Beautiful HTML is the foundation of a beautiful website. When I teach people about CSS, I always begin by telling them that good CSS can only exist with equally good HTML markup. A house is only as strong as its foundation, right? The advantages of clean, semantic HTML are many, yet so many websites suffer from poorly written markup.

Let’s take a look at some poorly written HTML, discuss its problems, and then whip it into shape! Bear in mind, we are not passing any judgment on the content or design of this page, only the markup that builds it. If you are interested, take a peek at the bad code1 and the good code2 before we start so you can see the big picture. Now let’s start right at the top.

1. Strict DOCTYPE Link

If we are going to do this, let’s just do it right. No need for a discussion about whether to use HTML 4.01 or XHTML 1.0: both of them offer a strict version that will keep us nice and honest as we write our code.

strict doctype example

Our code doesn’t use any tables for layout anyway (nice!), so there really is no need for a transitional DOCTYPE.


2. Character set & encoding characters Link

In our <head> section, the very first thing should be the declaration of our character set. We’re using UTF-8 here, which is swell, but it’s listed after our <title>. Let’s go ahead and move it up so that the browser knows what character set it’s dealing with before it starts reading any content at all.

character example

While we’re talking about characters, let’s go ahead and make sure any funny characters we are using are properly encoded. We have an ampersand in our title. To avoid any possible misinterpretation of that, we’ll convert it to &amp; instead.


3. Proper indentation Link

All right, we are about three lines in and I’m already annoyed by the lack of indentation. Indentation has no bearing on how the page is rendered, but it has a huge effect on the readability of the code. Standard procedure is to indent one tab (or a few spaces) when you are starting a new element that is a child element of the tag above it. Then move back in a tab when you are closing that element.

indentation example

Indentation rules are far from set in stone; feel free to invent your own system. But I recommend being consistent with whatever you choose. Nicely indented markup goes a long way in beautifying your code and making it easy to read and jump around in.


4. Keep your CSS and JavaScript external Link

We have some CSS that has snuck into our <head> section. This is a grievous foul because not only does it muddy our markup but it can only apply to this single HTML page. Keeping your CSS files separate means that future pages can link to them and use the same code, so changing the design on multiple pages becomes easy.

external example

This may have happened as a “quick fix” at some point, which is understandable and happens to all of us, but let’s get that moved to a more appropriate place in an external file. There is no JavaScript in our head section, but the same goes for that.

5. Nest your tags properly Link

The title of our site, “My Cat Site,” is properly inside <h1> tags, which makes perfect sense. And as per the norm, the title is a link to the home page. However, the anchor link, <a>, wraps the header tags. Easy mistake. Most browsers will handle it fine, but technically it’s a no-no. An anchor link is an “inline” element, and header tags are “block” elements. Blocks shouldn’t go inside inline elements. It’s like crossing the streams in Ghostbusters. It’s just not a good idea.

nesting example

6. Eliminate unnecessary divs Link

I don’t know who first coined it, but I love the term “divitis,” which refers to the overuse of divs in HTML markup. Sometime during the learning stages of Web design, people learn how to wrap elements in a div so that they can target them with CSS and apply styling. This leads to a proliferation of the div element and to their being used far too liberally in unnecessary places.

divitis example

In our example, we have a div (“topNav”) that wraps an unordered list (“bigBarNavigation”). Both divs and unordered lists are block-level elements. There really is no need whatsoever for the <ul> to be wrapped in a div; anything you can do with that div you can do with the <ul>.


7. Use better naming conventions Link

This is a good time to bring up naming conventions, as we have just talked about that unordered list with an id of “bigBarNavigation.” The “Navigation” part makes sense, because it’s describing the content that the list contains, but “big” and “Bar” describe the design not the content. It might make sense right now because the menu is a big bar, but if you change the design of the website (and, say, change the website navigation to a vertical style), that id name will be confusing and irrelevant.

naming conventions example

Good class and id names are things like “mainNav,” “subNav,” “sidebar,” “footer,” “metaData,” things that describe the content they contain. Bad class and id names are things that describe the design, like “bigBoldHeader,” “leftSidebar,” and “roundedBox.”

8. Leave typography to the CSS Link

The design of our menu calls for all-caps text. We just dig how that looks, and more power to us. We have achieved this by putting the text in all-caps, which of course works; but for better, future extensibility, we should abstract typographic choices like this one to the CSS. We can easily target this text and turn it to all-caps with {text-transform: uppercase}. This means that down the road, if that all-caps look loses its charm, we can make one little change in the CSS to change it to regular lowercase text.

typography example

9. Class/id the <body> Link

By “class the body,” I literally mean apply a class to the body, like <body class=”blogLayout”>. Why? I can see two things going on in this code that lead me to believe that this page has a layout that is different than other pages on the website. One, the main content div is id’d “mainContent-500.” Seems like someone had a “mainContent” div at one point and then needed to alter its size later on and, to do so, created a brand new id. I’m guessing it was to make it larger, because further in the code we see <class=”narrowSidebar”> applied to the sidebar, and we can infer that that was added to slim down the sidebar from its normal size.

This isn’t a very good long-term solution for alternate layouts. Instead, we should apply a class name to the body as suggested above. That will allow us to target both the “mainContent” and “sidebar” divs uniquely without the need for fancy new names or class additions.

body class example

Having unique class and id names for the body is very powerful and has many more uses than just for alternate layouts. Because every bit of page content lies in the “body” tag, you can uniquely target anything on any page with that hook; particularly useful for things like navigation and indicating current navigation, since you’ll know exactly what page you are on with that unique body class.


10. Validate Link

Kind of goes without saying, but you should run your code through the ol’ validator machine to pick up small mistakes. Sometimes the mistakes will have no bearing on how the page renders, but some mistakes certainly will. Validated code is certain to outlive non-validated code.

validation example

If for no other reason, seeing that green text on the W3C validator tool just makes you feel good inside.


11. Logical ordering Link

If it is at all possible, keeping the sections of your website in a logical order is best. Notice how the footer section lies above the sidebar in our code. This may be because it works best for the design of the website to keep that information just after the main content and out of the sidebar. Understandable, but if there is any way to get that footer markup down to be the last thing on the page and then use some kind of layout or positioning technique to visually put it where you need it, that is better.

order example

12. Just do what you can Link

We’ve covered a lot here, and this is a great start to writing cleaner HTML, but there is so much more. When starting from scratch, all of this seems much easier. When trying to fix existing code, it feels a lot more difficult. You can get bogged down in a CMS that is forcing bad markup on you. Or, there could be just so many pages on your website that it’s hard to think of even where to begin. That’s OK! The important thing is that you learn how to write good HTML and that you stick with it.

The next time you write HTML, be it a small chunk in a huge website, or the beginning of a fresh new project, just do what you can to make it right.

order example


Footnotes Link

  1. 1 http://www.smashingmagazine.com/images/principles-keep-code-clean/CodeExamples/bad.html.txt
  2. 2 http://www.smashingmagazine.com/images/principles-keep-code-clean/CodeExamples/good.html.txt
  3. 3 http://www.w3.org/QA/2002/04/valid-dtd-list.html
  4. 4 http://www.alistapart.com/stories/doctype/
  5. 5 http://www.456bereastreet.com/archive/200609/no_more_transitional_doctypes_please/
  6. 6 http://en.wikipedia.org/wiki/UTF-8
  7. 7 http://www.cs.tut.fi/~jkorpela/chars.html
  8. 8 http://www.ascii-code.com/
  9. 9 http://www.w3.org/People/Raggett/tidy/
  10. 10 http://csscreator.com/?q=divitis
  11. 11 http://css-tricks.com/id-your-body-for-greater-css-control-and-specificity/
  12. 12 http://www.37signals.com/svn/archives2/case_study_reusing_styles_with_a_body_class.php
  13. 13 http://validator.w3.org/
  14. 14 http://xhtml-css.com/
  15. 15 http://freesitevalidator.com/

↑ Back to top Tweet itShare on Facebook

I create websites and help others create better websites through writing and speaking. I consider myself a lucky man for getting to work in such a fun and rewarding field.

  1. 1

    So does div{margin:0 auto;}

  2. 2

    13. Apply the concept of DRY to your websites — use includes for repeating code like navigation, footer, headers, etc.

    14. Comment your closing div tags for when you come back to it in the future

    **Most times when people don’t use logical ordering it is because they want the most important information at the top of the page for SEO reasons.

  3. 3

    Great post!

    What font did you use for the comments :-)

  4. 4

    Just curious, what font are you using for the comments in your images?

  5. 5

    For some reason I dont really trust html tidy used it for the first time this weekend though. The whole automated thing sorta freaks me out.

    And #2 that’s new to me thanks a lot.

    Awesome article

  6. 6

    “Our code doesn’t use any tables for layout anyway (nice!)”
    Nice…but…tables do allow us to center blocks on the screen very easily.

  7. 7

    Cool… easy and well explained.

  8. 8

    Regarding the font, you’ll love this, it’s a freebie!


    Thanks for having me, Smashing Magazine =)

  9. 9

    really nice and usefull tips. thank you interweb! :)

  10. 10

    I’ve given up on the Strict DOCTYPE. I used to be its biggest advocate, but it has become less and less viable to me. The reason: user-generated content. We’re well into Web 2.0 now, whatever that means. It’s the era of interaction. I can control my code and validate it and make it semantically perfect… but the minute a user types an ampersand into a comment box, the whole thing explodes. Not to mention mismatched, unclosed, or deprecated HTML tags.

    I suppose if I got paid more I could bother to parse everything and convert characters to entities and figure out what to do with user-supplied HTML. That’s too big of a job to be feasible for me — I can’t anticipate every possible thing a user might type. With the Strict DOCTYPE, all it takes is one syntax error and the entire page fails most ungracefully. I can’t afford to let that happen on a modern dynamic site. Better to go with a Transitional DOCTYPE and let quirks mode deal with irregularities. Practicality wins out.

  11. 11

    great for beginners

  12. 12

    Great tips, Chris.

  13. 13

    Something really worth reading and extremely useful..as always Smashing Mag!

    I love you guys.

  14. 14

    Good post!
    oh, and the link “W3 MARKUP” in the footer is ugly dead..

  15. 15

    Close, but no cigar.
    It is a right step in the right direction, but… (there is always a but)…
    1) Since there should be only one <h1> in a page it does not need an id and if you need to style the <h1> in a different way in different pages you can use the body id to identify the <h1> with body#blogLayout h1{color:#f00}.
    2) in most designs the <div id="topNav"> is needless and the <ul> under it can be the hook for the CSS, on the other hand, if you do need the <div id="topNav"> then you probably do not need the id in <ul id="bigBarNavigation">
    3) the name “topNav”, “bigBarNavigation”, “sidebar” and “footer” are problematic. The id of an element should describe its content not its position (top, side, foot) or style (big). Navigation is a good name, you can add mainNavigation, secondaryNavigation and copy as ids, now if you will change (with CSS) the position and/or style of the element the id will still describe its content.

  16. 16

    Good Things! :D haha :)

  17. 17

    Much thanks to Chris Coyier, the handwritten font is Loved by the King (a great $5 font by Kimberly Geswein).

  18. 18

    Chris, great post. Really like the way you lay out the info, and explain in an easy to understand manner. Great stuff, nice work.

  19. 19

    Good article for Strict basic template building. Thanx

  20. 20

    With the Strict DOCTYPE, all it takes is one syntax error and the entire page fails most ungracefully.

    Only if you’re using an XHTML strict doctype and serving your page up as proper XHTML (mime type = application/xml+xhtml) with its more draconian error handling. And if you’re doing that then you’d need to be using content negotiation for IE anyway. XHTML served as text/html won’t fail badly and neither will HTML 4.0 pages. The pages might not validate, but they won’t fall apart. Sounds like you’re making things more difficult for yourself than they need to be.

    Since there should be only one <h1> in a page it does not need an id

    Not necessarily. You might use a h1 for the title of your site on the site’s home page but on internal pages use the h1 as the page title with the site’s title then being wrapped in a different tag. Rather than have two style rules for each different element, if you give the site title an ID, you only need to write the rule once. It also means that on internal pages that if you use a <p> or <div> for the site title that it won’t get confused with other similar elements in the header.

  21. 21

    So you guys do not draw tabular datas into tables?

  22. 22

    Great post Chris, thanks.

  23. 23

    I love clean code and whenever I develop anything I always make sure the code is readable and well commented. I find that it helps to have clean code to easily fix problems that may occur when the code is rendered.

    Great list of helpful tips there but don’t forget people that both javascript and css also need to be nice and clean too.

  24. 24

    Great article. Thanks.

  25. 25

    Great list, but I also disagree (somewhat) in regards to the naming conventions. “Sidebar” and “footer” have become so popular that we tend to forget that they are actually describing the style, or at least the layout more than they describe the content.

    Consider what content is going to go into those sections and name them accordingly. Try “secondary-content” or “supporting-information” or “calls-to-action” for “sidebar”, and “company-information” or “legal” for the footer.

    I’d also go so far as to say that “container”, another very popular class/id name, is also layout specific and should probably be replaced with the name of your website – div id=”www.mysite.com”.

  26. 26


    You should be sanitizing user input anyway so if a wayward & slips by you that is your fault. An ampersand is mos’ def’ a quite common replacement for and.

  27. 27

    Nice article Chris! I once was guilty of all these! But i’m improving thanks to you and other bloggers around the web!

    If you use php you can simply use the htmlspecialchars() function, which cleans all the special chars LOL

  28. 28

    Chris excellent article. You covered all the major points.

  29. 29

    Excellent. Thank you. I make many of these mistakes – (past tense}.

  30. 30

    Very weak. Strict still validates when using tables for layout. The difference is that in Strict you cannot declare css values as attributes


    I'm a div tag

  31. 31

    This was an excellent post. Well written, and very informative.

  32. 32

    Wow, nice blog – it doesn’t even encode my (x)html – let’s try this again:


    <div align="center">I'm a div tag</div>

  33. 33

    I actually disagree with a lot of the content. You know why people use tables to layout content? Because it’s intuitive, simple and self contained. While there’s a lot of merit in code isolation (particularly for re-use and robustness), there is little reason for many people to use CSS to layout their page.

    Another reason for code going directly into files is Dreamweaver and you know what – it works and people don’t care, in fact, why should they?

    I agree with points 3 and 11 on formatting code, but as another newsflash – people were doing this before blogs were around to tell them about it. In fact in my first year studying Computer Science at uni, I got marks for code style – formatting, indenting, comments. I’m also a fan of verbose variable names – take a look at Apple’s extensive design guidelines for more examples of that.

  34. 34

    The {text-transform: uppercase;} property works great for English text, but fails to transform foreign characters (such as ö -> Ö, å -> Å) for other languages.

  35. 35
  36. 36

    I disagree with #7, there is nothing wrong with the class “Red” if it is defined as { color: red; }. In that instance, it is the most descriptive it can be, and if you change your design, you wouldn’t change it to be defined differently, you would apply “Blue” as a class instead.

    As an ID name, I agree with you that Navigation or footer should be specific to what they are, but a class name is something that can be applied to many elements, and should define the class. What is the common denominator of every element of the class? Well, in that instance, every instance of the “Red” class will be red, so why is that a worse name than describing the content?

  37. 37

    @Lee… What is so intuitive about tons of spacer.gif graphics (you normally see ton of those when site is designed with tables)? Learn how to layout pages with CSS, and leave tables for tabular data. Just MHO.

  38. 38

    I was advocating “STRICT” XHTML until I hit the biggest snag – file upload in AJAX enabled websites – still requires an IFRAME which isn’t allowed in XHTML strict…. unfortunately the workaround – OBJECT – doesn’t offer the same functionality as IFRAME… in this one instance.!

  39. 39

    Nice article, good refresher for somebody who is coming back from a mini-vacation ;)

    I’ve seen more and more of these bad practices put into place. Especially ones like #6 & #7. Although, to add onto #7 I would prefer to name it based off the type of color it is – primary, highlight, shadows, etc in addition to what it is (subNav)

    Validating your markup is a bit, well, overrated. When some browsers *cough* IE *cough* still don’t display the page correctly, even when everything is valid – what’s the point of going the extra mile? Now, I do think that web pages need to be properly coded – like properly closing tags & attributes.

    P.S. – Did you ever look at SM’s css? “#leftcolumn”, “#footer .foologo” foo? Seriously?

  40. 40

    I’ve been doing these ever since i began, and i get all of my friends who are starting to codelike this aswell, it just looks soo much better.

    And i agree, that little green text does give a nice warm feeling :)

  41. 41

    Nice post! This will guide me even further in making web designs in the future!


  42. 42

    Completely disagree with 4, I’m getting very tired of sites loading without styles or JavaScript whenever there’s a glitch with the connection! The correct approach would be to keep the important code in the header (from a server side include) and use an external file for all the extras.

  43. 43

    Nitesh (Web Designer)

    November 12, 2008 10:07 pm

    Well explained.. cleared concepts of writing new html code… 10 out of 10 marks…

  44. 44

    Nice post! Thanks.

  45. 45

    It’s nice…….but very difficult to apply STRICT markup……when we are working on CMS’s…………end user doesn’t think about this..

    Well it’s nice post!


  46. 46

    I agree upon Strict but Transitional may be needed when e.g. using iframes (like Google map). It shall fade into the past when object finally renders properly in most browsers, but not today.. not today.

    And I believe 10. consists 5. (any validation points badly nested tags, right? – of course the rules should be applied while coding – it measures our skill and saves time – but if validation is mentioned I guess it serves a higher purpose than just pointing badly ended tags).

  47. 47

    HEALTH ADVISORY: “Non-acute Divitis can also be an advantage in the long term”

    Allow me to present a relatively weak but sound argument for the benefits of issue 6: Indeed, “Divitis” can result in a proliferation of div tags, and a lengthier HTML code. However, one long term benefit of the disease is the fact that the wrapping div can act as a great facilitator when using javascript frameworks (mootools, jquery, prototype).

    Having named divs wrapping interface elements (even if the div does not server any CSS purpose) can sometimes be a good thing. It will allow the developer to easily implement future JS framework goodness (slides, arbitrary selections, animation etc) without the need to re-edit the code or worry whether the ul element has defined dimensions, is absolutely or relatively positioned, IE’s hasLayout is applied etc, etc.

    Indeed, in the example presented, there’s no need to keep div id=”topNav” since if we need to refer to the li or a tags of the nested ul we can simply use $(‘bigBarNavigation’). However, if in the future we wanted to play around with the idea of a sliding or revealing menu, and if we assumed that topNav is a styled menu with display:inline or float:left li elements, it would be easier to apply the animation to the topNav div instead of the bigBarNavigation ul (despite the fact that it’s a block level element).

    Just my 2 cents…

  48. 48

    Great article! Back to basics.

  49. 49

    Basic but nice post.

  50. 50

    Thanks man, great article. Saved in my bookmarks…


↑ Back to top