I have a client who wanted rounded Web Part titles in their SharePoint 2007 Publishing site. “Easy!” I thought. “I’ll just use Heather Solomon’s great post that outlines exactly what to do!” That worked out fine and dandy until the client told me that they wanted it to work in IE6. I haven’t built to IE6 standards for years and didn’t relish trying to make :firstChild work in IE6.

FirstChild Hack for IE6
My Web Part background images were 29 pixels high. I used these classes in my default CSS file that worked for IE8, based on Heather’s guidance:

.ms-WPHeader td:first-child
{
  margin: 0;
  padding: 0;
  height: 28px;
  background: url('WebPartTitleBg.jpg') repeat-x;
}

.ms-WPHeader TD h3
{
  padding: 8px 4px 0px 0px;
  height: 20px;
  font-size: 11px;
  background: url('WebPartTitleBgRight.jpg') top right no-repeat;
  color:white;
}

.ms-WPHeader TD h3 a:link, .ms-WPHeader TD h3 a:visited
{
  color: white;
}

.ms-WPHeader TD span:first-child
{
  padding-top: 8px;
  padding-left: 14px;
  background: url('WebPartTitleBgLeft.jpg') top left no-repeat;
}

I had to do an “If” statement in my Master Page, checking to see if the user was using IE6. If so, they’ll get an additional CSS file that overrides the existing one. These are the classes that show up in the “IE6” CSS file:

.ms-WPHeader td
{
  background: expression((function(x){if(x == null)return 'url(/Style Library/MyStyles/Black and Blue/WebPartTitleBg.jpg) repeat-x'})(this.previousSibling));
}

.ms-WPHeader TD span
{
  line-height: 12px;
  padding-top: 7px;
  padding-left: 15px;
  background: expression((function(x){if(x == null)return 'url(/Style Library/MyStyles/Black and Blue/WebPartTitleBgLeft.jpg) top left no-repeat'})(this.previousSibling));
}

The “expression” basically tries to duplicate the “firstChild” behavior. I got it from a commenter in this post. Although you can do an easier expression, like this, (which Heather suggested):

.ms-WPHeader td
{
  background: expression(this.previousSibling==null?'rgb(242,181,15) url(/images/wpright.gif) no-repeat top right':'');
}

it won’t work. It works if you’re using an attribute like background color, but for whatever reason, it won’t work for a background-image. (My guess is becaue a background-image url needs quotes around the URL, and that doesn’t work if the expression needs to be in quotes as well.) A couple things to note:

  1. For some reason, I had to use an absolute path to my image file in my “expression”. This is a pain because it means you have to have different style sheets per Site Collection, and you need to know what your URL is going to be ahead of time, if you plan to package this file into a solution package.
  2. Expressions are generally bad to use in CSS; they are poor performing. However, in this case, I figure it’s a small user base who is still on IE6, so the impact is neglible.

Getting IE6-Specific Stylesheet to Work with Various Stylesheets
The next problem I ran across was this: although I have one “base” stylesheet for my site, the site owners wanted various “themed” style sheets (stylesheets they pick from the Master Page selection page, not actual SharePoint “themes”), so each site will have the same basic layout, but the colors in the site, and specifically the images (which have colors, necessitating different images per stylesheet), will be different. My problem was that I couldn’t just say “If you’re using IE6, use this stylesheet” in the Master Page, because the IE6 stylesheet references particular images that belong to a particular themed CSS. I needed to be able to say “If you’re using the ‘Black and Blue’ style sheet, grab the ‘Black and Blue’ IE6 stylesheet as well.”

I decided to create a folder inside the Style Library with a custom name, like “MyStyles”. I put my base style sheet in there. Then I created a new folder for each theme inside the “MyStyles” folder. That means I had a folder called “Black and Blue”, and I put the following three things in there: the BlackAndBlue.css themed CSS file, a file called IE6.css, and all the images that the theme used.

My goal was to be able to dynamically add a reference to the correct IE6.css file for the current CSS theme being used. I decided to use some javascript to loop through the “link” tags at the top of the page in my Master Page. Once I found the reference to the currently applied CSS file, I captured the path (“/Style Library/MyStyles/Black and Blue/BlackAndBlue.css”), then swapped out the name of the CSS file (“BlackAndBlue.css”) with “IE6.css”, and then added a new tag to the page using the new URL (“/Style Library/MyStyles/Black and Blue/IE6.css”).

Here’s what I placed in my Master Page <head/> tag:

<SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/MyStyles/BaseStyles.css%>" runat="server"/>

<![if IE 6]>
<script language="javascript">
   var linkTags = document.childNodes[1].getElementsByTagName("link");
   for (var i = 0; i < linkTags.length; i++) {
       var href = linkTags[i].href;
       if (href.indexOf("BaseStyles.css") < 0 && href.indexOf("MyStyles") >= 0) {
           var urlParts = href.split("/");
           var cssName = urlParts[urlParts.length - 1];
           switch (cssName) {
               case "BlackAndBlue.css":
                   document.write('<link rel="stylesheet" type="text/css" href="' + href.replace(cssName, "IE6.css") + '">');
                   break;
               case "IE6.css":
                   break;
           }
       }
   }
</script>
<![endif]>

Here’s what the Web Part title looks like in IE8:

Here’s what it looks like in Internet Explorer 6 without an alternative CSS:

Here’s what it looks like in IE 6 with the alternative stylesheet: