December 31st, 2007Customizing the order of your stylesheets
- Disbelief - “They couldn’t have possibly designed it this way; I must be missing something!”
- Anger – “This is ridiculous! What a waste of time and money!”
- Bargaining – “If I can get this to work the way I want, I promise I will love SharePoint forever.”
- Depression – “Maybe I’m not cut out for this SharePoint stuff. I should do something else. I wonder if there are any openings at Best Buy.”
- Acceptance – “Okay, I just won’t brand my site the way I wanted to do it.”
Essentially, Microsoft (in it’s infinite wisdom) has most of the styles, for any particular template, stored in the core.css.
The reality is that you may only want to make one minor change to the core.css and not have the whole thing be sent into the file system in a “customized” state. Or maybe you’re a purist (read: anal-retentive) and you just don’t like the idea of your core.css being stored on the file system.
Understanding that a value in a stylesheet takes precedence in the order it was applied (hence the name “cascading”) you might start to think:
CSSLink is used in order to load a specified stylesheet (using the DefaultUrl property). This will return all of the system stylesheets along with the path of the stylesheet you specified. All of this will be in order (yep, you guessed it) with the core.css sheet specified last.
The class that I built is rooted in the work of Michael Hofer and CleverWorkarounds.
This class creates a server control that is to be used in replace of CSSLink and is called EnhancedCssLink. I would read Michael Hofer’s blog on how you might add this class to your SharePoint site (build a .dll, mark it as safe in your web.config, deploy it to your SharePoint GAC or bin folder, etc.) If you can’t find out how to do it there, Google it man!
Michael Hofer’s class puts the core.css last in the order, which can be problematic. CleverWorkarounds improved on this idea by switching the core.css with a specified .css sheet. Ultimately, giving the specified stylesheet the highest priority. Cool!
I expanded on these two ideas by allowing the user to specify multiple stylesheets (separated by a comma). The DefaultCss property is now named “CSSPath”. Here’s an example on how to use it:
<PublishingEnhancements:EnhancedCssLink runat=”server” CSSPath=“../../_styles/master.css, ../../_styles/webparts.css”/>
This will now return the system stylesheets in the proper order with the specified stylesheets loaded last.
Finally, here is my code for the EnhancedCssLink class:
//Publishing Enhancements
namespace PublishingEnhancements
{
public class EnhancedCssLink : CssLink
{
public EnhancedCssLink() : base() { }
private string CSS;
public virtual string CSSPath
{
get
{
return CSS;
}
set
{
CSS = value;
}
}
protected override void Render(System.Web.UI.HtmlTextWriter output)
{
// Let base render the stylesheets
StringWriter sw = new StringWriter();
base.Render(new HtmlTextWriter(sw));
string renderedOutput = sw.ToString();
if (this.CSS == null) {
output.Write(renderedOutput);
}
else
{
// Split the styleSheets into an array
string[] styleSheets = renderedOutput.Split(new char[] { ‘\n’ }, StringSplitOptions.RemoveEmptyEntries);
if (styleSheets.Length == 0)
{
output.Write(renderedOutput);
}
else
// Render the system stylesheets, then render any specified stylesheets after that
{
string[] customStyleSheets = this.CSS.Split(new char[] { ‘,’ }, StringSplitOptions.RemoveEmptyEntries);
output.Write(string.Concat(styleSheets));
for (int i = 0; i < customStyleSheets.Length; i++)
{
output.Write(“<link rel=’stylesheet’ type=’text/css’ href=’” + customStyleSheets[i].ToString() + “‘ />”);
}
}
}
}
}
}
March 8th, 2008 at 8:56 pm
Tip: the best CSS editor ever made happens to be a Mac application: http://macrabbit.com/cssedit/