Posts Tagged ‘Branding’

Wednesday, July 23rd, 2008

SharePoint Branding Issues: Edit In Datasheet View

For a couple of weeks now, I’ve got some reports about crashing datasheet views when using custom master pages. As a reminder, the datasheet view is a view you can select when browsing within a list. It’ll enable you to view and edit the list in an excell-like format. Quite handy for bulk changes.

So, what is happening? I noticed the page was going into an infinite loop. When debugging I stumbled upon the GC-functions. Those functions are located in core.js and control the resizing of the datasheet view control. After carefull reviewing, I noticed the document.documentElement.scrollHeight was growing and growing. It seemed that my custom master page let the scroll height go out of it bounds.

To fix this, I simply bound the scroll height to the client height. To accomplish this, you look for

var lGCWindowHeight=document.documentElement.scrollHeight;

in core.js and replace it with

var lGCWindowHeight=(document.documentElement.scrollHeight>document.documentElement.clientHeight) ? document.documentElement.clientHeight : document.documentElement.scrollHeight;

This seemed to solve the problem and stopped the browser from crashing.

But why was this happenning? My best bet is the use of a specific doctype in my masterpage. In quirks mode, IE includes top and bottom borders and padding widths when calculating the offsetheight. Standard mode only defines the content height as offsetheight. I’m guessing core.js relies on the extra margins. Now, the strange thing is, the custom master pages of MOSS (BlueBand, OrangeSingleLevel, …) do not experience this bug, altough they also use a specific doctype. I didn’t really investigate into it too much, but I suspect they restrict the height of some container surrounding the main content. This could stop the growth of offsetheight. If anyone of you, readers, can confirm this behaviour, feel free to respond in the comments.

In the meantime.. have fun branding!

Update: according to reader Rufino, you can also revert this behaviour by specifying a height. Didn’t test it yet, but I’m pretty sure this ‘ll do the trick too. Thanks Rufino!

Monday, December 3rd, 2007

SharePoint Branding Issues: Calender View

Back again for a SharePoint branding issue, and this time we’ll tackle the calender. More specifically its calender views: the day and the week view. Let me first show you, how the week view should look like:

SharePoint Branding Issue: Calender view on default.master

As you can see, an appointment can cover multiple hours. This way you have a graphical overview of how much time appointments will take. This, however, is how it looks like on the other MOSS master pages:

SharePoint Branding Issue: Calender view on MOSS master pages

This is not what we expected. Appointments now only cover a small fragment of the time to take, while the rest stays blank. It is very confusing for the user. And some appointments seem to pointlessly be in different columns. The day view experiences the same kind of problem. What is this weird voodoo? We did not change anything to the calender, now did we?
Well, no, we didn’t. But we did change the looks of it by changing how the looks are parsed. As I already mentioned in another article a couple of weeks ago, the other MOSS master pages use a (correct) doctype declaration, while the default master page does not even contain one:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Make no mistake, this is a declaration HTML pages should contain. Otherwise, you have no clue how browsers will render the page. Internet Explorer falls back to its “quirk mode”, where everything is “kinda” allowed. Other browsers will just try to render the page. And this is what we experience in the calender views. The inner box of the appointment has a CSS property: height equals 100% to make the appointment cover the whole time slot space reserved in the table of the view. In the doctype declared version, this is only supported if all parent elements also have a CSS height equal to 100%. Of course, this is not the case for all its parents. That’s why the appointments get shortened.

Is there a solution? Well, no solutions, only workarounds, I’m afraid.

  • Remove the doctype declaration from the master page. I don’t really advice it, but it can do the trick. Make sure other browsers still display the master page correctly. Future browsers can break the layout however. (this is what SharePoint did for the default.master)
  • Rewrite the views. You could make the views compatible with current standards, but it’ll cost quite some time to develop.
  • Have SharePoint show the default.master for the calender views. It’s an ugly workaround, as you’ll have different layouts in your site, but it works.

Once more, a very unfortunate branding issue. Aspecially, because it could have been prevented by generating correct HTML. Hopefully this kind of bugs will be resolved in future SharePoint versions. Till next time.

Friday, November 9th, 2007

SharePoint Branding Issues: Web Parts

This final blog post (for now) in the SharePoint Branding Issues series is one regarding web parts and their branding issues. I’m assuming most of you know what web parts are. They are like mini applications within a web page. As they are so small, you’ll often add several of them together on the same web page. In other technologies, such applications are called widgets or gadgets or whatever. But basicly, their ideology is the same. A nice example is featured on live.com.

To get back to .NET, web parts are a new technology within ASP.NET (and unified in version 2). In previous versions of SharePoint, they used some custom made framework. And now in WSS 3.0, they are slowly migrating to the new ASP.NET 2 standard, which allows far more easy web part development. Finally to be complete, a few more statements regarding web parts. Web parts are placed within horizontal or vertical web parts zones. These zones can define the chrome style used for the web parts within. The web part chrome, for those who do not know, is a fancy word for its border decoration. Furthermore, the web parts need one single web part manager, per page, for.. well.. managing purposes. Finally, all of these concepts have a corresponding class within the System.Web.UI.WebControls.WebParts namespace. And basicly this is, in a nutshell, what web part infrastructure is all about.

Now, the thing with SharePoint. They decided to overwrite all of these classes (just as we would for a custom branding job in ASP.NET). But somewhy they made the decision to make the new classes all sealed. So basicly you can not change anything, except, of course, if you rewrite every single class… :-) I know… And as one of my hungarian colleagues would say in such a situation: nice! ;-)

The chrome in SharePoint consists of 5 fixed chrome types (Default, None, Title and Border, Title Only and Border Only). These are implemented in an internal SPChromeHelper. What this class does, is adding the following structure as chrome:

<table>
    <tr>
        <td>
            <table>
        </td>
    </tr>
    <tr>
        <td>
            <div>
        </td>
    </tr>
</table>

Depending of the style the first row, which is the header, will be generated or not. Accordingly CSS classes are attached to the rows, the inner div and the inner table. As you can imagine, this kind of structure can be really restrictive. It is very difficult to add gimmicks, like rounded corners, to such a composition.

What can we do then? Well, basicly, applying tricks and hacking our way in. To achieve this, once again, our friend is CSS. By adding some classes to the right place and by using some specific CSS selectors, one can manage to achieve some degree of customization. A possible solution could be to add a specific CSS tag name to the declaration of the zone tag in your page. This way you can reach its inner web parts through the use of CSS selectors. In most cases you can define your own zones, so this can potentially be a solution for the problem. Another, more obvious solution, consists of simply overwriting the fixed chrome type’s CSS styles. The issue here is that every web part has to be set with the correct fixed chrome type to display your customizations. Of course, you still have the same limitations as the previous solution, as the structure of the chrome is still the same. More over, you usually cannot reach all generated HTML tags using only the fixed CSS class names.

While writing this article, I found this post written by Daniel Terborn. Daniel tackled the same problem and supplied another possible solution. He decided to create a base web part which implements all of the layout. Finally, with some CSS hooks, he manages to get really nice web parts. The problem with this solution is that it only applies to custom written web parts. In some situations this can be acceptable (by only using custom web parts), but most of the time you’ll want to use the out-of-the-box web parts too, for obvious reasons.

Conclusion? There is no clean and neat solution for web part branding within the current iteration of SharePoint products. We can only hope the sealed classes will be opened up in future versions. Until then, happy SharePointing.

Monday, October 29th, 2007

SharePoint Branding Issues: Application Pages

Application pages are those special pages within SharePoint that share functionality accross sites. Some examples include the site settings, the list settings, each setting page within those settings, the All Site Content pages, the personal settings pages, etc. A way to directly recognize one of these pages is to look at the URL of the accessed page. If the url contains this segment “/_layouts/”, you are dealing with an application page. Why? Well, the /_layouts/ directory is a virtual directory created by IIS and is available to every created SharePoint site. You can access every page within the layouts directory by simply adding the path to your site url. For example: http://www.host.com/subsite/_layouts/settings.aspx. But where does this path redirect? The _layouts virtual directory is mapped to a fixed directory within the SharePoint hive, more specifically: C:\Program Files\Common Files\Microsoft shared\web server extensions\12\TEMPLATE\LAYOUTS\. So, every page within this directory is accessible through the special \_layouts\ directory.

Another way to recognize these pages is that, if you use a master page other than the default one, the application pages still seem to use the default master page. I write “seem”, because although the appearance seem to be the same, it is a different master page. This master page is also located within the layouts directory and is called application.master.

If you want a complete make-over of your SharePoint site, chances are you’ll want to change the appearance of those pages. One way to do this, is to edit the application.master master page. This can be a valid solution if your whole farm uses the same master page, as all application pages of the sites on your server use this system master page. So, if you change the master page, the changes will be visible on all instances. Most of the time, however, you have different sites on your server with different branding needs. So this approach is usually out of the question.

My solution consists of altering the application pages themselves. Although this is not a recommended practice, as Microsoft is not supporting this (Service packs could overwrite the changes), sometimes it’s the only option left. Let me show you what to add:

<script runat="server">
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
MasterPageFile = SPContext.Current.Web.CustomMasterUrl;
}
</script>

Basicly we’re assigning, at run time, a new master page to the application page. Application pages can use the SPContext object to find out the context in which they are called. From this object we extract the current site (a SPWeb object) and assign the CustomMasterUrl property as the application page’s master page. This will do the trick just fine.

An important note to this solution, regards the master pages themselves. Master pages for application pages need to support two extra content place holders, PlaceHolderPageDescriptionRowAttr and PlaceHolderPageDescriptionRowAttr2. As these place holders don’t seem to do much, you can just add those two tags within a hidden ASP.NET panel to your master page.

<asp:ContentPlaceHolder id="PlaceHolderPageDescriptionRowAttr2" runat="server" />
<asp:ContentPlaceHolder id="PlaceHolderPageDescriptionRowAttr" runat="server" />

If you are using this technique, be sure to add these tags to the default.master master page in the SharePoint hive and this for compatibility reasons with the other sites. Of course, do not forget to add them to your custom master page too, as this is usually the reason, in the first place, to apply this solution.

A nice extension would consist of making the Application Pages Master Page of a site selectable through the UI (in MOSS) for selecting a master page. You could then use the SPWeb property bag to save the master page url.

Untill next time, happy sharepointing.. :-)

Thursday, October 25th, 2007

SharePoint Branding Issues: Breadcrumb

Navigation can break or make your site, and more specifically, your site’s usability. One of the tools to achieve a good navigation experience is the breadcrumb. In opposite to a menu structure a breadcrumb is quite space saving. And this is, according to MSDN, because it displays a hierarchical path of hyperlinked page names that provides an escape up the hierarchy of pages from the current location.

Basicily, it shows the current node and all its parent nodes. For the sake of completeness, it’s also called an eyebrow. And I’m not making this stuff up.. :p All in all, I’m pretty sure you guys all know the beast. I, for one, find it pretty usefull… as long as it keeps consistency along the way.

Back to SharePoint now. A breadcrumb within ASP.NET is called a SiteMapPath. This is a control which uses an XML sitemap of your site structure to keep track of your every move. It then shows your progress in a nice little breadcrumb. To access the sitemap, we need to use a .NET object called SiteMapProvider. As this is an object in code, we can change the way such a SiteMapProvider works and feed him some custom links programmically in stead of using a XML scheme. This gives a whole lot of flexibility. And because of SharePoint’s inherent dynamic nature, this is why almost all SiteMapProviders within SharePoint are implemented this way.

WSS natively offers a couple of SiteMapProviders (SPNavigationProvider, SPSiteMapProvider, SPContentMapProvider and SPXmlContentMapProvider), each with its specific use within your site. MOSS adds about 10 more. And it’s in MOSS, the troubles begin. Say, you design your site and you have to choose the breadcrumb’s location. Done? Ok.. which SiteMapProvider will you use? The default.masterpage has two (event up to three) breadcrumbs integrated in its design, all with different SiteMapProviders. (I wonder why this design decision was made) The two providers used are:

  • SPContentMapProvider: the default WSS SiteMapProvider which shows nicely all different items and lists
  • CurrentNavSiteMapProviderNoEncode: a provider which parses pages, not as items in a Pages list, but as sections within the site, which is pretty clean.

My requirement was: I want both advantages: items and lists nicely shown and pages cleanly parsed. Unfortunately, the WSS SiteMapProvider does not know pages and the MOSS SiteMapProvider does not parse lists and items. So, I decided to develop my own SiteMapProvider.

A SiteMapProvider consists of two things. A class containing the logic and an entry in the web.config enabling the SiteMapProvider’s use in a masterpage. Let’s first start with the logic.
As this is a MOSS problem only, I created a class inheriting from a MOSS SiteMapProvider: CombinedNavSiteMapProvider. This one will show nice complete breadcrumbs, except of course for lists and items. The SiteMapPath control uses one particular property from the SiteMapProvider: CurrentNode. So this is the one to override. This is the code I came up with:

public override SiteMapNode CurrentNode
{
  get
  {
    SiteMapNode node = base.CurrentNode;
    SPListItem listItem = SPContext.Current.ListItem;
    string url = HttpContext.Current.Request.Url.AbsolutePath;
    bool isItemSelf = listItem != null && url.EndsWith(listItem.Url);
    if (!isItemSelf)
      node = SiteMap.Providers["SPContentMapProvider"].CurrentNode;
    return node;
  }
}

Two things to notice. I check if the url is a page by comparing the requested url with the current item’s url. If they both match, it’s a Page alright. Second thing, to parse with the default WSS provider, one can find the correct provider in the static property Providers from the type SiteMap.
The last piece of the puzzel is the entry in the web.config. This is pretty straight forward. Go to configuration.system.web.siteMap.providers and duplicate the entry of the provider you inherited from. Change the assembly details and you have yourself a working SiteMapProvider.

All in all, this was quite a challenging change to find a solution for and to implement it. But once up, it works like a charm and seems so easy. See you next time!

Tuesday, October 16th, 2007

SharePoint Branding Issues: MOSS Search Center

When searching in MOSS, your results are shown in the search center. This is a special site you can create within your MOSS site collection. When using the default master pages, everything looks nice. The search box is in some blue area, while results get listed on the page. So far, no problem.

Search in default.master Search results in default.master

Say you want to develop a new master page. You take your basic place holders and arrange them on your page, the way it best fits your design. One of those placeholders is called PlaceHolderTitleBreadcrumb. What does this place holder contain? You might have guessed it, it should contain the breadcrumb of the page. And this is very crucial. Master pages are a technology which rely on “design by contract“. This is a special way of designing based on trust. In our master page we add content place holders to enhold specific parts of page. We give them specific locations and identifiers and we expect the correct functionality in it. Sadly, this is not always the case.

The search center is one of those areas not respecting the content place holders. Let’s look what will happen, when changing the master page of our site. (And once again, I’m just switching to a MOSS master page)

Search in OrangeSingleLevel.master Search results in OrangeSingleLevel.master

As you can see, the layout of the pages is somewhat disturbed? Why? The page layouts, which are used in those pages, give another meaning to our PlaceHolderTitleBreadcrumb place holder. They have the complete search box logic in it. A valid question here would be: why? Well, my guess is: the search looks nice when used in the default master page. They wanted to distinguish the search box area from the results. So they added the search box in the PlaceHolderTitleBreadcrumb. Now, for people who have moved this place holder (to the top, for example) within their custom master page, this can be a serious problem.

The solution, per se, is not that complicated, nor hard to apply. You just open up the two page layouts (SearchMain.aspx and SearchResults.aspx in your site collection’s masterpage catalog) move the search boxes from the PlaceHolderTitleBreadcrumb to the PlaceHolderMain. And you’re done, quite simple. But this is not where the problem resides. What to do with your other search centers in your farm? … Let me think… How about altering the files directly on the disk in the 12 Hive? This way, when provisioning, the search centers will have a nice layout in all master pages? Ok, but what if your distributing the thing? Well, in this case, one could provide some altered page layouts to use, and dynamically switch the old ones to the new ones in a feature receiver. And so on, and so on…

I hope most of you will realize these practices are mere patching up work. They are not giving a real solution. Sadly, most of the times, this is what we have to do to get things done. The true solution consists of conventions, and keeping them applied. Unfortunately, in a team as big as the development team of Office, this can be quite cumbersome. Hopefully they’ll keep that in mind for next iterations, and try to be more consistent. :-) Until next time!

Friday, October 12th, 2007

SharePoint Branding Issues: Table Of Contents WebPart

On one of my projects I had to customize the table of contents webpart. This webpart can list pages, lists and subsites of a specific site, and this in a custom organization and presentation. When using it on the default master page, it shows the content in different levels with some nice indentation applied to it.

Table of Contents using default.master

But when I activated my custom master page, the indentation suddenly did not show. My first reaction was: “OK, this surely is some classic CSS problem. I’ll just set the correct class back in my custom CSS file.” However, whatever I tried, whatever CSS rule I put in, the indentation did not come back. Worse, there’s already margin applied to the elements, hard coded in the webpart. But Internet Explorer did not seem to wanna show it when using my master page. And this was only the beginning…

When stripping down both the default master page and my custom master page down to the bare necessities (no css files, no other controls, … nothing), the default master page still showed the indents while my master page didn’t! And to get even more confused, the other MOSS master pages do not show the margins either! This is weird.. very weird. What the hell makes the difference?

Table of Contents using OrangeSingleLevel.master

And then it hit me. My master page and the MOSS master pages use following code, where the default.master does not:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

For those of you who do not know what this is, you can read all about it over here . Basicly, it instructs the browser how to parse the HTML and CSS. How is this relevant, you ask? Well, as I said, the table of contents uses some inline code to display the indentation.

      <div style="margin-left:12;">

At first glance, this seems spot on, correct. Except, it isn’t. Though the default behaviour of Internet Explorer would accept this line. When using the doctype, Internet Explorer demands more precision and clarity. What kind of clarity? This kind:

      <div style="margin-left:12px;">

Yes, indeed, it’s the unit. Doctype requires correct values and units. And if those are not available, the browser will simply ignore the values. So what are the implications? All MOSS master pages and custom master pages, using this kind of doctype, will not show the identations. Talking about a bug.. ;-)

The solution, of course, is adding the ‘px’ unit to the style. Luckily, the table of contents is one of those webparts which uses XSL style sheets to format its data and makes those available in the Style Library within your SharePoint site collection. Once inside this style sheet (LevelStyle.xsl), one can easily add the px to the different styles using the margin. This creates an instant solution to the problem. If you want to apply this to your entire farm, go to your server and adjust the LevelStyle.xsl in the PublishingResources feature.

Fixed Table of Contents using OrangeSingleLevel.master

For the aftermath: this is sort of a silly problem. It could have been easily prevented. Nevertheless, these kind of problems are very hard to track down. My fear is this is not an isolated case and there could be more of those little ‘bugs’ within SharePoint, due to inconsistent use of CSS. This is quite a shame, I think, for such a rich product. :-(  But anyway, what have we learned today? Always set your units in CSS! ;-) See ya next time.

Wednesday, October 10th, 2007

SharePoint Branding Issues: ASP.NET Flyout Menus

The most prominent way to navigate within a SharePoint site is using the menus. SharePoint has two menu structures: the top main navigation, and the quick launch navigation which is usually located at the left side of your screen. When you’re defining the menu structure, you might consider flyout menu’s. These javascript powered menus will popup whenever you hover over their parent’s node. They have a huge space saving gain, so they are quite frequentaly used.
As they are native ASP.NET controls, you can somewhat customize these menus. This can be done by editing the master page. See msdn for more options on these menus.
There is, however, a nasty little issue when custom branding these flyout menus. Let me show you:

Dynamic menu with background color issue.

For some reason the background of a dynamic menu would not change when setting it in the CSS class of the menu. (You can specify a CSS class for the ASP.NET menu to use) A possible resolution would be to change the background of the nodes themselves.

Dynamic menu with item background colored. 

Unfortunately this gives some nasty gaps when using margins. I just had to find a way to color the background all together. When investigating the thing, I discovered this in the output.

.zz1_GlobalNav_0 { background-color:white;visibility:hidden;display:none;position:absolute;left:0px;top:0px; }

Somewhy, something had outputted some extra styles straight into the master page. Firstly, inline CSS, I really discourage using CSS like this, unless for testing purposes or if there really is no ther way. However, even I get sometimes tempted. But the point is, it’s bad, as it blocks using external CSS files. Secondly, why is the background color white? Once again I had to rely on Reflector as the ultimate resort to find what went wrong and how those styles were rendered. This is what I found in the PopOutPanelStyle class:

if (base.BackColor.IsEmpty && ((this._owner == null) || this._owner.BackColor.IsEmpty))
{
attributes.Add(HtmlTextWriterStyle.BackgroundColor, "white");
}

In other words, ASP.NET automaticly adds a white background when there is no background color defined in the color and the when the parent is empty. And this was the case in my example. So what is the solution? Putting the color directly as parameter in the control using BackColor.

You didn’t really think I would leave it at that, now did you? Well, there is another solution. As I couldn’t live with the fact there was a color directly defined in the master page, I continued searching. Finally, it was the magical CSS which, once again, offered a nice way out. When rendering a dynamic menu, ASP.NET first renders an absolute positioned panel with the actual menu table in it. And it’s this panel which has the menu’s CSS class reference, instead of the table with static menus. This gives us some flexibility. Thanks to the cascading styles, we can reach the untampered table with the following reference: .navGlobalFlyOuts table, allowing us to set the background after all:

.navGlobalFlyOuts table
{
background: #F7DCEA;
}

Once again, CSS has saved the day. Thank you CSS. ;-)

Dynamic menu with correct background color.

Tuesday, October 9th, 2007

SharePoint Branding Issues: MySite Control

This is the first of the more specific articles regarding SharePoint Branding. They will go from small issues to bigger ones.

One of the controls a SharePoint design usually sports is the My Site control. This is a control with a link to the current user’s MySite. But unfortunately this is not the only thing this controls adds. It also adds a pipe character (|) just to the right of the link. No problem, I thought. As it is a delegate control, it’ll use some custom control from the control templates. I’ll just have to remove the pipe from the control. I went to the control templates and bingo, there was MySiteLink.ascx. Wrong, as it seems, the control uses some code behind file where it programatically adds the pipe.

this.hlMySiteSpacerSuffix.Text =
  "<span style='padding-left:4px;padding-right:3px'>|</span>";

So how can I quickly remove the pipe, without having to rewrite another delegate control to take its place, or a whole new other control to render the special MySite link? The answer is CSS. As it turns out, the pipe is rendered within a span tag. So when adding the delegate control, make sure you encapsulate it within a specific css reference, for example: .removeSpan. In your css, you just have to define the following:

.removeSpan span
{
  display: none
}

Voila, one pipe free MySite link. Sure, it’s still on the page, but the design does not get screwed up by it. Problem solved.

Monday, October 1st, 2007

SharePoint Branding Issues

As promised, I am writing a series of blogposts regarding issues you may encouter when developing a custom branding solution for SharePoint. Customers usually want to customize the out of the box design SharePoint is offering. It often simply does not reflect their company’s branding. SharePoint uses master pages and CSS to provide a consistent look throughout their pages. But when developing a custom design, you will notice it is not that easy to customize the things you want. So how do I tackle this?

I always create a custom master page. Why do you ask? The master pages SharePoint provides do not always provide CSS support on all it tags, and codewise the HTML is not really clean. The number one thing to remember when developing a minimal or custom master page for SharePoint is that SharePoint expects a number of PlaceHolders to be within the master page.  If there’s some content in a placeholder you don’t want to be available on the page, don’t simply remove the place holder. Move the place holder within a hidden ASP panel.
So is that it? Obviously, no. SharePoint makes extensive use of controls within its pages. You can add and remove them at your discretion. Though there are a couple one which are pretty critical to ensure SharePoint running correctly. Namely, You better declare a SPWebPartManager on your page, otherwise WebParts won’t work. Another thing is to include the form tag right after the beginning of the body tag. This to ensure pages can be posted. Some other controls you might want to include, but which aren’t necessary include wssuc:Welcome, PublishingSiteAction:SiteActionMenu and PublishingConsole:Console.

In short:

  • add a form tag (don’t forget the JS wrapper functions)
  • include all place holders
  • add a WebPartManager control

So, now you have your master page. What about the CSS? SharePoint uses the CSSLink control to add references to their CSS files, of which core.css is the most important. The default way to do CSS in SharePoint is to overwrite the SharePoint CSS in custom CSS files. Unfortunately this method can be quite cumbersome, as core.css seems to be a SS rather than a CSS. They don’t really use the cascading part of style sheets. So, you have to overwrite multiple classes before a change comes through, and sometimes it’s impossible to overwrite a style whithout changing another style too.
My preferred way to work is to remove the CSSLink control altogether and use my own stylesheets. I have two. The first one is a CoreLight.css. It encapsulates only the most necessary classes from core.css and the ones who mostly do not have to be customized. Of course, I cleaned up this style sheet. This is a file I reuse with each project and keeps getting better with each project. The other file is the CSS specifically for the current project. It’ll define the styles, colors, layouts, typography the project uses.

In short:

  • do not use CSSLink
  • create a CoreLight, which incorporates the necessary core.css classes (and others)
  • create a specific stylesheet, where you define project related resources.

Mind that this way to work may not be the most recommended with SharePoint guidelines. It just makes my work far more easier. I can redesign a whole site within one work week. It is up to you to use the method you’re more at ease with.

This was my global approach for custom SharePoint branding. Following articles will deal with some specific issues when creating a custom SharePoint branding.