Remember that anything you do can be superseded, and that your site must be adaptable to change.
Look good naked.
Content is king. Websites are no different to books in that they format text in a way that is pleasing, visually, to the reader, but if you remove the wrapper the site must still flow like a document should.
The best way to know you have got it right is once you've removed all the CSS - this way you can get the bare bones of your informational hierarchy, and if it all looks like everything has equal weight then it's been done wrong.
By using HTML elements for their semantic meaning, you're doing more than reducing the amount of divs you're using, you're creating meaning for your document. Search engines give more weight to pages that have the search term in the heading than in the body content. Screen readers give emphasis to headings, not because they appear larger, but because you have given them priority in the document.
<div class="heading">What I ate for breakfast</div>
<div class="paragraph">Cereal, orange juice, toast.</div>
Even though this works from a presentational perspective, it has far less meaning than this:
<h1>What I ate for breakfast</h1>
<p>Cereal, orange juice, toast.</p>
Being even stricter, you could break down what I ate for breakfast into an unordered list, but that can be considered overkill for this short example. The point is that by using HTML as description of your content, you're benefiting everyone - yourself for better search ranking and your readers using alternative methods to display the page.
Not everybody is the same.
Designing for the web is certainly not designing for print. You have to make your site look good for your readers, on whatever platform they decide to use - Mac OS X, Windows, Linux, iPhone, mobile, etc. Before the iPhone appeared, mobile browsers sucked. Most still do, and in these cases once you've written your semantically correct markup you will be able to restyle the site accordingly - after all CSS includes support for many different media, including but not limited to computer screen, projector, mobile, print, screen reader etc.
Not everyone's computer is the same either - colours can be different, fonts installed can be different, hey, they could be using IE6. Never make a user feel that the browser they have is inadequate with popup messages that say 'Your browser is out of date'. Instead adapt. Include wide ranging font families that cover the latest and greatest fonts mixed in with the commonly used ones lower down the tree. Enhance your site progressively, so you can have a great design in IE—and make it even better for those Safari/Firefox users with things like CSS3 multicolumn, or multiple background images.
Code sensibly.
Thirdly I just want to touch on CSS best practices. It is a mistake to think that you need to give everything an ID and a class in your HTML. Unless you are running a page that needs those IDs for javascript, you should always start without the classes and add them in later.
Make use of descendant selectors like p em { }
, child selectors p > em { }
and adjacent selectors p + em { }
to target specific elements. It's easy to predict patterns in how your documents are styled, and you should not need to create classes 'just because'. A good trick I use is the element + * { }
rule - it applies styles to anything that comes after a certain element and it's nifty for clearing floated elements.
I prefer to consolidate many common rules into one big rule, for example if I wanted a bunch of different elements red I'd use something like this:
blockquote, a, h3 { color:red; }
This is much better than giving each of these elements a class, and of course you can always override styles later on. This is the real beauty of css, that any general rule can be cancelled out with a specific one later on.
This turned out a little longer than I planned. To summarise - write great HTML that doesn't need divs (unless you have to for styling workarounds), plan your design to be cross browser bearing in mind all the differences for every user, and code minimally. There's many more selectors out there, and I only touched upon a few here - the point is to code without classes unless you really have to.