Maintainability, a.k.a. the CSS elephant
Now that even Slashdot has made the move to CSS it’s safe to say that the CSS advocacy battle is slowly being won. It’s time to talk about the elephant in the corner of the room: stylesheet maintainability.
The C in CSS stands for the Cascade—a complex but elegant set of rules governing which style rule has precedence in cases of conflict. Consider the following:
* { color: black; }
h2 { color: red; }
div#header h2 { color: green; }
h2.funky { color: orange; }
An h2 with class “funky” inside a div with id “header” matches all of the above rules—it’s up to the cascade to pick the most specific one. While the key element of this process is calculating specificity a number of other differences such as @import v.s. linked stylesheets also plays a part.
There’s one big problem: if you see an h2 in the source code, you need to have a pretty intimate knowledge of the stylesheets being applied (not to mention the cascade rules governing them) to work out which rules are in effect. It’s a far sight trickier than deciphering <font size="3" color="red">. If a page element isn’t displaying the way you want it to, tracking down the cause can be a nightmare.
What’s needed is a well understood set of techniques for writing maintainable stylesheets. I’m interested in collecting advice on this, especially from people who have tackled this problem in a situation where more than one person has to work on the same CSS code. I’m particularly interested in ideas on how to best split up a large set of rules over multiple stylesheets. If you have any tips, please post a comment, write it up on your own site, e-mail me or add it to the wiki page.
The maintainability of css is something that has been bugging me for about a year (maybe a bit longer). I think the problem as you pointed out comes from the cascade. Comments help, but, not much. I'm currently working with a style sheet, wrtten by some one else which is 1400 lines with a rule per line. It is incredibly dense and hard to follow, All the same using the web developers tool bar in fire fox makes it bearable. I think from a maintainability point of view the tool bar is not just a god send but absolutely fundamental.
An additional thing that improves maintainability is to create a page with all the styles used for the site explaining which classes and ids are used, a sort of style guide. This is very useful and what I did for the Unilever web site, and was a great help when I had to develop new pages for the site a year later. I think the style guide is the bases of a maintainable style sheet, but it takes a lot of time and must be carefully maintained. Add to this the css tool bar and well indenting commented code and I think we're on our way to something workable.
The last thing is to corral any hacks into a separate file and maybe partition layout from color. this can be good for simplify the creation of a print style sheet, although I'm still working on this and the idea is slowly evolving. I'm still not completely convinced by this but I think it might have potential.
Any way I think you are right to raise the point, although having just had to do some serious table hacking css is infinitely more maintainable than the alternative.
Marc
Marc Pacheco - 26th September 2005 20:18 - #
David Dorward - 26th September 2005 20:46 - #
Patrick Fitzgerald - 26th September 2005 21:42 - #
Simon Willison - 26th September 2005 22:06 - #
Reminds me of the recent discussion on mezzoblue about so-called css optimizers. Beyond merely removing whitespace, a cleverly written css optimizer can collapse redundant selectors and group rules according to pre-defined parameters. On the other hand, I find machine-optimized css tends to wreak havok with my natural inclination to organize stylesheets into chunks that control either spacially discreet page areas or thematically unified classes of action (typography, layout, etc.), which is already a duality of purpose that seems to pull my stylesheets into two opposing organizational schemas. In fact, the more heavily machine-optimized css code becomes, the more human-unreadable it becomes. Not sure of the value of this observation; I end up answering a simple question with a tangled conundrum. Thanks a lot, Simon.
A couple mentioned in the thread are
http://www.cssoptimiser.com/and
http://cdburnerxp.se/cssparse/css_optimiser.phpChris Feldmann - 26th September 2005 22:09 - #
I haven't put this into practise as I'm not yet working on any stylesheets that are *that* unmanageable - the biggest set of late was for fish4 and I tried separating them out into layout, type, colours, navigation and hacks (ie5 mac/win), but I actually find that a bit of a pain as there are too many files to make certain changes simple.
How about comment-grouping by element? Gather all the H tags together under an obvious comment, followed by all of the copy styles (P's, blockquotes etc). In reality it's unlikely that you will have more than a handful of any one element for any one site.
If that becomes ungainly you could then try grouping and splitting the different element types into files? Or, separating layout and copy display - one file handles where the content is positioned, another file handles how it looks in that position?
As I say, I'm just thinking aloud, I'm sure someone out there has a better solution!
Paul Bellamy - 26th September 2005 22:09 - #
Adam Kalsey - 26th September 2005 22:17 - #
Simon Willison - 26th September 2005 22:24 - #
I have to second the Chris Pedrick toolbar recommendation. I understand the "tools can only get you so far" thing, but I'd have gone mad from hidden cascade issues without it (it does a nice job of popping open a new window with all the rules that are applied, separated by file, with line numbers and shown in order of applicability).
In terms of making files easy to read and maintain, something I started at work is indenting CSS entries to make their inheritance and location clear. This makes files easier to scan and makes it immediately obvious if something is affected by the containers it is inside of. The best example of what I mean is probably at http://www.cbeyond.net/ -- stuff that applies to all pages and all browsers is in base.css. Stuff for better browsers is in dom.css. Then page-specific CSS (like things on the homepage) are in their own file. Additionally, pieces of the page that require a lot of rules (like the sidebar in the sublevel of that site) are put in their own stylesheet to keep things easier to find.
Tom Clancy - 26th September 2005 22:24 - #
Simon Willison - 26th September 2005 22:37 - #
This has been bugging me for a while. I invented my own indentation schema, but I don't think a language design problem could be solved by indentation.
Dimitri Glazkov - 26th September 2005 22:45 - #
Tom, what's the "*" in this bit do? SSC-CSS?
#contentArea { margin-bottom: 0; padding-right: 40px; w\idth: 484px; height: 430px; min-height: 470px; *height: 470px; }Jeremy Dunck - 26th September 2005 22:56 - #
One big shortcoming of CSS is the total lack of macros or at least variables. This is why "maintainable CSS" sounds like an oxymoron to most of us who had to work with (read: against) it on larger projects.
There is no way to assign variables or - heaven forbid - re-assign the pre-defined constants. Things were much simpler if we could to write stylesheets like this:
/* imaginary css stylesheet */
mypink = #ff00ff;
.hilite {
color: mypink;
}
.crazy {
color: mypink;
}
/* end */
For some reason W3 doesn't seem to think so (I'm not up to date with the drafts, though, maybe they're considering it?).
So what do we do?
Generelly we end up pre-generating the stylesheet using some external script from a template or just throw server side scripting like JSP or PHP at it.
None of these approaches is satisfying as portability suffers and it's always a hack.
Just my 2c...
PS: One big shortcoming of this comment form is the insane hostility against the user. You have never heard about "usability" have you?
"Don't forget to close all of your tags, check for correct nesting and ensure &s are replaced with &"
This is easily the most ridiculous instruction that I've ever read on a comment form.
Needless to say this was my last comment on this site. Only reason I wasted so much time on the markup is that I had written the text *before* you told me it has to be valid XHTML in order to not look like crap. Webmaster: Go to amazon.com and buy yourself "Web usability in 21 days - for completely retarded idiots" NOW.
moe - 26th September 2005 23:05 - #
http://www.mozilla.org/xpfe/goodcss.html
Robert Sayre - 26th September 2005 23:15 - #
Hehe, don't hold back moe, say what you really think! For what it's worth I completely agree with you - the comment form does suck. It's a hold over from an experiment I did a few years ago. Fixing it remains on my list.
You might be interested in Shaun Inman's CSS Server-side Constants, which does pretty much what you describe.
Simon Willison - 26th September 2005 23:16 - #
On the other hand, Simon, you might look on the valid-XHTML requirement as a simple way of keeping comment spam down :)
Jacob Kaplan-Moss - 26th September 2005 23:21 - #
I markup up semantically using a pseudo-stripe-syntax of css classes. Then I point to a CSS file at a standard location for the web page or web site. That file points to all the css files needed for the site.
Now that I think about it though, there could be a way to do some Apache-foo and serve a default css file for any particular filename.css not in the local file system. Then you could have each web page point to a scoped "webpagename.css" file for that page. If you don't override it, the server distributes the default stylesheet. If you override it, you can still call the default stylesheet using a pointer to anohter file that doesn't exist by convention (e.g. "default.css"). Possible?
P.S. Moe: Look at the ancient JSSS submission by Netscape to the W3C. Play with Netscape 4 to play with it. The type of maintainability you are suggesting was considered and rejected for being too complex for CSS's goals (IIRC).
Jimmy Cerra - 27th September 2005 00:00 - #
David Schontzler - 27th September 2005 00:45 - #
Kai Hendry - 27th September 2005 01:00 - #
jcartledge - 27th September 2005 01:37 - #
Programming languages have the same problem when it comes to Aspect Oriented Programming.
The ultimate proposed solution is an IDE that can tell you what aspects (as point-cuts) are applied to a code statement.
Extended to CSS, this would require an IDE that could tell you which styles are applied to a particular element and allow you to navigate back and forth.
eg:- From the CSS, what elements does this apply to in the document?
- From the document, what CSS rules apply to this element?
Chris Pederick's web developer toolbar solves part of the problem, but I want to be able to inspect and edit :)james mc parlane - 27th September 2005 03:38 - #
<selector css="pre"> <style> font-size: 1.1em; background: #f0f0f0; -moz-border-radius: 10px; padding: 1em; </style> <selector css="span"> <style> font-weight: bold; </style> </selector> </selector>I'm hoping this will make my life a little easier.james mc parlane - 27th September 2005 03:56 - #
I avoid hacks at all costs! I find that it's much nicer to return to or reuse parts of a stylesheet if things don't have interlocking workarounds and dependancies. This means that I either use another technique (ie. because of the historically wonky box model I am extremely reluctant to use padding except to zero it out), make sure the look degrades gracefully, and avoid designs which absolutely require hacks. Also very consistant use of structured and regular xhtml is important so that styles can be applied fearlessly. That probably gets wicked difficult as soon as any code goes beyond one person.
In terms of css code structure, I separate out general text styling (page font, headers, paragraph indentation, quotes and blockquotes, etc.), classes that apply to specific repeating parts of the page (dates, post titles), classes that apply for incedental styling (ie. a <p> that contains a poem), page layout, links, and link styling each into their own comment-block-thing. Kind of in that order. Also I group styling relating to children of a certain parent all together. It's pretty key to maintainablitiy that each of these groups stands nearly on its own.
Anything specific to only one page I put in <style> tags rather than adding a seperate stylesheet; also I will put styles specific to a directory in a seperate css file (guess that one's obvious).
The disclaimer would be that I haven't maintained any sites that aren't low-key, which have been personal, for a friend, or for academic classes, so I can simplify or just plain cut out any complications that bug me.
r.w. - 27th September 2005 04:42 - #
When I first read Zeldman's book I really resonated with the idea of separating content from structure, presentation and behavior. Maybe I'm preaching now. I approach CSS in a "write once, display many" manner. I want what I write to be extensible. If everything I do has to be re-written later when some aspect of the website changes, then I've failed at my job (only my personal website is like that because it's an ongoing petri dish experiement). Is that too strong?
What about anticipating future needs/forward compatibiity?
Dan - 27th September 2005 04:58 - #
Nate - 27th September 2005 05:33 - #
Simon, see a screenshot of my next-generation CSS editor for Nvu.
A checkbox allows to see in the XUL tree only the rules applied to the element holding the caret. Of course, you can modify these rules.
I think it solves pretty well your problem here :-)
Daniel Glazman - 27th September 2005 07:32 - #
Jeremy - 27th September 2005 09:43 - #
Stefan - 27th September 2005 11:11 - #
It's one of my little obsessions trying to find sites that detail best practice of maintaining style sheets. There aren't really very many. The best thing I have come across is filtering out hacks and then having seperate stylesheets for each browser you need a hack for - keeps you main style sheet nice and tidy and hopefully accounts for new browsers as well. This article is where I got the idea from http://www.informit.com/articles/article.asp?p=170 511&rl=1 - I might possibly have seen something on stopdesign as well.
In terms of making the styles easier to understand I am still in two minds - have a separate id for each page so then you can easily find styles related to a particular page and everything else is generic - much as is described on the wiki or have a separate stylesheet for each page?
who can say? I do the first one at the moment
Matthew Pollard - 27th September 2005 11:49 - #
Tom, what's the "*" in this bit do?
@Jeremy: it's a hack to show that information to IE-only. Since I built that site we've formalized the formatting a little more, trying to keep rules in the same order, mainly so important things like floats, absolute- or relative-positioning, and display: block or inline for elements you wouldn't expect are right at the top/ immediately apparent. In doing this, we indent the hacks one more tab so they catch the eye as an override. Because the hacks we use are fairly formalized now, they become easy to parse (e.g., "This element has the min-height set and a height set in IE to force min-height behavior.").
Tom Clancy - 27th September 2005 12:40 - #
Le Roux Bodenstein - 27th September 2005 14:34 - #
In trying to tackle css maintainability, I think you've just scratched the surface on the problem of maintainability any web coding.
As I have always said, css is not a language that lives in a vacuum. In fact, it can't do very much by itself -- it has to be used by other languages to accomplish anything worthwhile.
Furthermore, one can jump-into and out-of several different languages (i.e., css, html, php, perl,javascript, etc.) within the same document to make a single presentation. For example, please review my simple solution of how to use a php variable within a css style sheet:
http://sperling.com/examples/pcss/
Because of a diverse focus, all the web languages leave a lot to be desired when it comes to maintainability. I believe that this stems from the fact that all web languages trying to accomplish a single task, which is to deliver a presentation. Unfortunately, no one language does it all, but instead requires a symbiotic dependence on others. As such, it is going to be difficult to define a set of techniques for maintaining styesheets without considering the larger picture. It's like trying to maintain a specific custom from within a larger diverse society.
So, if your goal is to set a standard for maintainability, then this standard should also consider the maintainability problems, and solutions, of other interdependent web languages.
As for me, my "maintainability solution" has always been -- abundant documentation.
tedd
http://sperling.com
tedd - 27th September 2005 14:47 - #
Isn't that what XSL-FO is for?
I've seen this on other sites. Evolt used to demand you wrote your comments in HTML. I don't like it either, but I wouldn't get web rage over it. Instead I set up a set of common HTML start and end tags in Opera as notes. Now all I need to do is right-click and paste 'em in.
One last thing. Why do all the links here go through Google.com?
Chris Hester - 27th September 2005 15:24 - #
Simon Willison - 27th September 2005 16:13 - #
I've spent a lot of time trying to optimize css organization to give my coworkers, and those that have to work with my css a chance at understanding how to change something.
Here's how I generally seperate things:
Just my ¢2
Jason Beaird - 27th September 2005 16:29 - #
As for me, my "maintainability solution" has always been -- abundant documentation. Eww! :) The less need there is for documentation the better. Where there is documentation it should be concise, to the point. Otherwise when you end up with a rather big system you're documenation is so big to be of anyuse, and maintaining documentation becomes a big headache.
The links go through Google so that they don't give PageRank - antispam.
And yes, CSS maintainability is a pain - but so it HTML. That's why people wrote Server Side Includes and eventually PHP with complex templating systems. The size of site and users determine the solution - HTML with a sprinking of JS & PHP through to the all singing all dancing AJAX solution powered by PHP running on Oracle ;) I'm saying personally I believe the problem can be solved by the right production tool, depending on the problem. In many cases this is little more than plain SS. In more complex cases CSS, in the big site some production tool support, in the massive multi-contributor site you're looking at something bordering on custom.
Swannie - 27th September 2005 16:33 - #
This has been a big deal for me lately. I keep changing the strategy with every site I work on, but my current plan goes something like this:
Most of the clutter and confusing I get in my own stylesheets is with section-specific selectors that override defaults. By sandboxing section specific selectors, I can keep them straight. As a side benefit, it also encourages me to think harder about how specific a certain rule needs to be, since I have to decide which stylesheet to put it in. As pointed out in the Digital Web article, it's not the only way of breaking up styles, but some form of segregation has proven to be a Good Thing for me.
I've always just built stylesheets organically, putting things where they felt right and reorganizing every now and then. But I've had to go back and change enough sites that I built that way to start hating myself for it. So I'm getting strict with myself.
Wilson - 27th September 2005 17:22 - #
Samual Icky - 27th September 2005 18:50 - #
Samual: Shaun Inman has an answer. CSS-SSC.
Lanny Heidbreder - 27th September 2005 23:03 - #
Lanny Heidbreder - 27th September 2005 23:04 - #
Jason, this is exactly what you shouldn't do! What does 22pt mypink actually mean? Is it a warning? A note? What happens later on when you want to redesign, and suddenly you want a note to have a green background, with a special icon, but normal text?
Lach - 28th September 2005 06:41 - #
Dustin Diaz - 28th September 2005 06:54 - #
In the W3C's CSS Techniques for Web Content Accessibility Guidelines 1.0 it says in the first part "Use a minimal number of style sheets for your site". I think some of these approaches above may lead to a large number of stylesheets that each have to be loaded. Targetting individual pages can be done for instance by adding an ID to the body tag for each page. Also the less stylesheets, the less physical files you need to open to edit the site.
Chris Hester - 28th September 2005 09:37 - #
Chris, that quote is in service of the goal of consistent presentation across multiple pages by reducing the complexity of maintaining the style declarations. I think this consistency is a second-order effect of maintainable stylesheets, so this discussion isn't at all at cross-purposes to the spirit of that recommendation.
Jeremy Dunck - 28th September 2005 15:30 - #
Francois PLANQUE - 29th September 2005 15:53 - #
moe: I feel the pain. One solution would be a greasemonkey script to instantiate Midas or TinyMCE in this textarea
A quick Google found nothing, but I'm sure Simon could knock one up quickly ;-)
PS: since when has <b> been an illegal tag? I wanted to use presentation-level bolding, not to add semantics with <strong>. And no, I'm not typing <span> with CSS instead!
Peter Bowyer - 30th September 2005 11:36 - #
I applaud everyone for not immediately debating the relative merits of strong vs. b ;-)
Jeremy Dunck - 1st October 2005 00:13 - #
Reviewing posts on CSS-Discuss and other places, sometimes I am appalled how so many people have taken this powerful and elegant approach to design mechanics and turned it into something complex, turgid and painful.
The key to having maintainable stylesheets is having simple stylesheets -- and the key to having simple stylesheets is having sparse, stripped-to-the-bone structural code. If *what* is to be styled can be made simple and rational, then everything that follows...flows.
The company I currently work for recently bought a two screen Web app from SAP. The .css file it served up to IE was 300,000 bytes. (!!) Yes, SAP is famous for this kind of Web app stupidity but I have seen plenty of Web workers who may as well go back to tables and FONT tags for all the benefit and glory they get out of CSS.
The primary CSS file I currently maintain supports the entire presentational layer for about 15 apps. This .css file, including global print styles (printing data is important to clients) is about 20k and is often a bit more than half that, depending on screen requirements. I *do* organize my .css files in a certain way but when stylesheets are that small, organization is a secondary affair.
BrettBrett Merkey - 2nd October 2005 21:20 - #
Paul's comment from early on hits on something I've found very helpful:
I've found this separation handy, especially when working on a site along with content editors who use WYSIWYG apps that don't display more complex layouts correctly. It's a simple matter to disable the CSS file that handles layout - I've used a 'hide_layout' template variable in Dreamweaver - while editing the content, but still keep all the content area styles in place so the editors get a feel for what their content will look like.
Jason Tremblay - 4th October 2005 22:06 - #
I have like 15 different -- and quite small -- css files on my local machine. They are grouped by purpose like "comments", "forms", "layout" etc. I got them all open in TextEdit so if I want to change something regarding to comments styling, I can just select the "comments.css" file and make the changes. It's easier than scrolling down a big file, desperately trying to find the spot where the comment rules are.
For the live site, however, I copy all the files in one big stylesheet because having 15 single files has some major disadvantages, e.g. regarding total file size. 15kb for the single one vs. 32kb for the 15 files, because the min file size on the file system is so and so many clusters -- dunno if that affects the load times in the internet, though.
The hacks for IE are kept seperate from the main stylesheet in (at the moment) two files, one for IE6 and 5.5 and another one for IE5. They're imported via conditional comments, so that only IE sees them.
But them again, I'm only webdesigning (aside from ImageReady, that is ;)) for 10 months or so.
Oh, and don't take my site's current css as best example because I just finished it yesterday... still tweaking it.
Julian Stahnke - 9th October 2005 23:53 - #
Stoyan - 10th October 2005 05:35 - #
Mathieu 'p01' HENRI - 10th October 2005 09:14 - #
Derek - 10th October 2005 15:30 - #
What I find easiest is to strip as many classes and ids as possible from my html and use html elements consistently across the entire site. For instance, I use h4's as paragraph headings regardless of whether or not there are any h2's or h3's on the page. In this sense, I create a site driven heirarchy, rather than a document driven one. This allows for very simplistic style rules in the CSS. You can think of it as replacing classes/ids with elements(though I realize this may not be possible on sites with legacy CMS's, or sites that you do not have control over the html code).
The other thing I do (though it has already been mentioned above) is add a unique id to every page (whether it requires special styling or not). This way, I can refer to any element on that page by referring to the page itself (which makes it very easy to find rules in the css, which I group together by page) and overriding the general style for any particular element. It also means that it is dead simple to add rules for pages that currently have no styles defined; you don't have add a thing to the html. Using these techniques (and a few others) I find that I can define rules for an entire site (granted, a small to medium sized one) in 200 lines of CSS or less (usually less).
Mat - 11th October 2005 20:24 - #
Maintainable CSS needs predictable HTML I guess.
Normally I (re)define the general HTML elements and then try to define specific modules like a certain kind of table, text elements combo or navigation. These split normally well into different files in which a single class for the outermost element and child and other selectors on simple element names can style most needs.
At least in my experience so far only so many cross-module styles are needed for e.g. special kind of inline links, form elements or specific colors. They can be put in a cross-module stylesheet.
Wether combining all CSS files into one big one on the server or during deployment or even include like 10 different files into a single HTML is a matter of personal preference (1 big one will be quicker due to only 1 request which true but using the same 10 sheets on a lot of pages will then not make a big difference for most users as they will come out the browser cache).
As some people before I really think indentation makes a difference, as it makes clear which style belong together. So only a few remain to be actually checked if the page elements was split in modules.
Even for a big corporate site I worked on all the CSS together was not very long. If the design of a site is reasonable and sticks to a styleguide which even for big sites only has so many elements it is possible to define these page modules and group them so it is not too difficult to achieve a maintainable CSS.
So I think it is not really the CSS that is difficult but more the HTML and design which needs to be sorted out and looked into before writing the stylesheets
BTW, I find Schemas (or even large Java class hierachies) tend to be more complex to work with then stylesheets...
The question would be how are people writing complex XSLT stylesheets, large Java class hierarchies and e.g. including and redefining RelaxNG schematas and make these understandable and maintainable?
Chris - 14th November 2005 19:45 - #
sinan isufi - 9th December 2005 12:25 - #
- Type
- Layout
- Lists & Forms
- Tables
- Links
/* 1. 'Type */This way, it really doesn't matter how long your CSS document is, it's how quickly you can find the information you want.
Jake Rayson - 17th February 2006 10:16 - #