SharePoint Branding & CSS Specificity

We all know that best practices SharePoint branding avoids the use of !important in your CSS, but how do you correctly control the specificity of your CSS to mitigate the need for it?

The order of operations for your CSS depends on a number of factors, including the loading order of the stylesheet, the order of the styles within that stylesheet, and lastly the specificity of the style. SharePoint allows us to use the <SharePoint:CssRegistration> tag to help provide greater control over the loading order of stylesheets and ensure that your custom style sheet is loaded after all of the core ones. This allows us to easily override the out of the box classes easily, since styles loaded later will override matching properties of identically named styles loaded previously.

I recently ran into a problem when branding SharePoint 2010 MySites for a client. The SharePoint core CSS has classes for branding the "Add New" links on the bottom of list/library web parts (.ms-addnew a:visited, .ms-addnew a:active, .ms-addnew a, etc.). Simple enough, my custom stylesheet that is loaded after all of the core ones overrides the link color to my desired color. But on the MySite, there's another core stylesheet (portal.css) that gets loaded as part of the layout of the MySite. The CSS link is actually rendered inside the main content placeholder, not in the head. These same few styles are redefined in portal.css, and since that is loaded later, it overrides my override of the core style.

Some people might now stand up, voilla... this is one of those cases where "you HAVE to use !important", but this is not the case. Remember that little thing called specificity? A style loaded later will not override a previous style if that previous style has greater specificity. Since .class .class element is more specific than .class element, the browser will always choose a more specific style over a newer one.

This being said, crack open your custom master page, and find the opening <body> tag. If your masterpage has been derived from the default out of the box master, you'll likely see that the body tag has a class attribute with a value of "v4master". Add a second value to the class attribute (ie: class="v4master customBranding"). We can now define more specific styles using the .customBranding selector. Using .customBranding .ms-addnew a will always take precedence over the .ms-addnew a in portal.css purely because it's more specific than any styles already defined in the core stylesheets. No !important here.