Friday, April 10, 2009

CSS Selector Collisions

Thick Competition

For those brave souls who actively try to make stock SharePoint UIs look user friendly, there's a gauntlet that first needs to be run. The challenge has to do with competing CSS rules and styles. Stock SharePoint will emit many style sheets who will often also be trying to style the same element that you are.

When it comes to deciding which rule wins, you should keep the following rules in mind. They'll very likely help you troubleshoot, especially when combined with tools like the IE Developer Toolbar or the Firefox Web Developer Tools extension.

Specificity

In general more specific rules tend to win. Remember that CSS styles can come from four different places. Rules that are increasingly specific will trump those who come from more generalized sources. Below we list (from most general to most specific) the four most common sources of CSS for a given html document.

  1. The browser's default styles. Believe it or not each browser has a stock set of styles that get applied to elements whether you've chosen to style them or not. You'll have to compete with these even if they're the easiest to best.
  2. An external style sheet (referenced from within the <head> tag [below]).
    <head>
    <link rel="stylesheet" type="text/css" href="mystyle.css" />
    </head>
  3. Internal style sheet (rules described in <style> tags within the HTML document itself).
    <HEAD>
    <STYLE type="text/css">
    H1 {border-width: 1;}
    </STYLE>
    </HEAD>
  4. Inline styles (styles placed on individual elements themselves).
    <P style="font-size: 12pt; color: fuchsia">Some Text</P>

More specific rules (those further down the list) will win out over more general ones.

Weight

Certain selectors are a little stronger than others. More specifically, ID has more weight than Class which has more weight than Tag name.

In fact weight of a selector is determined by taking the sum of (100 * [# IDs used] + 10 * [# Classes used] + [# Tags Used].

Here's an example:

#navigation div.container span a.footerLink

Has a weight of (123 since it has 1 ID, 2 classes, and 3 tags. It would be trumped by:

div#navigation div.container span.wrapper a.footerLink

Since the above has a weight of 134 (1 ID, 3 classes and 4 tags).

Order

If specificity and weight are the same then it comes down to who was emitted last. In general rules that were emitted later on in the document will win.

The Ace In The Hole

If you're too lazy to figure out the rest you can simply use the !important flag.

div
{
color:red !important;
}

This should trump all other rules but is considered to be pretty poor form and may get you dirty looks around the water cooler.

Hope that helps.

Best,
Tyler