Demystifying SharePoint CSS Links

There seems to be a lot of confusing, incomplete, or incorrect information (some of it from yours truly) out there about the choices available to you when the time comes to create your own styles or override existing ones so I thought I should shed a little light on the subject and talk about the Web Controls that actually emit said <Link> elements.

SharePoint:CssLink and CssRegistration

Have a look at the default.master page in the GLOBAL site definition (12TemplateGlobal). You’ll see a control named SharePoint:CssLink.

<HEAD runat="server">
    <META Name="GENERATOR" Content="Microsoft SharePoint">
    <META Name="progid" Content="SharePoint.WebPartPage.Document">
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    <META HTTP-EQUIV="Expires" content="0">
    <SharePoint:RobotsMetaTag runat="server"/>
    <Title ID=onetidTitle><asp:ContentPlaceHolder id=PlaceHolderPageTitle runat="server"/></Title>
    <SharePoint:CssLink runat="server"/>
    <SharePoint:Theme runat="server"/>
    <SharePoint:ScriptLink language="javascript" name="core.js" Defer="true" runat="server" />
    <SharePoint:CustomJSUrl runat="server" />
    <SharePoint:SoapDiscoveryLink runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderAdditionalPageHead" runat="server"/>
    <SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true"/>
</HEAD>

The CssLink Web Control renders <LINK> elements in this order:

  1. The primary CSS file (core.css)
  2. An optional CSS file specified by the control’s DefaultUrl property
  3. The value of the site definition’s AlternateCSS attribute if one exists. (If you are using the MOSS publishing features, you can also set this property for a single site by using the Site Master Page Settings page.)

Note that the AlternateCSS attribute affects every page in the site, even the application pages.

If you examine any of the master pages included in either of the MOSS publishing site definitions, you will see another control, SharePoint:CssRegistration.

For example, the following code comes from OrangeSingleLevel.master:

<Sharepoint:CssLink runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/~language/Core Styles/SingleLevel.css%>" runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/controls.css %>" runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/zz1_orange.css%>" runat="server"/>

The CssRegistration control adds each of the style sheets to an internal collection in the SPContext and the CssLink renders each of them in alphabetical order before rendering the primary, default, and alternate CSS links. If you want one of them to appear after core.css, set the DefaultUrl property of CssLink.

So, if you want to ensure that zz1_orange.css appears after core.css, you would change the above to match the following:

<Sharepoint:CssLink runat="server" DefaultUrl="<% $SPUrl:~SiteCollection/Style Library/zz1_orange.css%>"/>
<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/~language/Core Styles/SingleLevel.css%>" runat="server"/>
<SharePoint:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/controls.css %>" runat="server"/>

It’s very easy to get confused by this because the CssRegistration controls are after CssLink, but they don’t render the links, CssLink does!

One advantage that the publishing definitions have over the WSS default.master is the $SPUrl expression that allows dynamic creation of the URL for sites under the root web that use the root web’s master pages. Unfortunately, while CssRegistration is part of the core Microsoft.SharePoint.dll, $SPUrl requires the publishing features of MOSS.

Theme

On either of these master pages, somewhere under SharePoint:CssLink is SharePoint:Theme. The Theme Web Control just renders a <LINK> to the current theme if one is applied (Default is actually the lack of a theme).

For example, here the rendered HTML source for a page on a site that has the Simple theme applied.

<link rel="stylesheet" type="text/css"

   href="/_layouts/1033/styles/core.css"/>

<link rel="stylesheet" type="text/css"

   id="onetidThemeCSS"

   href="/sites/y/_themes/simple/simp1011-65001.css"/>

Note that the href points, not to the 12 hive, but to the site’s _themes folder. When a user applies a theme, the themes files are copied to the site to allow customization.

Also note that like AlternateCSS, themes affect the application pages.

Summary

So, to summarize the rendering order on a MOSS publishing site page is:

  1. The CssRegistration entries in alphabetical order
  2. Core.css
  3. The value of the CssLink Web Controls DefaultUrl property if one is specified
  4. The AlternateCSS if one is specified
  5. The current theme if there is one

If you want to add your own HTML <LINK> by hand bypassing any of these and want to be sure it comes last, simply place it after both SharePoint:CssLink and SharePoint:Theme.

–Doug Ware

Author: Doug Ware