Struggling for Competence

CSS Enlightenment

Descent selectors are the key to good CSS design. Descendent selectors let you select the element you want, without having to explicitly add a class to it. Using descent selectors avoids polluting the html with style specific class attributes. The Galloway body class technique is used to make page specific tweaks to the style, in a controlled manor.

To appreciate the full power of CSS check out CSS Zen Garden. The site contains a single page of html, which is rendered in radically different ways by selecting the style sheet. A few cool designs are:

retro theater
Retro Theater
css zen army
CSS Zen Army
the hall
The Hall
zen pool
Zen Pool

Looking at the html for Zen Garden is a Zen experience in itself. The html is clean, simple, and focussed on content. Where are all those crazy style elements that I have in my html? The mistake I'm making is to treat CSS as a style library:

Need a bold blue heading? Yep, I think I've got one of them...there it is:
.BigBlueText { color: #99f; font-size: 16px; }

No... that's not big enough. Time for BiggerBlueText.
.BiggerBlueText{ color: #99f; font-size: 22px; }

When you take the style library approach, each element which needs a style gets a class attribute which describes the style. Over time the style sheet becomes a huge blob of styles. Refactoring is scary...it's hard to tell what the impact of any clean up will be, and you potentially have to check the whole site.

How do the CSS Zen Masters avoid the style library pitfall? If you look carefully at the Zen Garden html it does contain id and class attributes, but they are limited to the container elements on the page, and they don't indicate any particular style. The CSS then uses decent selectors to match the required element.

As an example, consider the following web page structure:

typical web page layout

Div's are used to define the four regions, and are given an id's so that they can be identified:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<title>Css Demo</title>
		<link type="text/css" rel="stylesheet" href="CssDemo.css" />
	</head>
	<body class="css-demo">
	    <div id="header">
	        <p>header</p>
	    </div>
   	    <div id="content">
	        <p>content</p>
	    </div>
   	    <div id="sidebar">
  	        <p>sidebar</p>
	    </div>
   	    <div id="footer">
   	        <p>footer</p>
	    </div>
	</body>
</html>

Now, to style the <p> elements in the content and sidebar, use descent selectors:


body {
	width: 604px;
}
div {
	border: 1px solid black;	
}
#content {
	float: left;
	width: 400px;
}
#sidebar {
	float: right;
	width: 200px;	
}
#footer {
	clear: both;	
}
#content p {
	color: red;	
}
#sidebar p {
	color: blue;	
}

Page specific tweaks are the other difficulty with CSS. In the past the approach I have taken is to define a new class, and apply it directly to the element which needs to be changed. A better approach is the Galloway body class technique:

The nice thing with this approach is the CSS is very clear about what is the "main" style, and what is page specific. In his article Jon provides some master page code to automatically add a unique body class to the page. (It would be more natural to use an id to identify the body element, however in ASP.NET this is not possible because the engine will mangle the id for an element with runat="server").

Descendent selectors are the path to enlightenment in Cascading Style Sheets. To keep your CSS clean: