CSS Style Rule Management
The overall subject of CSS Rule Management is broad, but there are several key concepts that will follow almost any paradigm a designer chooses to follow. I'll be covering two broad, abstract concepts in this document, each of which contains several ideas that may be used separately, or in conjunction.
Getting well-rounded and easy to maintain CSS Style Rules has a lot to do with two things:
Multiple-Inheritance, and
Compartmentalization (no, I didn't make these terms up). The two abstract ideas, when applied to CSS rules, each plays its own separate role. I'll summerize each in theory, before we move on to looking at their implementations in practice:
Multiple-Inheritance
The term "Multiple-Inheritance" comes from object-oriented programming, where one object can inherit 'traits' from more than one element (usually a 'class'). Multiple-Inheritance appears in CSS indirectly when it is applied to the
Document Tree (and the properties that are inherited by the rules derived from it), and directly due to the fact that multiple rules can apply to a single element. To be clear, I'm using the term "Multiple-Inheritance" as an abstract to encapsulate an idea, the term "Multiple-Inheritance" can mean different things when it relates to CSS.
I'll be more specific about what I mean in the context of this document; Multiple-Inheritance relies on two basic CSS features:
First, an element can be selected by more than one rule, and all style rules that select it will apply to it. For example, if you styled the
P element and then created a class and styled a
P element with that class, then that
P element is already selected by two separate CSS rules, and both will apply to it.
The second feature is that elements can inherit different properties from different ancestors. For example, you may have assigned a
background-color property to your
BODY element, and then a
font-family property to a
DIV element within the document. There may be some text that resides within a
P element, that resides within a
DIV element somewhere on the document. Unless something has overridden any of those properties along the way, that text will inherit both the
background-color value from the
BODY element, and the
font-family value from the
DIV, because it's within an element which is a descendant of both. Now let's see this in practice.
Let's say you've designed a page that will mainly contain a text document, which may or may not include some images. This page will have special paragraphs within it that will contain comments, that will be visually separated by their
background-color and slightly smaller
font-size.
First, let's say you style the main container of the document area (we'll say it's a
DIV element and give it an
id="doc_container"). You'll want to set its
font-family property, its
font-size, and its
background-color. All of these properties are inherited, so all of the descendant elements will also be effected by these assigned values.
Now, you have paragraphs within the document, and you'd like to add those nice
text-indent properties to each of them, by assigning the
text-indent property to the
P elements. Also, you'd like your Headings to be slightly larger, so you make the following rule:
h1, h2, h3, h4, h5 {font-size: 1.2em;}.
Now about those comment areas -- you make a class called
.comments, and set its
background-color to
#FFC. Also, remember that you wanted to reduce the size of the font within those comments, so you set the
font-size to
0.8em.
After all that, let's look at the code:
h1, h2, h3, h4, h5
{
font-size: 1.2em;
}
p
{
text-indent: 1em;
}
#doc_container
{
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
background-color: #FFF;
}
.comment
{
background-color:#FFD;
font-size: 0.8em;
}
I'll admit right off the bat that this is not a good example of CSS Rule design. Styling global Headings and Paragraphs is
not something anyone should be doing, unless it's an untied page that will only exist within its own world. But that's not the point I'm trying to make -- I was trying to get very few rules together to illustrate how multiple-inheritence can work for you, and save you a lot of coding if you think ahead.
Let's look at the coverage of these rules visually:
Look at the amount of different combinations that were created by those 4 Style Rules. Elements that were located at different positions around the document were effected by different rules, and inherited different properties, some of which were overridden (like the
background-color), while others were modified from the parent (like
font-size properties with
em values). There was no need for descendant rules.
Clearly, this is an extreme case, but the moral(s) of the story remain(s):
- Don't style what you can inherit.
- Don't override what you can modify using relative units (percentages (
%), Ems (em)).
- If you're going to be using certain properties across the entire page, set their values early on, higher up on the Document Tree, and let these values be inherited by multiple elements, until you really need to override them.
Obviously, nothing is set in stone. Your needs will eventually determine how you design your CSS Rules, but these are overall advisable broad guidelines. The point is to keep in mind that you
can make use of these traits/features, so that when it's prudent to use them, you can choose which ones are applicable to your situation, and implement them accordingly.
Now let's move on to the next abstract:
Compartmentalization
I'm using the term "Compartmentalization" so that I may derive the term "Compartment". Some prefer calling it encapsulation (can you guess what they derive?). It often helps to think of your document as being compartments within compartments, or boxes within compartments within a closet, whichever works. This has a lot to do with the Semantic Web Structure/Design, but it builds on it. The idea is that you designate zones (or compartments, or shoe boxes... you get the idea) within your document, and you decide what they're function is going to be. I don't mean specific, dedicated elements with one or two descendants that are styled under them (which is fine -- when you need to do that, do that), I mean thinking in a more macro sense. Instead of keeping up with the philosophical lecture, I'll get to the practical implementation. This time, I'll make it a real-world one.
We'll go over a design implementation of a news post. This can also be thought of as a blog entry or a forum post, the idea is that it will be repeating itself within the document quite a few times, and so it will need to utilize very little markup.
You'll need to have the entire picture in front of you, so I'll start with the markup, proceed with the rendered result, then the CSS that was used to style it, and then a diagram to illustrate the compartmentalization of the CSS rules that were used. Ready the scroll-wheel.
Here goes:
<div class="post">
<h3>Post Title <strong>Post Date</strong></h3>
<p>
News, Blog, or forum post content goes here...<br />
Another line that includes a <a href="#">Link</a>, and <a href="#">Another Link</a>.
<span class="signiture">-Author's Signiture</span>
</p>
</div>
The goal is to get from the above markup, to this:
Post Title Post Date
News, Blog or forum post content goes here...
Another line that includes a Link, and Another Link.
-Author's Signiture
We do so using the CSS below:
.post
{
width: 450px;
font-family: Georgia, "Times New Roman", Times, serif;
font-size: 14px;
color: #FFF;
background-color: #8081a6;
border: #4c4d70 solid 2px;
}
.post h3
{
margin: 0;
padding: 0.2em;
border-bottom: #4c4d70 solid 2px;
text-indent: 0.5em;
font-size: 1.2em;
background-color: #9797b7;
}
.post h3 strong
{
font-size: 0.7em;
color: #dedee8;
font-weight:normal;
font-style:normal;
padding-left: 0.5em;
}
.post p
{
margin: 0;
margin-top: 2px;
border-top: #4c4d70 dashed 1px;
padding-top: 0.4em;
padding-bottom: 0.4em;
padding-left: 1.5em;
padding-right: 1.5em;
}
.post p .signiture
{
display: block;
font-style:italic;
text-indent: 1em;
padding-top: 0.1em;
border-top: #b8b8ce dashed 1px;
margin-top: 0.7em;
}
.post p a:link, .post p a:visited
{
color:#FFFFFF;
font-weight:bold;
text-decoration:none;
}
.post p a:hover, .post p a:active
{
color:#FFFFFF;
font-weight:bold;
text-decoration:underline;
}
And finally, the diagram:
The first thing to notice is that there is only one class in the global namespace -- the
.post class. This way, while you may not be saving CSS "volume", you're not littering the namespace -- in other words, you're not creating many new names you'll have to remember to assign to individual elements, which may lead to confusion or name clashes along the way when you need to maintain your code down the line, and you don't remember exactly what you used each class for. Your CSS becomes more readable, because in a way, it becomes self-explanatory. When you see the CSS in conjunction with the markup of one post, you see what the author meant with relative ease, even if they didn't leave a handy diagram lying around.
I took the liberty of creating a second class, named
.signiture, because it was so specific. It would only take effect if it was found within a descendant of a
P element, which was a descendant of an element styled by the
.post class. This would not happen by accident. However, if you don't like assigning class attributes, and you'd rather really keep the markup to a minimum, you could always choose another tag and create a very specific selector for it. For example, instead of a
SPAN element styled by the
.signiture class, I could have used the
EM element, by using a selector like this:
.post p em. The downside of this is that someone looking over the CSS would be wondering "Um... So what's this for?", just like they might be doing when they look at the
.post p strong rule. It doesn't say in the CSS that the
.post p strong rule was meant to style the date of the post, it's just a style rule. This, of course, can easily be fixed using comments within the CSS, but remember that in most programming languages, it's better when the code explains itself, and the comments should be reserved to explaining the 'why', not the 'what' (and yes, CSS is a definition standard, not a programming language, but you get my meaning).
Another thing to notice is the use of the first idea expanded on in this document: Multiple-Inheritance. First, the
font-family property value was set in the
.post class, and left to be inherited by the rest of the elements below it. Second, the
font-size property value in the
.post class was set to an absolute value, while the rest of the
font-size properties were assigned relative values. This means that if you were to change the value of the
font-size property within the
.post class, the rest of the elements would scale accordingly. In fact, other properties were assigned relative values as well --
text-indent,
padding, and
margin were all assigned
em values, so the entire structure of the post would scale with the change of one absolute value. Actually, I only set the top-most value to an absolute one because I don't know where this post would be placed (that is, within which other element), but if I did, I'd probably set the value for the
font-size property of the
.post class to a relative value as well. This way, you could design your page so that by changing one or two values, by whatever means (JavaScript, browser settings, etc.), you could scale the design entirely.
A couple of things to note: If you were to place this markup within a page, you'd have to consider the use of the
H3 element. I chose it arbitrarily. You should keep Headings going in a linear fashion. That is, start with
H1s (usually you should only have one
H1 element within each document), followed by
H2 elements (notice I said 'followed', they don't have to be 'under' them in the overall
Document Tree), and so on. Just like you'd see in a book (especially in technical manuals). This has nothing to do with the standards, your code will validate just fine, but search engines will favor web sites with properly descending headings, so you'll be improving your SEO by doing so. Also, I added a
width property to the
.post class just to contain it visually within this document, obviously you'd use whatever means you choose to size it (you may choose to omit the
width property entirely).