15 April 2012

Modular CSS? Some thoughts (2)

Click here for part 1

Semantic IDs and class names. It is common advice that ID and class names should be semantically meaningful, that is, they should reflect the content (e.g. "sidebar", "widget", "promoted") and not the styling ("greybox", "red"). Unfortunately, this is not always possible, especially when some HTML elements need to be introduced solely for formatting. Still, it is worth keeping this in mind and starting from a semantic name, and name e.g. a DIV to be put around all widgets "widgetwrap" and not "newborder", and the narrow column on the right "sidebar" and not "leftbar".

Start CSS selectors with a top-level element. Unless a CSS rule is intended to be general (formatting, for example, all links, STRONG elements, or all text), I've found starting the CSS selector with a top-level element very useful. This way, one can avoid most clashes and CSS specificity issues, as the scope of the rule will be limited to well-defined areas on the page. Ideally, start with the ID associated with the main area (see the relevant suggestion in the previous post), that is, the promo box in the sidebar should be referred to as "#sidebar .promo", not as only ".promo". This allows re-using the class name elsewhere without causing problems.

In other cases, when the element can appear in any area (for example, a widget in either the navigation bar or the sidebar), try to start with the topmost still meaningful class name. For example, links inside the bodies of these widgets should be referenced using ".widget .widgetbody a" instead of ".widgetbody a".

Be as specific as possible. This is a continuation of the previous suggestion. The idea is to list all applicable intermediary classes when referencing an element. Using the previous example, for obvious reasons, links in the bodies of widgets should be addressed using ".widget .widgetbody a" and not ".widget a", as that would target A elements in the headers as well.

Avoid mentioning the element type. And finally, I think an argument can be made for addressing elements using class names and IDs, not element types. (Again, this only applies to CSS rules that are not general.) There are two reasons for this. One is that if the element type is not mentioned in the CSS rule, then it becomes possible to switch, for example, from a DIV to a P, or from H2 to a DIV with minimal changes to the CSS (mostly all that is necessary is to undo the default styling of these elements). Such changes may be necessary for any reason, standard compliance, SEO, or cross-browser issues.

The other reason is that styling a class rather than an element makes it possible to use the same element in the same context without having to worry about over-reaching CSS rules. For example, if ".widget .widgethead a" is used to style that one A element in widget header that is the title of the widget, one runs into problems when trying to introduce another A element to implement, for example, an accessible close button. This problem could be avoided by adding a class to the original A element (it can be as simple as using "tl" for title), and using ".widget .widgetbody .tl" to style it.