There are several different approaches, each with its up- and downsides, and most of them are tied to a particular workflow.
In large teams, where the work is divided into 'graphics design', 'interaction design', 'slicing', 'front-end scripting', and 'back-end coding', each job performed by a different person, the CSS part is the job of the person who does the slicing, and because that person controls both the HTML and the CSS, they can do it pretty much as they like. Often, they use tools like Dreamweaver; this allows for WYSIWYG editing, but the resulting HTML/CSS is often kind of messy and hard to maintain - which is OK if the process demands setting the design in stone before writing any code: once handed to the coders, the design isn't going to change, so there is little point in spending extra effort on maintainability.
Often, however, teams are smaller, and the site needs to be more dynamic and more maintainable. In such a situation, it is important to write scalable and adaptable CSS. What I found works reasonably well is this:
- Start with a few 'reset' rules. You can use a pre-written general-purpose reset stylesheet (google for them, there are a bunch of good ones available on the net), or you can write some simple rules yourself. Some people don't believe in reset stylesheets; it's a matter of taste and philosophy really, so you may want to just overrule the default appearance of those elements that you don't like.
- Keep your HTML semantic, that is, write it so that it reflects the structure of your document, not the appearance. Load the HTML without any stylesheet at all. It doesn't have to look as intended yet, but it should present itself in a logical structure.
- Create the general style by writing rules matching on element names (
div
, dd
, input
, a
, ...) and, where needed, pseudo-elements / pseudo-classes (a:hover
, a:visited
, ...), and attribute selectors (you need those to distinguish between different types of inputs, e.g. input[type=text]
). Try them out on a generic piece of HTML, e.g. the output of http://loripsum.net/. This is going to be your default appearance; most of your site should look good with these rules alone.
- Now you have some site elements left that don't look as you want them yet. For those, add class names that describe, semantically, what the element is (or one aspect of what it is). Examples are things like
<input type="submit" class="default-button"/>
, <div class="validation-errors">
, etc. Don't use class names to describe presentational properties (<span class="red large">
, <div class="float-right">
): those tend to diverge from the actual rules over time, and then you end up with class float-right
being floated to the left or some such nonsense. Style those elements based on their class names. For example, if your default button should be larger, you'd use .default-button { font-size: larger; }
(or a percentage if you like those better).
- Avoid inline styles at all costs.
Develop on a sane browser (firefox, or anything webkit-based); once you have it all working, test it on at least Firefox, Webkit, and Opera. It's probably going to break on IE; use conditional comments to include extra stylesheets for various IE versions you have to support, adding whatever hacks you need to make it work.
As far as tools go; you don't really need more than a text editor and a browser to test in. Firebug or an equivalent document inspector plugin is a great help (Google Chrome / Chromium has a similar tool built into it), especially since it allows you to modify styles inside the browser - they won't persist, but you can quickly try out things to see what works.
On the server side, there are a few technologies that allow you to take shortcuts - basically, they take a stylesheet written in a superset of CSS, adding things like variables, nested rules, etc., and transform it into regular CSS before sending it to the browser. The cassius and lucius template languages (for Haskell) are nice examples, but solutions exist for many programming languages.