Back to Cleverworkarounds mainpage
 

SharePoint Branding Part 7 -The ‘governance’ of it all..

Well, here we are! After delving into dark arts where everybody but metrosexual web designers fear to tread (HTML and CSS), we then delved into the areas that metrosexual web designers truly fear to tread (packaging, deployment and even some c# code!). Finally, we get to the area where everybody is interested until it happens to get in their way! (Ooh, I am a cynical old sod tonight).

That is Governance!

Continue reading “SharePoint Branding Part 7 -The ‘governance’ of it all..”

No Tags



SharePoint Branding Part 6 - A "solution" to all issues?

There has been a bit of a gap in this series between part 5 and 6 - and fortunately for the both of us, I think this is the penultimate post in my series on SharePoint branding. While it has been an interesting exercise for me, I must confess each successive article is getting harder to write as my interest is shifting :-)  So many sub-disciplines within MOSS - I think I might delve into WCM soon :-).

Continue reading “SharePoint Branding Part 6 - A "solution" to all issues?”

No Tags



SharePoint Branding Part 5 – Feature Improvements and Bugs

So, here we are at the fifth article in my series on SharePoint branding. By now, we have left all the master page stuff way behind, and we have created a custom feature to install our branding to a server.

To recap for those of you hitting this page first, I suggest you go back and read this series in order.

  • Part 1 dealt with the publishing feature, and some general masterpage/CSS concepts and some quirks (core.css and application.master) that have to be worked around.
  • Part 2 delved into the methods to work around the application.master and core.css issue
  • Part 3 delved further into the methods to work around the application.master and core.css issue and the option that solved a specific problem for me
  • Part 4 then changed tack and introduced how to package up your clever branding

Continue reading “SharePoint Branding Part 5 – Feature Improvements and Bugs”

No Tags



SharePoint Branding Part 4 – Packaging up your masterpiece into a Feature

Welcome to the fourth article in my series on SharePoint branding. Sorry for the time it’s taken to get this one out, but a certain game called “The Legend of Zelda:  Hourglass Phantom” on NDS got in the way. I finished it yesterday and only had to cheat via google once :-). Anyway it’s out of my system now so I can get back to this.

After 3 epic articles on all that painful CSS and master page stuff (part one, two and three), we now focus on what you have to do to get your branding masterpiece deployed to the SharePoint farm the clever way. In this next set of articles, we will look at where things should go, and then how to get it there the right way.

Continue reading “SharePoint Branding Part 4 – Packaging up your masterpiece into a Feature”

No Tags



SharePoint Branding - How CSS works with master pages – Part 3

Welcome to the third article (or is it a manifesto?) in my series on SharePoint branding. In this article, we continue examining methods to incorporate CSS files into master pages for clever branding. In my first article of this topic, I discussed what I think is the main issue with SharePoint branding - APPLICATION.MASTER and CORE.CSS. The previous article to this one, examined 5 methods to deal with the trial and tribulations of APPLICATION.MASTER and CORE.CSS behavior. So, to recap where we got to, let’s re-examine the original scenario and then look at the summary of the 5 different several methods with their relative merits and issues.

The Scenario

Like many organizations, my client had an existing corporate branding standard that was used in a non SharePoint environment and naturally enough, they wanted their SharePoint site to look like this branding. This was for a fully featured intranet/extranet that utilized most of the MOSS2007 features such as

  • Document collaboration
  • Infopath Forms Services
  • Workflow
  • Enterprise Search
  • Excel services
  • Business Data Catalog
  • Custom web parts
  • Event Handlers

It was *not* a public site at all.

Initial investigation soon concluded that we would need a custom master page. DEFAULT.MASTER didn’t quite have the design flexibility that was required. In fact the branding requirements were actually closer to some of the built in master pages such as BLUEGLASS.MASTER, since this was for intranet purposes, particularly collaborative document management, those master pages are unsuitable.

Other major requirements included mandatory consistency of branding across the entire farm. This meant that we had to deal with the APPLICATION.MASTER issue. Additionally, different semi-autonomous divisions within the client’s organisation wanted to be able to modify the corporate brand in accordance with existing branding policy (mainly colours/skinning) while maintaining the existing structural look and feel.

Additionally, as well as the corporate branding, there was another, very different branding which was used as part of a communications plan for some organizational change stuff. This had a deliberately different look to the rest of the site, yet the web designer had been clever when this design was created. They were able to completely rebrand the look and feel of the additional branding just through additional CSS and not wholesale HTML structural changes.

So, really, we had two general classes of sites. ‘Standard’ corporate sites and the custom branded ‘Organisational Change’ site.

The type of MOSS environment this was to be applied to was a medium to large SharePoint farm with three web front end (WFE) servers, and there were several SharePoint web applications and site collections in the farm that needed this branding. Further down the track, there was to be other SharePoint farms in different offices around the world with localized language requirements.

The final requirement (the one that complicated things) was that many of the CORE.CSS styles needed to be overridden to ensure the branding was correct.

Summary of CSS methods

Method Advantages Disadvantages
SharePoint:CSSRegistration - Easy to implement - Does not overrides core.css
- Does not work with _layout pages
Master Page Settings - Easy to implement
- Overrides core.css
- Works on _layout pages
- Can only be used once
- Has to be set up for each site
<link> method - Set in master page once
- Overrides core.css
- Precludes “Master Page Settings” CSS override
- Does not work with _layout pages
Michael’s webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- Does not work with _layout pages
- core.css as the first CSS can be problematic
My webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- core.css is not the first stylesheet in the list
- allows choice as to what css overrides core.css
- Does not work with _layout pages

Now for many SharePoint logical architectures, these methods will likely work well. Unfortunately in my situation each had enough drawbacks that I kept looking. So next stop: SharePoint Themes.

Over-riding CSS – SharePoint Themes

In my humble opinion, when you examine themes, it smells a little like legacy WSS/SharePoint 2 functionality carried over and now adds to confusion rather than clarifies. This is purely a hunch of course, but given the way themes have to be installed, and their scope across the farm, suggests to me that it may become a legacy feature going forward.

Why do I think this? Well, the official purpose a SharePoint theme is for ’skinning’ a site, but at the end of the day, a theme is just another CSS file, only implemented a different way. Being CSS, you can define any style you want here, not just the ones related to colour. Furthermore, the styles defined in themes can be used in any other other CSS files too.

Okay, so it is essentially another form of CSS file… then what is the difference between this and the other methods CSS I have outlined?

Well, for a start, theme CSS files live in a sub-folder of on the server:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\THEMES

So, this is a location on the web front end server/servers, whereas with the other methods, the CSS files reside inside a document library of a site collection. I believe that document library is a better choice because you have all those niceties like versioning, approvals and recycle bin, etc. If you have a farm of WFE servers, you would have to add your theme to each server and hope no mistake was made.

On top of being in every WFE server folder, just making a CSS file and dropping it in here is not enough either. Examining one of the pre-supplied themes shows that a theme consists of CSS files, an INF file, and of course, the images referred to by the styles. The two CSS files are called THEME.CSS and MOSSEXTENSION.CSS. (When you apply a theme to a site, MOSSextension.css is appended to the bottom of your theme.css)

The INF file is always the name of the theme folder, eg

<path to sharepoint>\12\TEMPLATE\THEMES\CITRUS contains CITRUS.INF

So you create a folder, add the CSS, INF and images, and finally, you then have to tell SharePoint about it. This is done by modifying a single XML file called SPTHEMES.XML.

SPTHEMES.XML can be found in:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033

A typical entry will look like:

<Templates>
    <TemplateID>PimpMySharePoint</TemplateID>
    <DisplayName>Pimp me</DisplayName>
    <Description>A pimped sharepoint</Description>
    <Thumbnail>images/thpimp.gif</Thumbnail>
    <Preview>images/thvpimp.gif</Preview>
</templates> 

So let’s look at an example.

I have taken a copy of the CLASSIC folder under THEMES, info a folder called PIMPMySharePoint. I’ve then renamed CLASSIC.INF to PIMPMYSHAREPOINT.INF and added this theme to SPTHEMES.XML.

I then run IISRESET and open up my site collection. Go to Site Actions->Site Settings and choose “Site Theme”

Now you should see your “Pimp SharePoint” theme listed

Click apply and re-examine the page. You will see that the look and feel of the site will have changed.

Now examine the HTML source in the browser. You will see something like

<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/controls.css?rev=EhwiQKSLiI%2F4dGDs6DyUdQ%3D%3D”/>
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/HtmlEditorCustomStyles.css?rev=8SKxtNx33FmoDhbbfB27UA%3D%3D”/>
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/HtmlEditorTableFormats.css?rev=guYGdUBUxQit03E2jhSdvA%3D%3D”/>
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css?rev=5msmprmeONfN6lJ3wtbAlA%3D%3D”/>
<link rel=”stylesheet” type=”text/css” id=”onetidThemeCSS” href=”/sites/ft1/_themes/PimpSharePoint/Pimp1011-65001.css?rev=12%2E0%2E0%2E6007″/>

Note that the theme (in bold) is rendered after core.css.

How did this happen?

You should already be familiar with SharePoint:CssLink and SharePoint:CssRegistration webcontrols via my previous articles. Behind the scenes to all of this, the theme is rendered via an additional control called the <Sharepoint:Theme> in the master page. Here is DEFAULT.MASTER source code that produced the above output

<Title ID=onetidTitle><asp:ContentPlaceHolder id=PlaceHolderPageTitle runat=”server”/></Title>
<SharePoint:CssLink runat=”server”/>
<SharePoint:Theme runat=”server”/> 

If you look carefully at the above source code, you will see that the only reason that the theme has overriding CORE.CSS is because the SharePoint:Theme control is listed after Sharepoint:CSS. If you reverse the order of the two controls, as expected the order of the theme is changed. In the example below, I took a copy of DEFAULT.MASTER and made the following modification:

<Title ID=onetidTitle><asp:ContentPlaceHolder id=PlaceHolderPageTitle runat=”server”/></Title>
<SharePoint:Theme runat=”server”/>
<SharePoint:CssLink runat=”server”/>

and the resulting HTML is now reversed with CORE.CSS once again last.

<link rel=”stylesheet” type=”text/css” id=”onetidThemeCSS” href=”/sites/ft1/_themes/PimpSharePoint/Pimp1011-65001.css?rev=12%2E0%2E0%2E6007″/>
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/controls.css?rev=EhwiQKSLiI%2F4dGDs6DyUdQ%3D%3D” />
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/HtmlEditorCustomStyles.css?rev=8SKxtNx33FmoDhbbfB27UA%3D%3D” />
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/HtmlEditorTableFormats.css?rev=guYGdUBUxQit03E2jhSdvA%3D%3D” />
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css?rev=5msmprmeONfN6lJ3wtbAlA%3D%3D” />

Thus, although you will read that themes are used to say, “re-skin the layout of a site”, in reality, it is the order of the application of CSS files that determine what parts of a site a theme will modify. Put in a different way, you add whatever you like to the theme CSS files and it will act like any other CSS, except it gets rendered last by default.

Heather notes that themes have the same benefit as using “Master Page Settings” to override CORE.CSS. That is, they also apply to _layouts pages and affect APPLICATION.MASTER. The only reason that they work here is because the APPLICATION.MASTER master page used for _layout pages has the SharePoint: Theme webcontrol in its source code.

A gotcha with this method is that themes are per farm. Since they reside on the web front end server, my “Pimp Sharepoint” theme is available to any site in the farm. What’s more, if I modify the theme here, all sites are modified. This can be good but is equally going to catch you out as your SharePoint farm grows.

Another gotcha! Do not for a second assume that the SharePoint:Theme control is always included in master pages because it is not! Go and check the master pages that are installed by the “Office SharePoint Server Publishing Infrastructure” feature and you will see that none of them use the SharePoint:Theme webcontrol. Therefore, no matter what you put as your theme for sites based on publishing master pages, only the _layout pages (based on APPLICATION.MASTER) are affected by the theme CSS. (This to me reinforces my belief that themes are a legacy technology.)

Another gotcha! You will not like themes if you have a lot of sub-sites because you have to apply it at the site level for each site. Unlike the other methods described thus far, this method is not inheritable to sub-sites.

Yet another issue that makes this method a low cleverworkarounds rating, is that themes have to be installed on the web front end servers. In a large scale farm, there may be several WFE servers that need this set. There is no version control, version history, recycle bin, publishing approvals, and as a developer it means you have to deal with anal SharePoint infrastructure or governance Nazis who will not even talk to you unless you have packaged your work up as a solution.

Cleverworkaround Rating: Sucky

Overriding CSS – Master Page Settings with @import

This is a method that I considered but did not test, although I am sure that it will work (so I would be happy to hear from anyone who did). It actually needs to be used in combination with the “master page settings” method that I described in article 2. The idea here is based around strict naming conventions for CSS files.

Now remember my original scenario, I have a master page, and a corporate brand CSS that needs to override CORE.CSS (CSS number #1). But then I have additional CSS files that override the corporate brand CSS file depending on the site. Using the master page settings to specify a CSS file only deals with CSS number 1.

But my idea here is that the CSS to be specified in Master Page Settings (CSS number 1) , refers to one of more additional CSS via the @import directive. The names are strictly defined, so for example:

@import url(brandingoverridemintyfresh.css);

@import url(brandingoverrideorgchange.css);

So now, you have two extra CSS ‘placeholders’. If they do not exist in the site collection, they will not be used. But if you put a CSS file into the site collection, and give it one of the above names, you should in theory get the additional styles required.

This method seems relatively simple in the sense that it is all done in the CSS files, and the SharePoint GUI. However, since by default the CSS files reside in the site collection style library, adding or removing CSS files affect the entire site collection. This behavior can probably overridden with hard-coded or relative URL’s but it will not be great. Hard-coding anything is “not clever” for scalability and flexibility, and relative URL’s are difficult because site collections are not necessarily top level sites.

In addition, your CSS file can get ugly, with lots of @import references to files that do not exist which will confuse things later if governance around this is not well handled.

I won’t assign this a rating, given that I didn’t test it. But I can see it would have its uses in some circumstances. If someone wants to experiment with this I’m happy to link you, or add to this article.

My solution

Now despite the fact that I’ve in effect bagged themes earlier, the actual styles defined in the themes are some of the ones you are likely to be interested in, when performing a branding exercise. It is this fact that led me to my final solution that for me, had the best clever rating of all.

So let’s now examine our matrix so far with the addition of the themes method.

Method Advantages Disadvantages
SharePoint:CSSRegistration - Easy to implement - Does not override core.css
- Does not work with _layout pages
Master Page Settings - Easy to implement
- Overrides core.css
- Works on _layout pages
- Can only be used once
- Has to be set up for each site
<link> method - Set in master page once
- Overrides core.css
- Precludes “Master Page Settings” CSS override
- Does not work with _layout pages
Michael’s webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- Does not work with _layout pages
- core.css as the first CSS can be problematic
My webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- core.css is not the first stylesheet in the list
- allows choice as to what css overrides core.css
- Does not work with _layout pages
Custom Themes - Easy to implement (GUI set)
- Overrides core.css
- Works on _layout pages
- Modifying the theme modifies all sites using it
- Not inherited - has to be manually set for all sites
- Installing and updating themes require farm administrator and manual configuration of WFE servers
- Not all master pages will obey the theme

Over-riding CSS - The hybrid!

Now remember my original scenario, I have a master page, and a corporate brand CSS that needs to override CORE.CSS (CSS number 1). But then I have additional CSS files (let’s collectively call them CSS number 2), that override the corporate brand CSS file depending on the site. CSS number 2 assumes that CSS number 1 is also referenced. This keeps CSS number 2 smaller and more manageable. But the disadvantage is that as discussed, using the master page settings to specify a CSS file can only be used once and therefore only deals with CSS number 1.

But…what if we took all of the bits that needed to be overridden CORE.CSS and moved them to CSS number 2? Then CSS number 1 is left with styles that CORE.CSS does not interfere with.

CSS number 2 (remember there are potentially many of these) is a little bigger now, as it has some additional styles since now it has to deal with any CORE.CSS interference, however it is still relatively maintainable.

So then, we can do this… (…drumroll)

Have the generic branding (CSS number 1) added to the master page using the SharePoint:CSSRegistration method. Then any CSS number 2, can be specified by the ‘master page settings’ method.

So to illustrate, let’s take a look at the source code to our branded master page.

<SharePoint:CssLink runat=”server”/>
 <SharePoint:CssRegistration name=”<% $SPUrl:~SiteCollection/Style Library/~language/Core Styles/Band.css%>” runat=”server”/>
  <SharePoint:CssRegistration name=”<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/controls.css %>” runat=”server”/>
 <SharePoint:CssRegistration name=”<% $SPUrl:~sitecollection/Style Library/zMyDefaultBrand.css %>” runat=”server”/>
  <SharePoint:Theme runat=”server”/> 

So, looking at this code, you can see that we are using SharePoint:CssRegistration, to specify a CSS file called zMyDefaultBrand.css. Remember why I prepended it with a z? It’s because SharePoint:CssLink control renders CSS files in alphabetical order it will be rendered last by the CSSLink webcontrol, except for CORE.CSS of course.

You can also see that I left the SharePoint:Theme control in so it can be used if required.

So, since we have moved all the CORE.CSS overrides to CSS number 2, we have a default CSS file called MyTheme.css. This now goes hand in hand with zMyDefaultBrand.css and is set set via the “master page settings” screen.

So the rendered HTML code combines to this:

<link rel=”stylesheet” type=”text/css” href=”/sites/pc/Style%20Library/en-US/Core%20Styles/Band.css” mce_href=”/sites/pc/Style%20Library/en-US/Core%20Styles/Band.css”/>
<link rel=”stylesheet” type=”text/css” href=”/sites/pc/Style%20Library/en-US/Core%20Styles/controls.css” mce_href=”/sites/pc/Style%20Library/en-US/Core%20Styles/controls.css”/>
<link rel=”stylesheet” type=”text/css” href=”/sites/pc/Style%20Library/zMyDefaultBrand.css” mce_href=”/sites/pc/Style%20Library/zMyDefaultBrand.css”/>
<link rel=”stylesheet” type=”text/css” href=”/sites/pc/_styles/core.css” mce_href=”/sites/pc/_styles/core.css”/>
<link rel=”stylesheet” type=”text/css” href=”/sites/pc/Style%20Library/MyTheme.css” mce_href=”/sites/pc/Style%20Library/MyTheme.css”/> 

Let’s look at the result and compare with our requirements. As you can see, CORE.CSS still beats zMyDefaultBrand.css but it is subsequently beaten by MyTheme.css, so we can override any CORE.CSS quirks.

Since MyTheme.CSS contains all of the look and feel styles that are usually defined in the SharePoint themes and CORE.CSS, the _layouts pages based on APPLICATION.MASTER get overridden nicely. By splitting the CSS we are able to define the global style in zMyDefault.css and the *default* CORE.CSS override in MyTheme.CSS

Since we are using master page override method, this is set on a per site basis and is inheritable from a parent site. Now our web designers can work their CSS magic to make additional MyTheme.css type files to offer flexible branding options such as MyThemeMintyFresh.CSS or MyThemeCorporateBrandB.CSS. Web administrators can pick the CSS file they want to use on a site by site basis giving complete flexibility.

Wohoo!

Cleverworkaround rating: Nice

Summary

So here is the final version of my table..

Method Advantages Disadvantages
SharePoint:CSSRegistration - Easy to implement - Does not override core.css
- Does not work with _layout pages
Master Page Settings - Easy to implement
- Overrides core.css
- Works on _layout pages
- Can only be used once
- Has to be set up for each site
<link> method - Set in master page once
- Overrides core.css
- Precludes “Master Page Settings” CSS override
- Does not work with _layout pages
Michael’s webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- Does not work with _layout pages
- core.css as the first CSS can be problematic
My webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- core.css is not the first stylesheet in the list
- allows choice as to what css overrides core.css
- Does not work with _layout pages
Custom Themes - Easy to implement (GUI set)
- Overrides core.css
- Works on _layout pages
- Modifying the theme modifies all sites using it
- Not inherited - has to be manually set for all sites
- Installing and updating themes require farm administrator and manual configuration of WFE servers
- Not all master pages will obey the theme
My Hybrid Method - Easy to implement (GUI set)
- Overrides core.css
- Works on _layout pages
- master page setting is always specified

Next steps

I am a two finger typist, so after 3 articles you would think we are done. But nooooo, we still haven’t solved all of the issues. Next stop, we examine how to deploy this to the farm set-up in a nice, easy to maintain format. So we do some work on features, solutions, quirks (yeah there are quirks) and governance around it all.

No Tags



SharePoint Branding - How CSS works with master pages - Part 2

Jeez if I had realised how long it would take to write these damn articles, I probably wouldn’t have started! In my first article of this topic, I discussed the theory behind master pages, the publishing feature, and what I think is the main issue with SharePoint branding - APPLICATION.MASTER and CORE.CSS. In this article I will now list a branding scenario that I had to deal with, and the various options you can use to deal with the challenges of APPLICATION.MASTER and CORE.CSS

The Scenario

Like many organizations, my client had an existing corporate branding standard that was used in a non SharePoint environment and naturally enough, they wanted their SharePoint site to look like this branding.

This was for a fully featured intranet/extranet that utilized most of the MOSS2007 features such as

  • Document collaboration
  • Infopath Forms Services
  • Workflow
  • Enterprise Search
  • Excel services
  • Business Data Catalog
  • Custom web parts
  • Event Handlers

It was *not* a public site at all.

Initial investigation soon concluded that we would need a custom master page. DEFAULT.MASTER didn’t quite have the design flexibility that was required. In fact the branding requirements were actually closer to some of the built in master pages such as BLUEGLASS.MASTER, since this was for intranet purposes, particularly collaborative document management, those master pages are unsuitable. (I will explain why soon).

Other major requirements included mandatory consistency of branding across the entire farm. This meant that we had to deal with the APPLICATION.MASTER issue as described in my last post. Additionally, different semi-autonomous divisions within the client’s organisation wanted to be able to modify the corporate brand in accordance with existing branding policy (mainly colours/skinning) while maintaining the existing structural look and feel.

Additionally, as well as the corporate branding, there was another, very different branding which was used as part of a communications plan for some organizational change stuff. This had a deliberately different look to the rest of the site, yet the web designer had been clever when this design was created. They were able to completely rebrand the look and feel of the additional branding just through additional CSS and not wholesale HTML structural changes.

So, really, we had two general classes of sites. ‘Standard’ corporate sites and the custom branded ‘Organisational Change’ site.

 

The type of MOSS environment this was to be applied to was a medium to large SharePoint farm with three web front end (WFE) servers, and there were several SharePoint web applications and site collections in the farm that needed this branding. Further down the track, there was to be other SharePoint farms in different offices around the world with localized language requirements.

The final requirement (the one that complicated things) was that many of the CORE.CSS styles needed to be overridden to ensure the branding was correct.

The Custom Master Page

The first decision to make is whether to stick to just CSS modifications to an existing master page, or to create a new master page. This post is based around a new master page, however the CSS methods I outline in this post are equally valid when using, say, DEFAULT.MASTER or one of the publishing master pages like BLUEBAND.MASTER.

So since we knew we had to use a custom master page, we had 3 choices in creating a new master page.

  • Make a copy of DEFAULT.MASTER and use that
  • Start with a completely blank master page
  • Make a copy of one of the publishing master pages like BLACKBAND.MASTER

I’ll actually deal with the third option first because we initially used it and then discounted it.

As previously mentioned, in our case BLUEGLASS.MASTER was the closest of the built in master pages to our branding needs but in the end we did not use it. Publishing master pages are actually somewhat simpler than the default.master page. Some web controls/placeholders have been modified/removed from publishing master pages, and if you use them for say, a document collaboration site, you will find quirks like:

  • Missing breadcrumb navigation in document libraries when browsing subfolders
  • Missing recycle bin link
  • Different navigational structure
  • Tree-view not being rendered despite being selected
  • Themes are ignored (I discuss this in detail in part 3)

Furthermore, I actually read not so long ago that it was recommended that these pages be generally used for internet facing sites which by definition tend to be publishing sites. (I’m trying to find the reference and as soon as I locate it I’ll paste here), but Tyler’s post offers some hints where he talks of custom CSS and navigation out of the box.

A blank master page is potentially a great option, either the MSDN one that everyone seems to hate or Heather’s, that the general population seems to like. Ultimately flexibility, of course, as it means that you can code up the look and feel from scratch. Unless you are a world class web designer and have a great understanding of ASP.NET, it may not be worth the time and budget (especially for an internal facing site).

So, we chose to simply make a copy of default.master because we actually did not have to change that much to achieve our ends. Yes it is complex and fiddly, but it is the out of the box master page that works with SharePoint, so using it as a base is a pretty safe bet. The main issue you need to watch out for when doing this, is related to the publishing feature.

So, for the purposes of this article, our new master page will be referred to as PIMPMYSHAREPOINT.MASTER – and we have to get our custom CSS styles into this.

Over-riding CSS – SharePoint:CSSRegistration

We took a look at SharePoint:CssRegistration and its brother SharePoint:CssLink in part 1, but I think it’s worth a recap.

SharePoint:CssRegistration defines a CSS file and Sharepoint:CssLink is the control that actually renders the SharePoint:CssRegistration styles as well as CORE.CSS.

<head runat=”server”>
[snip]
<Sharepoint:CssLink runat=”server” /
<!–Styles used for positioning, font and spacing definitions–>
<SharePoint:CssRegistration name=”<% $SPUrl:~SiteCollection/Style Library/pimpmysharepoint.css%>” runat=”server”/>
[snip]
</head>

And the result is…

<head>
[snip]
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/pimpmysharepoint.css” mce_href=”/sites/nopub/Style%20Library/pimpmysharepoint.css”/>
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css” mce_href=”/_layouts/1033/styles/core.css”/>
[snip]
</head>

As discussed in part 1, CORE.CSS, has been rendered, despite the fact that it is not explicitly defined. What’s more, CORE.CSS is always listed last.

Ah! But remember our requirement above? Our custom styles need to override styles in CORE.CSS! GONG! This isn’t going to do it for us.

Cleverworkaround Rating: Useless for me

Over-riding CSS – Master Page Settings

So we look at the next most obvious way to defeat this CORE.CSS issue. On a MOSS07 site with the “Office SharePoint Server Publishing Infrastructure” site collection feature enabled, we have the means to add a custom CSS to a master page via the GUI. It can be found in Site Settings on any site. Navigate to look and feel and choose “Master Page”.

Scroll to the bottom of this page and you will see the CSS override settings.

From here, you can choose a custom CSS file to use. In this example we have chosen pimpmysharepoint.css which was uploaded to the style library for this site collection. Let’s examine the HTML output once pimpmysharepoint.css has been selected.

<link rel=”stylesheet” type=”text/css” href=”/_styles/core.css” mce_href=”/_styles/core.css”/>
<link rel=”stylesheet” type=”text/css” href=”/Style%20Library/PimpMySharePoint.css” mce_href=”/Style%20Library/PimpMySharePoint.css”/>

Aha! We have overridden CORE.CSS – nice! Given that we have not modified the master page itself, we can conclude that SharePoint:CssLink will render the “alternate CSS URL” last. In addition, we have solved the APPLICATION.MASTER problem. Hands up who can tell me why ? :-) The reason is that APPLICATION.MASTER uses SharePoint:CssLink as well, so it will render this CSS in _layout pages derived from that master page.

Furthermore, we did it with no coding or custom work, and it can be inherited or forced out to all subsites from this one. WOHOO!

So? Have we found our clever workaround? No we have NOT. DOH! We have a workaround, but I do not believe that it’s clever yet!

Remember my requirements. We had a corporate brand that required CORE.CSS override for a few styles. In addition, we have the ‘organizational change’ branding CSS that overrides the corporate branding CSS. In addition, even within corporate branding we had CSS overrides for individual departments too.

So what is our problem then?

Using this method, we can only override once! Once you set this alternate CSS, that’s it. Thus, if I was to use this method, I would have to maintain several large custom CSS files, one for each branding scenario. Given that 80% of the actual styles are consistent between them, I prefer a method where the common stuff is kept common, rather than risk being fragmented over time with changes to one of the CSS files not being propagated to others.

I’m sure many of you would be okay with this, and for certain clients, I would be too. However, call me anal if you want but I wanted to find a better way.

CleverWorkaround Rating: Close, but no cigar!

Over-Riding CSS – Static CSS Link

Now, given that SharePoint:CssLink control renders stylesheet links at runtime, what is stopping us simply adding a static CSS link in the master page? The source code below illustrates the idea.

<head runat=”server”>
[snip]
<Sharepoint:CssLink runat=”server” /
<!–Styles used for positioning, font and spacing definitions–>
<SharePoint:CssRegistration name=”<% $SPUrl:~SiteCollection/Style Library/pimpmysharepoint.css%>” runat=”server”/>
<link rel=”stylesheet” type=”text/css” href=”/Style Library/anothercss.css”/>
[snip]
</head>

This works on the premise that 80% of your branding (the stuff that CORE.CSS doesn’t screw with) is in PIMPMYSHAREPOINT.CSS. The other 20% that needs to override CORE.CSS is in ANOTHERCSS.CSS.

So, now I have embedded a static link into the master page. Before we go on to assess its cleverness, can you see my mistake?

Imagine, that you have 3 site collections named:

That static link, will always try and use the style library for the top site collection, even for the bottom two site collections. But what if the users do not have permission to the top site collection? Will the CSS render? Probably not as access to it would be denied.

Here is the adjusted source to fix this – using a token to render the correct site collection URL.

<head runat=”server”>
[snip]
<Sharepoint:CssLink runat=”server” /
<!–Styles used for positioning, font and spacing definitions–>
<SharePoint:CssRegistration name=”<% $SPUrl:~SiteCollection/Style Library/pimpmysharepoint.css%>” runat=”server”/>
<link rel=”stylesheet” type=”text/css” href=”<% $SPUrl:~SiteCollection/Style Library/anothercss.css%”/>
[snip]
</head>
>

See what I have done (in bold)? I have placed the rendered link into the master page source. I have used the $SPURL:~SiteCollection token though which at runtime gets replaced with the path to the site collection. (In the example below the site collection was called “/sites/nopub”).

So let’s examine the HTML output of this.

<head>
[snip]
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/pimpmysharepoint.css” mce_href=”/sites/nopub/Style%20Library/pimpmysharepoint.css”/>
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css” mce_href=”/_layouts/1033/styles/core.css”/>
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/anothercss.css” mce_href=”/sites/nopub/Style%20Library/anothercss.css”/>
[snip]
</head>

Wohoo! We have our custom styles after CORE.CSS. What’s more, we can add as many <link> entries as we like here. Although not shown above, I could have one <link> with the 80% of common styles and another <link> with the 20% of custom ones.

So have we found our branding utopia? No – hell no!

One of the disadvantages with this method is that if your <link> is placed AFTER SharePoint:CssLink, then it will also trump your “alternate CSS URL” setting described in the “master page setting” method. This is because the alternate CSS URL is rendered by SharePoint:CssLink. Placing your static link before SharePoint:CssLink is utterly pointless, because all of the CSS files specified by SharePoint:CssRegistration will trump the <link> entry. The whole point here was to override CORE.CSS.

If that wasn’t bad enough, the clincher is that _layout pages, based on APPLICATION.MASTER master page, will not have this static link anyway. Therefore, your branding is inconsistent for _layout pages and in fact is likely WORSE because it will apply the 20% customizations of ANOTHERCSS.CSS but the other 80% of PIMPMYSHAREPOINT.CSS common styles will be missing.

CleverWorkaround Rating: Pretty damn crappy actually !

So, what can we try next?

Over-riding CSS – Mike’s method

Now this method I was very, very impressed with (and cursed that I did not think of it myself). Mike came up with a novel way to solve the CORE.CSS problem. He created his own asp.net control that REPLACES SharePoint:CssLink. He has inherited the CSSLink class and modified the rendered output to move CORE.CSS from last to first. Ingenious!

So, to implement this, you need to compile it to a DLL in visual studio. You need to copy the DLL into the global assemble cache, and then mark the web control as safe. This is done by making a modification to the <safecontrols> section of the XML file, WEB.CONFIG of the web application that is going to render this control.

<SafeControls>

[snip]

<SafeControl Assembly=” MichaelHofer.SharePoint.PublishingEnhancements, Version=1.1.0.0, Culture=neutral, PublicKeyToken=7ce575c89ea427a4″ Namespace=” MichaelHofer.SharePoint.PublishingEnhancements ” Safe=”True” />

</SafeControls>

Then, in the custom master page, you have to tell SharePoint how to find the DLL. It is called ‘declaring the assembly’. Here is Mike’s example:

<%@ Register Tagprefix=”PublishingEnhancements” Namespace=”MichaelHofer.SharePoint.PublishingEnhancements” Assembly=”MichaelHofer.SharePoint.PublishingEnhancements, Version=1.1.0.0, Culture=neutral, PublicKeyToken=7ce575c89ea427a4″ %>

And now, you delete the reference to <SharePoint:CssLink> in the master page and use Mike’s control.

<PublishingEnhancements:EnhancedCssLink runat=”server”/>

Now, let’s examine the output when using this method.

<head>
[snip]
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css” mce_href=”/_layouts/1033/styles/core.css” />
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/pimpmysharepoint.css” mce_href=”/sites/nopub/Style%20Library/pimpmysharepoint.css” />
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/anothercss.css” mce_href=”/sites/nopub/Style%20Library/anothercss.css” />
[snip]
</head>

So, CORE.CSS is now moved to the top and the world is a happy place! Or is it?

I had one problem with this method. Moving CORE.CSS unexpectedly changed the look of my branding. Then I realized the problem. Now CORE.CSS was being overwritten by every other style, and this was causing unforeseen side effects.

One other DOH problem. APPLICATION.MASTER will not reflect this change – so it has the same issue as the <link> method.

Despite this, I am going to give Mike a high cleverworkaround rating for this solution, but I am going to have to take off one point because he did not package it up into a solution :-) Mike will probably think this is terribly unfair, but on my SharePoint large farms with multiple WFE servers, if it is not a solution, it doesn’t go into production! (That’s the topic of part 4 of this series of articles).

CleverWorkaround Rating: Flawed genius – respect, man !

Over-riding CSS Files – My method

Inspired by Mike’s cleverness, I came up with an idea to improve his control. I dusted off VS2005 and added a public property called DefaultCSS. This holds the value of a CSS file I am interested in.

private string CSS;
public virtual string DefaultCSS
{
    get
    {
        return CSS;
    }
    set
    {
        CSS = value;
    }
}

Next I changed the render method, to swap the value stored in this property with CORE.CSS

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
        // Find reference of core and CSS property
        {
            int CSSRef = new int();
            int CoreRef = new int();
            for (int i = 0; i < styleSheets.Length; i++) {
                if (styleSheets[i].Contains(this.CSS)) {
                    CSSRef = i;
                }
                else if (styleSheets[i].Contains(”core.css”)) {
                    CoreRef = i;
                }
                else {
                    styleSheets[i] = styleSheets[i] + “\n”;
                }
            }
            // Now swap those elements
            string tmp = styleSheets[CSSRef];
            styleSheets[CSSRef] = styleSheets[CoreRef] + “\n”;
            styleSheets[CoreRef] = tmp + “\n”;
            output.Write(string.Concat(styleSheets));}}
        }
    }
}

So, as with Mike’s control, I compiled it to a DLL and copied it into global assemble cache (GAC), and then marked the web control as safe in web.config.

Then, in the master page, I added a reference to my DLL.

<%@ Register Tagprefix=”PublishingEnhancements” Namespace=”cleverworkarounds.SharePoint.PublishingEnhancements” Assembly=” cleverworkarounds.SharePoint.PublishingEnhancements, Version=1.1.0.0, Culture=neutral, PublicKeyToken=7ce575c89ea427a4″ %>

And now, you delete the reference to <SharePoint:CssLink> in the master page and use my version of the control. (Don’t forget to add the DefaultCSS property!).

<PublishingEnhancements:EnhancedCssLink runat=”server” DefaultCSS=”anothercss.css” />

I then packaged this up as part of my branding feature/solution (more on this in part 4) and then deployed with success. Now let’s examine the output when using this method.

<head>
[snip]
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/pimpmysharepoint.css” mce_href=”/sites/nopub/Style%20Library/pimpmysharepoint.css” />
<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css” mce_href=”/_layouts/1033/styles/core.css” />
<link rel=”stylesheet” type=”text/css” href=”/sites/nopub/Style%20Library/anothercss.css” mce_href=”/sites/nopub/Style%20Library/anothercss.css” />
[snip]
</head>

So now, only ANOTHERCSS.CSS has been swapped with CORE.CSS. PIMPMYSHAREPOINT.CSS is rendered prior to both, but the key here is CORE.CSS is not rendered last!

So, was I a genius? Was this the clever workaround? Can I give myself a high clever rating? :-)

Unfortunately not. Both Mike’s method and my BRO (blatant rip off) of his method fail to deal with the _layouts/APPLICATION.MASTER issue. In addition, this method requires the most customization. We need to add a DLL to the GAC, declare it in the master page, as well as tell the various SharePoint web applications that the control is safe to use.

If you do all this manually on a single server WFE farm, you can probably get away with this, but on a medium to large scale farm, it should be packaged up as a solution before being deployed.

CleverWorkaround Rating: Was a worthwhile exercise

So … let’s take a breath and recap on the 5 methods discussed so far and list their relative merits and disadvantages.

Method Advantages Disadvantages

SharePoint:CSSRegistration

- Easy to implement

- Does not overrides core.css
- Does not work with _layout pages

Master Page Settings - Easy to implement
- Overrides core.css
- Works on _layout pages
- Can only be used once
- Has to be set up for each site
<link> method - Set in master page once
- Overrides core.css
- Precludes “Master Page Settings” CSS override
- Does not work with _layout pages
Michael’s webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- Does not work with _layout pages
- core.css as the first CSS can be problematic
My webcontrol - Set in master page once
- Overrides core.css
- Works nicely with “Master Page Settings” CSS override
- core.css is not the first stylesheet in the list
- allows choice as to what css overrides core.css
- Does not work with _layout pages

 

Now for many SharePoint logical architectures, these methods will likely work very well (Okay… maybe not the <link> method). I hope that some people will find that one of these options solves their respective issues. Unfortunately in my situation each had enough drawbacks that I kept looking.

So, in part 3 of this series of articles, I will explain some more options, and explain the method that eventually worked the best for me.

Technorati Tags:



SharePoint Branding - How CSS works with master pages - Part 1

This is version 2 of this article, after I went and accidentally blew away my first masterpiece that took literally days to write. If this has ever happened to you, don’t you hate it, that your second version is never as good as your first?

Quick Links: [Part 1, Part 2, Part 3, Part 4, Part 5, Part 6, Part 7]

Anyway, this is (attempt 2 of) part 1 of a series of articles that cover SharePoint branding in some detail. Kudos has to be given Heather Solomon especially for her wonderful site and articles on this subject (and author of the book to your left :). In Addition, Andrew Connell and Mike have done some great work that helped me in this area.

So, SharePoint branding was the catalyst behind my deciding to make a blog and call it cleverworkarounds. The whole experience at times made me want to change careers, but I ultimately got there. I would go down one path, only to be stumped by a problem, and think I have the solution, only to find another quirk that needed another workaround. So the aim of cleverworkarounds is to determine the least dodgy way to implement branding of a SharePoint installation. No doubt people will disagree with the conclusions I’ve reached, but that’s expected since the cleverness of a workaround really depends on your needs.

 

So this series of articles will cover a few issues. First some basic master page theory, then I will talk about the difference between branding in WSS3 (the freebie version) and MOSS07 (the pricey one). I will then take you through the quirks of CSS and master pages. Subsequent articles will get into the details of branding techniques and finally finish off by covering the governance issues surrounding branding.

Master Page theory

This is a large topic in itself, but I will try and cover it quickly. Heather has written the definitive explanation for master pages so I’m trying here to cover the bits I want to cover without rehashing her great work. Suffice to say that the technology is actually part of ASP.NET and SharePoint simply leverages this (no point reinventing the wheel after all). Generally, most aspx pages in a SharePoint site will be derived from a Page Layout (content) page that itself, refers to a master page. Below is the MSDN diagram illustrating the concept.

MSDN has a good definition: “A master page contains references to elements that you can share across multiple pages in an Office SharePoint Server 2007 site, such as navigation, search controls, logon controls, and banner images. A master page can also contain the cascading style sheet (CSS) and ECMAScript (JScript, JavaScript) references that define the overall look and feel of your site. Commonly, every site—and therefore every page—in your site collection uses the same master page to present a consistent user experience across the entire site collection. Depending on your needs, you can use a different master page for one or for all of the sites in your site hierarchy to distinguish the various areas of your portal.”

To illustrate this idea, below I have pasted the very top line in a resulting page “DEFAULT.ASPX” from a basic SharePoint site.

<%@ Page language=“C#” MasterPageFile=“~masterurl/default.master”
Inherits=“Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12.0.0.0,
Culture=neutral,PublicKeyToken=71e9bce111e9429c” meta:webpartpageexpansion=“full”
meta:progid=“SharePoint.WebPartPage.Document” %> 

Note the reference to the token ~masterurl/default.master in the first line. This is a special token that represents the currently used master page. (I will drill down further on this in a few moments).

A master page, like DEFAULT.MASTER, will almost always refer to one or more CSS files to style the site. Below I have pasted some of the HTML browser output from the very same DEFAULT.ASPX that I referred to above.

<link rel=”stylesheet” type=”text/css” href=”/_layouts/1033/styles/core.css?
rev=5msmprmeONfN6lJ3wtbAlA%3D%3D”/> 

So in the example above, any ASPX page that uses DEFAULT.MASTER, refers to a CSS file called CORE.CSS.

Thus, SharePoint branding usually means either:

  • Using the default master page and simply overriding the built in CSS styles with your own
  • Creating a new master page and then overriding the built in CSS styles with your own.

So let’s drill down a little further, by looking at another master page and compare it with DEFAULT.MASTER. MOSS does come with some other master pages we can examine, but depending on your site template, you may have to activate the publishing feature. If you wondering what a feature is, check this post, and then come back ;-)

So let’s activate the publishing feature and see what happens.

WSS, MOSS and the Publishing Feature

This article is primarily written around MOSS07 and not WSS3, but WSS3 is worth a quick discussion. WSS can be branded using the techniques I outline here, but if you are being paid to brand a SharePoint site/farm, it is very likely you are using MOSS.

The reason for this, is that WSS3 does not have available a site collection feature called “Office SharePoint Server Publishing Infrastructure”. It is this feature that gives you all the tools you need to manage branding easily from just the web browser, as well as provide some sample master pages and different styles to learn from.

Almost all branding articles I have read assume this feature is installed and activated, but it is not always active for a site collection, depending on the site template used to create the site collection. You will find it under “Site Collection Features” in the “Site Actions” -> “Site Settings” screen.

So if you cannot find this feature listed, you are probably using WSS3. Sorry, but you are going to have a more fiddly time because you have to change your master page using SharePoint Designer (Kathy has written a nice overview here). But to get a quick sense of the idea, re-examine the reference to the master page token below..

<%@ Page language=“C#” MasterPageFile=“~masterurl/default.master” 

In WSS, this refers to what SharePoint designer calls the “Default master page”. Below, I show where I have taken a copy of DEFAULT.MASTER and called it PIMPMYSHAREPOINT.MASTER and set it as the default master page. Note that when I right click on PIMPMYSHAREPOINT.MASTER I have an option to set this as the default master page.

So now, when SharePoint loads pages on this site, the token “~masterurl/default.master” is replaced at run time by the default master page set above - “pimpmysharepoint.master”.

Of course, if you have MOSS2007 and enable the publishing feature, you have a much easier method to change the master page for a site that does not involve SharePoint designer. So let’s enable this site collection feature and see what happens.

First up, (note below what a site collection looks like without this publishing infrastructure feature activated), you have a master page gallery link, but under “look and feel”, there are no options related to choosing any other master pages.

If you open the site up in SharePoint designer, you will also see a basic SharePoint structure. Below shows a SharePoint site collection created using the blank SharePoint site template.

So now let’s activate the site collection feature “Office SharePoint Server Publishing Infrastructure” and re-examine the above site. Note the change in options, particularly in relation to “Look and Feel”. We now have a link for choosing which master page to use. That saves you having to fiddle with SharePoint Designer, doesn’t it?  :-)

It is when you look at the site collection in SharePoint Designer though, that you see the significant changes which have been made. There are a lot more goodies there now in the form of Lists, Document Libraries and Workflows. Thus, the publishing feature does a lot more than simply add a link to choose a master page. Penny has a great, detailed description of the additional resources installed by enabling this feature

So, now let’s choose a different master page. Under “Master Page Settings” in the “Look and Feel” section of site administration, you will see a selection of example master pages that come with the feature.

Now, at this point, I will throw you a little theory. With WSS, I explained how you can use SharePoint designer to change the master page to set the default master page. But MOSS gives you the nice method of being able to do this via the administration pages for a site collection. Both methods look in the same place - The master page gallery.

When you provision a site collection the system creates a master page gallery that contains all the master pages and page layouts for that site collection. The master page gallery is stored at the location /_catalogs/masterpages. It is a standard document library and as a result has version history, recycle bin support, approval workflow and all of the other document management goodies you get with SharePoint. This is great, since it makes it easy to roll back if an update to a master page file goes horribly wrong. No matter how many sub sites you make in the site collection, they will all be able to access the master page library via the link to /_catalogs/masterpages.

Below is the content of the master page gallery when the publishing feature has been enabled.

So, too easy then. Any web designer should be able to crank out their design app of choice, drop it into the master page gallery and shoot out a master page in minutes right? … Riiiiggghht? :-)

Well…yes, they can, but there are two major issues that cause a lot of grief with branding, CORE.CSS and APPLICATION.MASTER. The next section describes this.

CORE.CSS

So a quick recap. When you create a SharePoint site collection, even if using the blank site template, a document library is created to store master pages. It is referred by the path of _catalogs/masterpage and is called the “master page gallery”. The actual master page used, is a site based property set either via Sharepoint Designer (WSS3) or site administration (MOSS07). The master page almost always defaults to DEFAULT.MASTER (although site templates can actually specify another). DEFAULT.MASTER refers to a file called CORE.CSS. Thus, any web pages that use this template will always use CORE.CSS when processing styles.

Recap over: Now lets dig a bit more into CSS files in SharePoint!

The best way to understand how CSS is handled actually is to look at one of the sample master pages, for example blackglass.master that comes with the publishing feature. Since it significantly changes the look and feel of a site when applied, we know that CSS modifications have been made. If you go to the master page gallery of your publishing enabled site (http://<mysiteurl>/catalogs/masterpage), you will be able to download this master page and check out the source code in notepad or any other HTML designer. I have pasted the important bit below:

<head runat=”server”>
[snip]
    <Sharepoint:CssLink runat=”server” />
    <!–Styles used for positioning, font and spacing definitions–>
    <SharePoint:CssRegistration name=”<% $SPUrl:~SiteCollection/Style Library/~language/Core Styles/Band.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_black.css%>” runat=”server”/>
[snip]
</head>