tags:

views:

1851

answers:

13

We have a large ASP.Net website that has a single css stylesheet which is getting out of control.

I am thinking of using the the following strategy (taken from http://articles.techrepublic.com.com/5100-10878_11-5437796.html) which seems logical to me...

you might have one CSS file devoted to sitewide styles and separate CSS files for identifiable subsets of site pages (such as pages for a specific department or pages with a different layout style). For styles that are unique to a specific page, use a separate CSS file for each page (if there are too many styles to fit comfortably in the document header). You link or import the appropriate CSS files for each page, so that you load all the styles needed to display that page, but very few unnecessary styles that only appear on other pages.

Is this a good way to proceed? What are the alternatives? Thanks.

+12  A: 

I think the best option is to divide css in:

-layout.css

-content.css

Then if you need other more specific you can add more like an css for the ads: ads.css, or one css for a specific section.

I would also add ie.css for IE css hacks.

I would not speak about creating one css for only one page: the problem you can have if you use too many css, is that your page will have to do more requests to the server and this will slow your page. This is why i recommend you to implement an HttpHandler which will create a cache copy in only one file of the css you need at the moment. Look here: http://blog.madskristensen.dk/post/Combine-multiple-stylesheets-at-runtime.aspx

netadictos
I would add a print.css
Kaaviar
A: 

netadictos makes some good points and I would concur. It's easy to seek reasons for more Css but the benefits of keeping them lean are far greater in the longer term.

In addition, have you looked at using themes and skin files within asp.net? The combination of .css and .skin can dramatically reduce the overall size of your Css, which is marginally good for performance but very good for easier administration.

Some exceptions could be contained within the one css file but if things are radically different within the one then you may consider a separate css or even a separate site if they are that different. Obviously you might load different versions of the themes depending on which user it is. This is where you could have an explosion of Css files. That is, say you had a css for each page and then you wanted to have different for different clients on your site, then you'd be growing exponentially. This of course assumes you have this challenge.

dove
A: 

I wonder the same thing with regards to JavaScript files. If your site is highly dependent on Ajax to the point where almost every page requires some kind of custom Javascript then were do you stick it all?

Best practices oftern spout not having javascript in the page but as external files (as with css). But if you have a .js file per page then things will slowly get out of hand.

Owen
+5  A: 

What you can do is have lots of easy to manage, separate files for development, then smoosh them all together into one file and minify it on your live site.

This is a little more work to set up, but gives you the best of both worlds - easy to manage site + fast page loads.

Edit: Yahoo's YUI compressor seems to be the best minifier around. It can compress both CSS and Javascript.

Greg
Any tool suggestions on how to set this up RoBorg?
Richard Ev
+1  A: 

I would check out YUI CSS. Maybe not the answer you were looking for, but YUI CSS removes much of the hassle with different browsers etc...

Thomas Hansen
+1  A: 

Work out some simple rules that work for you (or your company).

Divide your CSS into separate files, such as:

layout.css
content.css
menu.css
typography.css

Decide what declarations will go in each file, for example, ensure:

font-weight, text-decoration, font-family

and

h1, h2, h3, h4, h5, h6, a, p, li

All reside in the typography CSS file. Decide what to do for edge cases, such as border properties on headers, padding and margins on text elemants (layout or typography).

If your sets of declarations are getting unwieldy, some people like to organise them alphabetically.

Indent your css, for example:

#logo h1 {text-indent: -9999px}
     #logo h1 a {display: block; width: 200px; height: 98px; backround...}

Comment your CSS, including references to other files if other rule for that specific selector reside there.

If you do divide you CSS into separate files, consider consolidating and compressing them into one file as part of your build & deployment process.

Make sure every developer is well aware of your standard for CSS.

Also, somewhat relevant, I've just been made aware of a Firefox plugin for finding unnecessary selectors. It's called Dust-Me Selectors.

Chris Hawes
A: 

I'm not sure about Windows equivalents, but on the Mac you can get CSSEdit, which allows you to add folders to CSS files and manage them like that. There's a good explanation of it in this article.

Philip Morton
+10  A: 

There are three principle methods used for breaking up stylesheets: property-based, structure-based, and hybrid. Which method you choose should most be based on workflow and personal preference.

Property-Based

The most basic, representative form of a property-based breakup would be to use two stylesheets: structure.css and style.css. The structure.css file would contain rules that only used properties like height, width, margin, padding, float, position, etc. This would effectively contain the "building blocks" necessary to arrange the elements of the page the way you want. The style.css file would contain rules with properties like background, font, color, text-decoration, etc. This effectively acts as a skin for the structure created in the other stylesheet.

Additional separation might include using a typography.css file, where you'd place all of your font properties. Or a colors.css file, where you'd place all of your color and background properties. Try not to go overboard because this method quickly becomes more trouble than it's worth.

Structure-Based

The structure-based method of breaking up stylesheets revolves around segregating rules based on what elements to which they apply. For example, you might see a masthead.css file for everything in the header, a body.css file for everything in the content area of the page, a sidebar.css file for everything in the sidebar, and a footer.css file for everything at the bottom of the page.

This method really helps when you have a site with lots of distinct sections on each page. It also helps minimize the number of rules found in each stylesheet. Unlike the property-based method, which tends to have a rule in each stylesheet for each element on the page, with this method you only have one rule in one stylesheet for any given element.

Hybrid

As you might expect, the hybrid method combines the best of both methods and it's my preferred choice. Here you create a structure.css file, just like in the property-based method, using only those properties that you need to create the basic layout. Then you create additional stylesheets like masthead.css, which skins the header; body.css, which skins the content; etc.

Other Considerations

One problem that plagues each of these methods is that by creating multiple stylesheets, you require that the client's browser fetches many files. This can have a negative effect on the user experience because most browsers will only make two concurrent requests to the same server. If you have seven stylesheets, that means adding potentially hundreds of milliseconds on the initial page load (this effect is lessened once the stylesheets have been cached, but you want to make a good first impression on those new visitors). It's for this reason that the CSS sprites technique was created. Breaking up your stylesheets may wipe out any gains made by using sprites.

The way around this is to compress your broken-up stylesheets back into one stylesheet when the user makes a page request.

To get the best of both worlds, consider using a CSS meta-language like Sass. This allows a CSS author to break one stylesheet into many while still only presenting one stylesheet to the browser. This adds a step to the CSS authoring workflow (though it could potentially be scripted to compile the Sass into CSS any time a Sass file is updated), but it can be worthwhile, especially when considering some of Sass' many other benefits.

Greg Hines
A: 

Global css files have caused me headaches before. CSS usually isn't namespaced, so if two different modules create a div with a class of "box", then the intent of one overwrites the other. Also, styles on the [a] tag, [p] tag and other basic tags (ie. styles not based on classes or id's) will wreck havoc on 3rd party controls as your global style sheet cascades onto an html component that was designed assuming no other css on the page. Inappropriate usage of text centering to center elements can lead to hard to debug global centering. So I favor multiple css files. I've seen css managers (http modules that merge css together at request time), but decided the extra http requests is well worth limiting the scope of the damage ill considered css can do to my application.

MatthewMartin
A: 

We use Ruby on Rails so we have a clear controller/action pair, we use this to reference both CSS classes and Javascript views.

Specifically, grab the name of the controller+action name and embed this as a ID in the view, put it on the body tag or your main content div.

<body id="users_list_body">

Where "users" is the name of the controller, "list" is the action. Then in your CSS you have rules likes

#users_list_body

So you can scope all of your specific CSS to that view. Of course, you also have more general CSS to handle overall styling. But having this ID defined more easily allows you to create specific CSS for individual pages (since a controller/action maps to a specific page).

You end up having rules like this

  #users_list_body table 
  #users_list_body table thead

Do the same for Javascript. So in the footer of every page you take your same controller/action name pair and embed it in a function call

 //javascript
 if(V.views.users_list) { V.views.user_list(); }

Then in your external Javascript you have something like

V = {};
V.views = {};
V.views.user_list = function() {
  //any code you want to run for the Users controller / List action..
  //jQuery or something
  $('#save_button').click({ ... });
}

with all of your Javascript code scoped to a specific function, it ends up being all encapsulated. You can then combine all of your Javascript files into one, compress it and then serve it up as one file and none of your logic will conflict. One page's JS will not conflict with any other page's JS because each page is scoped by its method name.

Cody Caughlan
A: 

Whatever your choice is, avoid using the @import directive.

Makes the browser load stylesheets sequentially, hence slowing down loading and rendering for your page.

Brian Clozel
+2  A: 

My solution, amidst plenty:

  • base.css / reset.css: your foundation {base layout, type, color} -- 100% reusability
  • helper.css: basic layout rules for modules as well as 'utility classes' {grid variations, forms, tables, etc} -- 90+% reusability
  • module.css: complex layout rules for modules {semantic modules like .post or .comment} - 75% reusability
  • layout.css: template-based rules {#hd, #bd, #ft, #homePage, etc.}- almost no reusability
  • color.css: all color rules, combined - 50% reusability
  • type.css: all type rules, combined - 75% reusability (text styling has less variations)
  • this separation also allows mobile and print versions for the layout sheets, all controlled by @import via the stylesheet I link to the html.

I am using this for a medium-sized site. For extra organization, I keep each sheet sectioned basically the same {wrapper, general, unique, etc}. I also tag my selectors and properties, as well as indent them in order of dependency inside the same selector group, so I know what rules I am referencing or extending. This framework allows nearly infinite expansion while keeping things organized, understandable, and reusable. I've had to refactor a 7000+ line master.css file a month ago, so this is a new system I am trying out. I've found that 100% content-semantic CSS isn't as scalable and easy to understand as a semantic/layout hybrid, since that's what CSS is used for anyway.

1.25-yr-later-edit: Another method which might be more relevant is to just use a good CSS text editor. I'm positive VS is crap for working with CSS, unless you happen upon some extensions. If you're on windows, give E Text Editor a shot, b/c it's a TextMate Windows port and has bundles designed for CSS and markup that give you much better syntax highlighting and autocompletion. What you then can do is organize, even a 8000-line stylesheet, into collapsible folds:

/** Start Module 1 */
[css]
/* End Module 1 **/

And use the symbol list to display for you a quick TOC on the fly with a query like Start or Module 1 It also indexes lines with /** these types of comments **/ (great for tagging areas) and all CSS selector chains. You should have no trouble working with single big files with E. Besides, unless you're progressively enhancing your CSS it's all going to get minified anyway. I would also make sure to indent your CSS to somewhat mimic the structure of DOM section it is referring to.

.container {}
    .container .inner {}
        .container .head {}
    .container .inner.alt {}

Otherwise, I agree with the '1 Base CSS and 1 Page/Section CSS` method, though it entirely depends on your business requirements.

hlfcoding
A: 

Here is what I do: I keep my stylesheets separate, somewhat along the lines of what others have suggested. However, I have a script that concatenates them together, minifies them, adds the headers, and then gzips them. The resulting file is then used as the stylesheet and if it goes beyond the expiration date, it automatically recompiles. I do this on a sitewide basis for all the common files and then also on a page specific basis for CSS that will only appear on that page. At the most, I will only ever have 2 CSS files called per page and they will be compressed, which minimizes download time and size and the number of page requests, but I will still have the benefit of separating them in whatever way makes sense to me. The same strategy can also be used for JavaScript.

VirtuosiMedia