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:
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:
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:
- Give the body element a class which is unique to the page.
- Use descendent selectors to match the element which needs tweaking.
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:
- Make sure container elements, for example
div and table
, are marked with an id or a class attribute. - Use decent selectors to match the element you want in the style sheet.
- Make sure class attributes indicate content rather than a style.
- Use the Galloway body class technique to make page specific tweaks.