Thursday, February 01, 2007

Overriding Default Stylesheets in SharePoint 2007

Heather Solomon posted a detailed explanation on her site regarding the inheritance of styles in MOSS; specifically, the various methods for overriding CORE.CSS in master pages and site definitions. After defining the various options, Heather recommends the following for applying custom styles:

My recommendation is to store styles in the master page itself in a set of STYLE tags. If your master page design has variations for assorted subsites, store the CSS differences in a file and reference it via the Master Page settings, or if you need CSS changes for a single page, store it in an HTML file and reference it in a hidden Content Editor Web Part.

I wasn't at all comfortable with this approach, not so much because there is anything wrong with it (there isn't and Heather should get an award for incurring the brain damage required to sort through it all), but mostly because I don't like the idea of SharePoint forcing a default style onto my customized pages, thereby making me jump through hoops to correct a deficiency that never should have been there in the first place. I thought we'd been through this enough with 2003 and the design team would have learned their lesson but apparently not.

So after playing around with a few alternatives, I went old school and found the solution. Instead of using one of the new < SharePoint:CssRegistration / > tags to register your override style in the header, simply place it in a classic ASP < link > tag in the same location, like so:

< link rel="stylesheet" type="text/css" href="../../Style Library/en-us/Core Styles/core_override.css" / >

This procedure will circumvent whatever the parser is doing in the background to throw CORE.CSS into the mix at all the wrong places. The beauty of it is that CORE.CSS is called before your override stylesheet so you can inherit all the default styles and only override the styles you need. Be sure that the relative path is correct for the site definition you are working with. An alternative would be to place your override into the same folder as CORE.CSS and use a fixed path, which would make working with different site definitions much easier, as each master page can point to its own override file (this can also be done programmatically).

UPDATE: As Shane points out in his comments on this post, using the alternate style setting in the site collection settings IS a reliable method for overriding CORE.CSS; however, there are some things you should consider if you are using this approach:

1) The alternate CSS setting is GLOBAl for the site collection. This means that all pages, including _layout pages, will inherit this style. That may work for one implementation and not another; you might want different styles for the Admin pages (my term for all the pages found in _layouts), content pages, or subsites.

2) The Alternate CSS setting applies to all subsites in the collection, making it more difficult to assign those styles programatically. If you want to mix and match styles in your subsites you will have to find a method to override both CORE.CSS AND the alternate style.

3) The alternate setting must be done AFTER the site is provisioned. This obviously won't work for custom site definitions. A better approach would be to put the style in the master page settings, the PlaceHolderAdditionalPageHead, or, as I have suggested, use a <> tag.