TV version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer


Weblog Entry

Redundancy vs. Dependency

January 20, 2005

When coding larger sites, the CSS cascade is both friend and foe. The choice is yours: redundancy, or dependency?

CSS forces you to make a choice in your coding techniques, a choice that becomes more obvious the larger a site grows. As the amount of variance between different templates increases, you can go in one of two directions: you can either code for redundancy, or code for dependency.

I’ll give you some examples to illustrate what I’m talking about. First, redundancy. You’ve just created a series of forms across three pages. Each form has a couple of fields in common with the other forms, that you’d like to present in a similar way. The redundant method of coding each is to copy and paste the CSS, changing only the selector. For example:

.checkout #loginForm {margin: 5px; color: #333;}
.entrypage #loginForm {margin: 5px; color: #333;}
.cms #loginForm {margin: 5px; color: #333;}

Or slightly less redundant, the selectors can be combined with commas:

.checkout #loginForm,
 .entrypage #loginForm,
 .cms #loginForm {margin: 5px; color: #333;}

In the interest of code optimization, it can be even further condensed of course. You can style #loginForm generically, no matter what its parent might be:

#loginForm {margin: 5px; color: #333;}

Now, what’s happening here is that there’s an assumption driving the coding decision: all instances of #loginForm should have a 5 pixel margin, and be coloured dark grey. What if the form on the site’s entry page needs a slightly different margin to adjust for other surrounding elements? You’d have to rely on the cascade to pick up the initial styling, then call it out separately:

#loginForm {margin: 5px; color: #333;}
.entrypage #loginForm {margin: 2px 10px;}

At this point, the instance of #loginForm showing up on .entrypage is picking up the color value from the previous style rule, and now we’re moving firmly into the territory of the previously mentioned dependency. The second rule is relying on part of the styling of the first, so if you remove or modify the first, you change the formatting of the element in question.

It’s relatively easy to see what’s happening at a glance: first, your #loginForm is generically styled. Second, the generic style is overridden with a followup rule in certain instances. Easy.

But it gets more difficult if there’s, say, a third dependency on a padding value picked up from a new style rule. Not to mention the difficulty added if part of the styling shows up quite a bit further down in the style sheet from the initial rule, or even in a new style sheet altogether. And if you’re handing your CSS over to a client who hasn’t quite grasped the concept of the cascade, they won’t be able to make heads or tales of the dependencies.

To take it to an extreme, what if eight different style rules form the basis of the final style which eventually gets rendered on-screen, and changing any one of those prior rules might affect the element in question, but ripple across the site and change other elements unintentionally?

Let’s analyze this a little more closely, since it’s so important to understand. Say you’ve got the following rules combining to create the style for #loginForm on the site’s entry page, as above:

#loginForm {margin: 5px; color: #333;}
.sidebar #loginForm {padding: 5px; font-size: 0.9em;}
.entrypage .sidebar #loginForm {padding-left: 0;}

The final styling for the instance of #loginForm in question would then be: a margin of 5 pixels, dark grey text, a slightly smaller font size, and 5 pixels of padding on all sides except the left, which gets no padding. So now you want to go back and change the font size to match your body text, what do you do? The natural inclination is to modify the second line:

.sidebar #loginForm {padding: 5px; font-size: 1em;}

Except oh no wait, other elements were picking up the style from that particular rule and you just changed the font size for all occurances of #loginForm that sit inside the site’s sidebar, and you didn’t want to do that. You’re making the font size adjustment six months later though, so you don’t even remember the dependency. And chances are you won’t notice it immediately since you’re not liable to refresh pages other than the one you’re currently working on, so you just gave yourself an extra few minutes of debugging for whenever you actually spot the difference.

The easy fix, of course, is to just not modify the more general style rule and add a further override to the last line, like so:

.entrypage .sidebar #loginForm {padding-left: 0px; font-size: 1em;}

And if you follow that line of reasoning to its logical end, you’re back in the redundancy camp:

.checkout #loginForm {
 margin: 5px; color: #333; font-size: 0.9em; padding: 5px;
}
.entrypage #loginForm {
 margin: 2px 10px; color: #333; font-size: 1em; padding: 5px;
}
.cms #loginForm {
 margin: 5px; color: #333; font-size: 0.9em; padding: 3px 6px;
}

So it turns out there’s a spectrum; you can move in either direction, in varying degrees. More dependencies make for a sticky and tangled mess of logic that creates extra work when you come back to modify your creation. More redundancies are verbose and bandwidth intensive, and create extra work for the initial creation process.

I tend to favour redundancy in theory, but I code in plenty of dependencies in practice. Redundancy is easier to understand, cheap enough when the CSS is being cached properly, but inconvenient to build. Dependencies are far easier to create when coding, but during browser testing and later modifications to the style they cause no end of headaches. And when I’m working on a CSS file that I know will have to be understood by someone else, there’s all the more reason to keep it simple.


web says:
January 20, 01h

I find myself always applying an specific ID to the BODY tag, that way if I need to apply a specific rule on just one page I can just refer to the BODY#ID .class

Also helpfull when needing to put nav buttons on a solid state.

2 birds, 1 ID .. or something like that.

January 20, 01h

As I tend to write my CSS in sections, a section per page-type, I’ve never encountered this problem. It’s redundant… it’s not optimised for download speed, it’s optimised for easy reading and editing.

I suppose one could have develop ones CSS in stages. There would be a development stage, where the CSS is optimised for easy reading and editing. These CSS files would be the reference CSS files… any future edits are done to them, and them alone.

Before the CSS files go live, they are passed through a CSS optimiser. This could be automatic (then checked), or it could be entirely manual. If you’re doing it manually, you could use as much dependencies as you liked, so long as the rendering matched the master CSS for each page-type.

Here’s an automatic CSS optimiser (I don’t remember THAT header graphic :). Something like this could be used:
http://flumpcakes.co.uk/css/optimiser/

The live CSS files would be one way. You never make changes to them; the files are always replaced.

This would certainly solve a couple of problems (and create whole new ones). As I said, it’s just one possible way of doing things. It is certainly one I’ll consider for my next large project.

Dave S. says:
January 20, 01h

A few people have mentioned applying custom ids to the body element and tapping into page-specific style that way. It’s a good idea, but no real fix for the problem.

Go back to the examples in the article and assume each is using a body id, instead of the listed class. So “.checkout #loginForm” becomes “#checkout #loginForm” since the body is given an id of “checkout”.

The problem isn’t solved by that alone. In fact, that’s not doing anything differently than the listed example from the article — there’s a specific parent, and a generic child that may be pulling its style from a few different rules (that either involve the parent or don’t.)

You still run into dependencies if you’re not careful, because doing this is quite easy too:

.form {padding: 5px;}
#homepage .form {color: blue;}

See?

I think Eris has hit on something wise though, the idea that base style elements are okay being dependent, and redundancy can be applied to page-by-page styling.

In principle it’s the same as having page-specific external style sheets that contain extra, non-base styling for each page, you just have the option of centralizing all your style in one sheet. That makes a lot of sense to me.

Guillaume says:
January 20, 01h

I tend to favour dependency when I’m coding for myself because it seems to make more sense to me from a logical point of view. But dependency can seem a little messy when it’s not your creation and without comments. So when I’m coding for someone else, redundancy is appropriated since it’s easier to understand.

January 20, 02h

I definitely favor dependency, though the inheritance problem can be a pain (Firefox’s Web Developer Toolbar helps ease that pain). One thing I’ve started to move to is applying multiple classes to an element.

I’m glad someone else mentioned OOP already, so I don’t sound completely nuts. I’ve started to think of classes as … classes in an OOP language. They describe a set of common characteristics. An id is like an instantiation of the class, where your Person object gets its own name, age, whatever (e.g., this instance of the form overrides its shared border color because of an id).

The only trick is breaking the common characteristics into sensible classes so they can be applied together without trying to set the same styles. Unless you want to do that; I suppose the order of the class names would control which class wins out.

January 20, 03h

If I’m coding a project for me an no one else, I have a tendency to be redundant, more than dependent. As you said, it seems to make browser testing and final tweaks go much more smoothly.

Of course, it drives my boss nuts because he’s a stickler for code-optimization. So, in practice, I often end up being redundant, and then going back at the end of the project and optimizing the code, often building in dependancies.

Great article, Dave!

January 20, 04h

Does anyone know of a resource that will help me create good forms? Not just accessible forms but good looking forms for more than just a comment form.

There seems to be a lot of information on CSS layout, individual form element styles, accessible forms, but not form style.

For instance the comment form on this page has labels to the left of the first three input elements but the comments label is on top of the textarea.

What’s a good format for a simple name and address form? How about telephone numbers?

January 20, 04h

I do not think the questions should be to write with redundancy vs dependency - but “is it good business to make so many exceptions and variations”.

Consider something you design for print - having a lot of different styling, font sizes and margins really only makes the page messy.

So instead of styling form elements differently from page to page and from location to location - consider using single design for all.

What you will get is consistency in design and coding - which impoves usability for all.

January 20, 07h

I hate to bandy semantics on a post that has some very good points, but what you’re discussing is not, repeat NOT, inheritance. It’s the cascade.

Inheritance is the mechanism by which values are passed from an element to its children, and from them to their children, and so on. Period.

When two rules apply to an element, and there are conflicting declarations in those rules, then the process of choosing which value wins is the cascade at work. (The foundation of making that particular choice is specificity.)

See http://www.w3.org/TR/css21/cascade.html#cascading-order for more details.

January 20, 10h

I’m relatively new to the whole CSS thing, but even just in coding my homepage and a simple recipe db, I’ve already run into this dilemma.

Ultimately, the more everything can match to common templates, the better. A login form is really just a general form… with some differences. So style ‘forms’ with the consistent attributes such as colour, and then add a single layer of redundent rules later that override where necessary.

Or maybe maximum two: One that overrides the “.form” rules for “.form .login”, and then any final tweaks can be applied via the id, so you’ve got the second dependent layer styled as “.form #loginsidebar”. It means you wrap two divs around around your form, but I don’t think that’s the end of the world.

Mike P. says:
January 20, 10h

Nice post Dave. I find that achieving the balance between the two can be challenging.

By Buidling CSS with a consistent structure (ie, how you lay out your style sheet(s)) and good commenting often always helps me out of a mess later.

January 20, 10h

I tend to favor dependency over redundancy, it seems to make more sense to me from a logical point of view, not to mention optimization. That could be the object-oriented, computer science part of me talking though.

I tend to put my basic form styling in the main stylesheet, then if I need to customize a particular page in any further way I would give the page body an ID, then drive rules to that page with selectors. Kinda like your example above, except with ID’s instead of classes.

Why would a particular page have a custom class (as in your examples) instead of an ID anyway?

body#special-page fieldset{…}
-or-
.special-page fieldset{…}

I don’t know, maybe I’m just being picky.

Mike D. says:
January 20, 10h

One thing dependency does is force you to document your project a little better. If you have styles which will change all sorts of things throughout the site, you <em>must</em> document every single dependency to avoid changing things unexpectedly. This is especially important if you are passing the site off to either the client or another firm. Without documentation, things can get bad quickly.

January 20, 10h

I mostly tend to favour redundancy over dependency. I tend to ask myself a couple of questions while working on the stylesheet. Is this style open for changes in the future? Is this style related to another style?

If it’s open for changes, I try to build it in a redundant way first. After a couple of revisions for that particular section and I have come to the point of finalizing it, I’ll look if I can optimize it.

If it’s related to another style, dependency might be my choice. If it isn’t, I favour redundancy no matter what. Often cases like these are only a small bit of the stylesheet, so, initially, to make my life a whole lot less of a hassle, I’ll write a bit more than really needed.

I’ve always considered relying on dependency too much as creating a CSS class for 5px padding, 10px padding and 20px along with similar classes for margin. Sure, you could then refer a wide range of classes, but think about it for a second. Are you sure you’re not destroying the flexibility CSS initially gives you? Are you sure a single change somewhere doesn’t spawn 10 other changes?

I constantly answer those questions while working on something and with every case the answer could be different. For me personally, the answers are mostly in favour of redundancy.

January 20, 11h

Thanks for the post Dave. I wrestle with this every time I am writing css. I often find myself looking at a stylesheet I had written and thinking that it could be a lot cleaner and more efficient but opting not to touch it in order to preserve future understanding of what I had written. That, and secretely thinking: “I hope no one ends up looking at this stylesheet…”.

I am a pretty big proponent of comments, though more for myself than other people, which can be extremely helpful when I foresee a sticky situation in the future or something tricky intially that might leave my head when the time comes to look at it again.

But again, thanks. I can’t really speak for the rest of the readers out there, but I value posts like this a lot. It is reassuring to know that even a “guru” wrestles with something like this which could be percieved as having a simple, but unknown, solution.

Jason says:
January 20, 11h

It’s funny how much you hit the nail on the head with this post Dave! I am currently involved in a coding project that revolved around achieving such a balance between both.

Having encountered this CSS dilemma in the past, especially the client confusion part, we decided to plan how this project would layout exactly, from the get-go. We storyboarded the flow of the entire site, and everywhere where an element would go we brainstormed the most effective (and semantic) use of its being marked up and styled. Div blocks were cut out of the Photoshop comps and were logically named. Unordered lists, it was decided, would only be used in the footer, for example. Paragraph tags would only occur within #content div, etc. Nothing was left out of consderation.

Coming to the end of this project now, I realize that this painstaking planning up front with consistent naming, logical ID’ing, and well-considered decisions about markup has reduced the CSS bloat, greatly improved the reliance of the cascade, and has allowed for a more logical editing for future maintenance. In other words, our client will not have to have a Zen Garden submission to know how to manage their CSS file.

For most, this amount of precious time spent planning like this would not be conducive for a client’s budget. However, when you really take the time up front to make these hard choices, it really makes everything run much smoother in the end. Unfortunately, it is all too easy to just jump right in, hit the ground running with your design, and find yourself and your design breaking every time you touch your CSS file.

Rob says:
January 20, 11h

Some very good points you’ve made. I’ve grappled with the same issues and usually end up taking the redundant approach. Even if I attempt to start out creating appropriate dependencies it seems that there’s always that exception where you need to override a specific attribute.

When creating dependencies I try to make things easier by grouping like elements together. But then of course if you group your h1, h2, h3 and other block level element styles together and then all of your #sidebar styles together, where do you override the h2 for your #sidebar?

Either way you’re well on your way to that tangled mess you spoke of. Personally, I prefer to take care in creating clean, lightweight CSS so that if its necessary to have some redundancy for the sake of clarity I’m not taking a huge bandwidth hit.

January 20, 11h

The exact same issue is present in object oriented programming too. In OO, though, there’s no choice… it’s all for dependency, but in the idea of a proper architecture. I’d say, the same can apply here… a proper inheritance structure should be able to “take it”.

Eris says:
January 20, 11h

The more I experiment and code, I’ve found myself taking a hybrid approach with this. On most of my base style, it’d dependancy and with elements that are page or object specific, it’s redundancy. It works for me because there’s less of a chance that my base file is going to change whereas my specifics seem to be in a constant state of alteration.

Well written Dave, thanks!

January 20, 12h

If you want to document your css a lot without bloating the download, you can make it a style.css.php file on your server, and add a quick mod_rewrite rule that points anything .css to .css.php

Then your comments are just:

<? /*
Not the most elegant solution, but if documentation is a must, and bandwidth is at a premium, it’s an option.
*/ ?>

To the client, it looks like a bald CSS file, but it’s secretly got comments that are stripped out every time it downloads.

Mike says:
January 20, 12h

Good article - I just came off a huge project that was my first experience with this really becoming an issue. The forms of the site were all built in a Java/XML pipeline and I really had very little control over classing and IDs.

To make it worse, I had to start styling the site before I was too aware of exactly what the scope was.

3/4 of the way through I ended up removing a lot of redundancies and exchanging them for dependencies as the CSS files got too huge and started to bug out Internet Explorer.

The moral of the story is: Know your scope; planning your selectors in advance gives you a huge advantage later, much like the OO programmer who uses UML to figure out his classes.

marko says:
January 21, 03h

Everyone has his own practices, here’s mine if you care… if the CSS is surely going to be re-worked later by me or the colleague, i cascade selectors from the topmost element with an ID (for example BODY)—i found that DOM-like approach and extensive commenting (which includes something like /* IE this is for you : ) */) make things a lot easier.

January 21, 03h

Answering comment #33 by Justin Perkins:

Take the time to read how a compressor works and you’ll understand why gzip will remove redundancy. That’s what every lossless compressor does.

By the way, I have never said you can develop bloated code and be forgiven for that thanks to gzip. I just say many times optimizing code to have a small size takes so much time and it’s soooo messy when debugging it does not pay the pain or the bandwidth.

chuck says:
January 21, 04h

a really good topic here, and you explained everything very plainly, Dave -thanks

for me, dependency is the thing about CSS that has been the hardest to grasp … I usually tend to err on the side of redundancy, but I always have this feeling that there’s a more efficient way to do it …

this post will be bookmarked for me for a long time :) thanks

January 21, 04h

Dave,
you are describing exactly the problem I am facing these days. In the past I had always coded smaller Websites which were maintained by myself with Dreamweaver. But now I am doing a large Website and code the CSS for a CMS-application. So now all the parts of the website have to be a small universe for themself. Having coded now for years with the cascade and inheriting code (to write leaner CSS-files) I now face a different kind of coding where I prefer to put an extra DIV around a chunk of text. In the days before I wouldn’t, but then I had the control.

So, having said that, I think both ways of coding are correct, it simply depends on the complexity of the application.

Greetings from Germany.
Jens Grochtdreis

January 21, 05h

I can’t see the point in favouring dependency over redundancy.

Code with redundancy is almost always easier to implement and debug, so the only point for dependency would be size.

Say your CSS stylesheet with plenty of dependencies would be 5 KB. Now, how much would it be if you favour redundancy? 6 KB? 7 KB? Nowadays most of the people have at least a 56Kbps connection or broadband, so 1 or 2 KB more is almost nothing. Heck, even 5 KB more would be just a second more!

Indeed, if you want to care about size, you’d better enable gzip compression in your web server and save lots of bandwith. Most browsers are already gzip-enabled.

Ben says:
January 21, 07h

I tend toward combining classes for when you need to alter genericly styled elements.

As an example, if you want a form button to trail the form element, (such as on a single line form), adding the class “trail” to its existing class can alter it enough without building up complex dependancies and associated problems.

This also works well when you need a longer form element, such as for a URL/email address. Why create a complex inheritance when you can combine tmodify the existing one with a new class, “long” to achieve the same?

(You can use more than one class within an element by seperating them by a space).

28
Isaac Lin says:
January 21, 09h

In some cases, multiple classes could be used to decouple one set of characteristics from another. For example, one page on your web site (or one section within a page) might feature a different colour scheme than another. You could introduce two classes to define the two different colour schemes, and use whichever one was appropriate in each case.

This will only work, however, in cases where the set of properties you need to switch between are truly independent of all the other properties.

January 21, 09h

In regards to Pau Garcia’s comment, bandwidth concerns are a reality, not a relic from the olden days. A high traffic site sees hundreds of thousands of visitors a month (probably more). When you take a small amount of savings in file size and multiply that by the number of monthy visitors you’re suddenly talking about gigabytes of data consuming bandwidth when it could be conserved.

File download time is hardly the primary reason behind reducing file size, imo.

30
Isaac Lin says:
January 21, 09h

Sorry, for some reason I missed comment 26, which says basically the same thing as what I said.

January 21, 09h

This is why theres a marked difference between preaching about web standards, and actually providing solutions that use them.

Mike D. says:
January 21, 09h

Holy crap, Tom Clancy reads this blog???

January 21, 10h

Answering comment #28 by Justin Perkins:

If you want to truly save bandwidth, enable gzip. You will save not only in CSS, but in almost every object your server sends (and of course in CSS, because gzip compression will remove redundancy)

January 21, 12h

Bandwidth concerns are not solved by enabling gzip compression. Sure it helps greatly, but to think that you can make bloated HTML, CSS, Javascript, etc.. just because of gzip is quite short-sighted. Maybe in personal web environments where bandwidth isn’t of great concern, due to low volume of traffic, you can create comment rich CSS and nicely formatted Javascript. In professional web applications *everything* should be optimized as much as possible.

Lost visitors = lost customers = lost revenue = high stress for the web developer

File optimization certainly is one place where I can reduce monthly bandwidth usage (lower cost for business) and decrease download times. I don’t see the arguement against such methodology.

“…because gzip compression will remove redundancy)”

Possibly you are confused as to what either gzip does or what this topic was originally about, but gzip compression will not alter your CSS file in anyway. Enabling gzip does not magically remove your redundant rules.

January 21, 12h

I’ve had the unfortunate experience of writign some pretty nasty CSS and it’s come from this very problem. It definately is a dilemma if you don’t really put a lot of thought into the initial design of both the site layout and the structure of the CSS.

36
Moirin Tierce says:
January 22, 01h

Dependency really floats my boat for the most part. Oddly, I find it easier to edit when everything’s dependent on a master set of styles. It makes more sense in the end if you *know* what changes everything, and what changes one thing (inline or page-specific styles). Redundant CSS requires you to edit specific rules every time you want to change what should be a master rule, kind of defeating the purpose of the cascade, which the way I see it is to allow you to modify only what must be modified and let previous rules handle the rest. Generally ease in debugging follows logical coding. The only difficulty with Dependency is when you can’t find what rules are already applied; but then it helps to have tools like “View Style Information” on the Web Developer Toolbar for Firefox. Besides, when part of your CSS is generated from Perl and you modify things far away from your XHTML files it’s not easy to be redundant if you wanted to.

January 22, 08h

I read yours too, Mike, but I’ve got some disappointing news for you.

January 23, 02h

Redundancy is the way to go for me. I just can’t handle thinking about the cascading effect of a change somewhere that will bring about changes in 50 other places