Wednesday, August 12, 2009

WebKit border radius and cascading styles don't always mix

Since starting the new job in January I've had to learn more about developing for the web than I ever have. One of the fascinating (and frustrating) aspects has been the way different browsers render the same code. The only web content I've written prior to this job was a very basic set of static pages for the Burlington Irish Heritage Festival and for an intranet web application where the company dictated which browser was to be used. But with the new gig I'm in the real world. That means every change I make needs to test against 4 or 5 browsers. And that's just on my development box, once it goes into QA the application is tested against over 20 different browser and OS combinations.

So I've started to familiarize myself with the various rendering engines used by the major browsers. One of the big ones is the WebKit open source engine. It serves as the rendering engine for some of the browsers I need to support; Safari on Windows and Google's Chrome. Recently we encountered a little WebKit specific gotcha that I wouldn't have expected. It has to do with a WebKit specific CSS attribute, -webkit-border-radius. It's a wonderful attribute that when set instructs the WebKit browsers to round the corners of an element. This post has a very good summary of the -webkit-border-radius attribute (and it's Mozilla equivilent, -moz-border-radius). The important point for this discussion is -webkit-border-radius is a shortcut declaration.

The problem we encountered had to do with how the -webkit-border-radius attribute behaved when used in a cascading style. The application on which I work has one style sheet defined for application wide default styles and then uses additional files to adjust the styles as needed. So, for example, the application default stylesheet may define a class like this:

.someRoundedThing { -webkit-border-radius: 4px; }

which will will cause a WebKit browser to round the corners of an element decorated with that class. Another style sheet could then declares following:

.someRoundedThing { -webkit-border-radius: 8px; }

If a page pulls in the application style sheet and then the alternate style sheet what should happen is the elements on that page which are decorated with the "someRoundedThing" class should be twice as rounded (again, only in WebKit browsers) than on a page where only the application default styles are included. But this wasn't working as expected.

In order for the page defined style to work we had to declare the alternate -webkit-border-radius value using the more verbose, four value declaration. Like this:

.someRoundedThing { -webkit-border-radius: 8px 8px 8px 8px; }

Declaring each corner's radius individually also worked:
.someRoundedThing {
-webkit-border-top-left-radius: 8px;
-webkit-border-top-right-radius: 8px;
-webkit-border-top-bottom-radius: 8px;
-webkit-border-top-bottom-radius: 8px;
}

While I'm not certain why this is going on, I assume it is related to the differences in implementation outlined in this post.

So while I like using the shortcut declarations for their terseness it appears they can lead to problems if your not careful.