SharePoint CSS and CSS Specificity

CSS specificity (weight) and SharePoint

When dealing with SharePoint CSS one of your biggest friends is specificity. It also happens to be one of the harder things to wrap your head around, especially if you are just getting into creating and editing CSS. Specificity is a key thing to understand for SharePoint branding and something that I cover in all my branding classes.

What is “specificity” anyways?

When you write a CSS style statement, it is broken into two parts. The selector, which is everything before the opening curly brace, and the properties, which is everything inside of the curly braces.

selector {properties}

Here is what happens when we use CSS on a web page:

  1. The selector targets an element, such as DIV or H1.
    <div><h1>Cranky Kitty</h1></div>
  2. The properties and their values modify the look and feel of the element. For example, set the background of the DIV to green.
    div {
         background: green;
    }
  3. There is only one element, but many style statements can be created for the one element.
    div {
         background: green;
    }
    div {
         background: red;
    }
  4. The browser can only use one property value (there can’t be a background that is both solid red AND solid green) and relies on specificity to know which property value to apply.

Selectors are assigned weights (think numbers, such as a rotund kitty that weighs 20lbs) and the higher weight will always prevail (fat cats squish skinny cats). If two style selectors have the same weight, then the one that was included last will be applied.

Pointless cat picture, here for the fun of it.

Various web sites will state that specificity is what you call the rules that determine which CSS style property values will get applied to an element. This is right, but makes it sound more complicated than it needs to be. Specificity is a fancy word for selector weight, and the only rule that matters is the selector that weighs more, wins.

How to determine the weight of a selector

You assign a numerical value, or weight, to the individual selector components based on their type. Next, add up the points and you will have the final weight for the style statement.

Weight Assignment: 1,000 100 10 1 0
Selector Type: Inline style ID ClassAttribute

Pseudo-class

ElementPseudo-element Universal (*)Inherited
(from other style statements & elements)

If you use !important in your style statement, a special weight isn’t applied. Instead the style property that has !important added to it will be bumped to the top of the priority pole, no matter the weight of the selector. !important is used on properties, not on selectors.

Here is an example style statement that grows in the quantity and types of selector components to show you how the weight increases. For this example I have ignored selectors that receive zero points (universal and inherited).

p {background: red;}

Weight Assignment 1,000 100 10 1
Selector p
Sub total 0 0 0 1
Total weight: 1

p.tabby {background: red;}

Weight Assignment 1,000 100 10 1
Selector .tabby p
Sub total 0 0 10 1
Total weight: 11

p.tabby h1 {background: red;}

Weight Assignment 1,000 100 10 1
Selector .tabby p
Selector h1
Sub total 0 0 10 2
Total weight: 12

p.tabby h1.calico {background: red;}

Weight Assignment 1,000 100 10 1
Selector .tabby p
Selector .calico h1
Sub total 0 0 20 2
Total weight: 22

#Siamese p.tabby h1.calico {background: red;}

Weight Assignment 1,000 100 10 1
Selector .tabby p
Selector .calico h1
Selector #Siamese
Sub total 0 100 20 2
Total weight: 122

#Siamese:hover p.tabby h1.calico:first-child {background: red;}

Weight Assignment 1,000 100 10 1
Selector .tabby p
Selector .calico h1
Selector :first-child
Selector #Siamese :hover
Sub total 0 100 30 3
Total weight: 133

Any style statement selector can be broken down this way to determine the final weight. And remember, what weighs more will be what is applied to the element in the rendered web page.

See? The bigger cat wins out since it has more weight.

You may have noticed that I never included an inline style:

<p style="background: red;">

or !important:

p {
     background: red !important;
}

to score the ultimate weight of 1,000 or shift the property to a top priority. This is because these two should be avoided at all costs.

Got it. Now why should I care about it?

SharePoint is many things, but what SharePoint isn’t is a nice little web application you wrote from scratch. Any existing web application or content management tool that you use choose to implement for your site will have its own CSS. Depending on how the CSS selectors were written, you may have a very fat cat waddling your direction when you decide to brand the tool. You may be a pro at writing nice, skinny compact CSS but if your selectors have a lower weight than the tool you are branding, your styles won’t be applied.

Here is a simple example, that is straight from SharePoint…

You have decided you want to change the hyperlink color in SharePoint, so you write this style statement:

a {
     color: green;
}

The weight of that selector is a measly 1. SharePoint on the other hand has this:

a:link {
     color: #0072BC;
}

The weight of the SharePoint selector is 11 (:link is a pseudo-class). SharePoint wins.

Now some people in a fit of frustration would do this in retaliation:

a {
     color: green !important;
}

Now this style statement still has a weight of 1, but since !important was used the color style property will be applied (green) instead of the color property supplied by SharePoint (#0072BC). However you have just set the stage to have to use “!important” on every style property that you write that alters the hyperlink color from the base color of green that you set. Plus if there were other style properties included such as font size or face, the changes still wouldn’t take affect because your selector only has a weight of 1. Instead you would have to add !important on every style property. This will quickly turn into very messy and undesirable code.

Your retaliation to get past the weight value will become a royal pain as you try to beat yourself in future selector and style property wars (oh I think I just got a new reality TV show idea!). The end solution for our hyperlink color dilemma is to just do this:

a:link {
     color: green;
}

Put this style statement in a CSS file that is called AFTER the SharePoint CSS and the other bit of specificity will come into play: “If two style selectors have the same weight, then the one that was included last will be applied.” Now you have won.

If you are really wanting to make sure your selector value is higher and not just the same value as SharePoint, you can add body to your selector.  This is a great way to essentially one-up SharePoint on any CSS style selector to win a weight war. Now your value is 12.

body a:link {
     color: green;
}

Heavy-weight Champion of the World… SharePoint

Well not really but when you are working with an existing tool and the CSS that comes with it, specificity matters a lot. A good bit of SharePoint CSS is straightforward and has low weight selectors. But there are some style statements that will make your life difficult if you don’t understand specificity. Here are some examples…

Style links in an unordered list within your content area

Your HTML, inside the main content area:

<ul>
     <li>
          <a href="link.com">Why do cats toss their lunch so much?</a>
     </li>
</ul>

Your CSS for hyperlink styling:

Statement Weight
ul li a {
     color: green;
}
3
ul li a:hover {
     text-decoration: none;
}
13

SharePoint on the other hand has this:

Statement Weight
a:link {
     color: #0072BC;
}
11
.ms-rtestate-field a:hover {
     text-decoration: underline;
}
21

The introduction of “ms-rtestate-field” is stemming from the fact that your content area is wrapped with this class. This style statement is affecting hyperlinks in your content area, even though at first glance you may not think it will affect anything you are doing.

To beat SharePoint, your CSS selectors need to be modified like so:

Statement Weight
ul li a:link {
     color: green;
}
13
.ms-rtestate-field ul li a:hover {
     text-decoration: none;
}
23

Modify containers by targeting the ID

There are several key wrapper elements that help structure things like the ribbon, the workspace area under the ribbon, the web part tool pane, the quick launch, etc. A lot of people would modify one of these big ticket items by targeting the ID on the element. For example, the quick launch is wrapped in a DIV that sets the width of the quick launch bar. To change this width you write:

Statement Weight
#s4-leftpanel {
     width: 200px;
}
100

But SharePoint has this:

Statement Weight
body #s4-leftpanel {
     width: 155px;
}
101

So a simple selector change is in order for your custom CSS:

Statement Weight
body #s4-leftpanel {
     width: 200px;
}
101 <– This one is applied since it was included after SharePoint CSS.

Add borders to rows in a list view (web part)

Perhaps the all white approach SharePoint has with list views isn’t meeting your needs and you want to add borders between list item rows. After poking around you see that the list view is wrapped in a table, with a class of “ms-listviewtable”. You come up with the following:

Statement Weight
.ms-listviewtable td {
     border: 1px solid gray;
}
11

But no borders appear for your table. Look deeper into SharePoint and you will find this:

Statement Weight
table.ms-listviewtable > tbody > tr > td {
     border-color: transparent; 
     border-image: none; 
     border-style: solid; 
     border-width: 1px 0;
}
14

A few things about this example…

  1. The greater than signs (>) are child selectors and don’t affect the weight.
  2. You can be smarter than SharePoint – you don’t have to duplicate their style statement. Instead you could win this weight war by doing this:
Statement Weight
.s4-wpTopTable .ms-listviewtable td {
     border: 1px solid gray;
}
21

“s4-wpTopTable” is a class assigned to a parent table of “ms-listviewtable”. There was no need to repeat the long string of elements when you can score an easy +10 for adding another class to the selector.

In closing…

The reason why you need to care about CSS specificity when dealing with SharePoint is so you can make sure the CSS you write will override any default/OOTB SharePoint styles and will successfully be applied to your SharePoint site – without littering your code with !important and inline styles. No one wants to deal with a 1,000+ pound cat after all.

Got a CSS Challenge?

If you are scratching your head over some CSS dilemma in SharePoint, please drop me a line and I will take a stab at solving your issue.

The cat analogy in this post is both inspired by and dedicated to my November 2012 SharePoint 2010 Branding Experience course attendees, and of course, Cranky Kitty. Cranky Kitty