Weston Ruter

Web application developer in Portland, Oregon

Multiple Borders via CSS box-shadow

To make multiple borders appear around an element, the traditional approach has been to nest multiple elements and apply a different border to each. For example, to put a rainbow border on an element:

I have rainbow borders!

This approach uses seven div elements. However, there is an alternative that avoids the need for so many superfluous elements: the new CSS3 box-shadow property. A key feature of this property is that it allows for multiple shadows to be supplied at once:

box-shadow: none | <shadow> [ , <shadow> ]*

When multiple shadows are supplied, they can be positioned on top of each other to create a multiple-border effect. Using the box-shadow property in this way requires support for the "spread radius" value, and this is not currently supported by WebKit (includes Safari and Chrome). However, Firefox 3.5 (now available as a preview release) does support the box-shadow spread radius, and if using that browser, the following example should look identical to the example above:

I have rainbow borders!

Using box-shadow for multiple borders not only eliminates the need for extra markup, it also allows the multiple borders to be easily rounded on corners simply by adding the border-radius property (see screenshot from Firefox 3.5):

I have rainbow borders with rounded corners!

To accomplish the above with multiple nested elements, you would have to tediously increase the border-radius for each wrapped element in order to get the corner arcs to fit together properly.

I suppose using box-shadow to implement borders is a kind of hack (the technique requires setting margins because the shadows don't effect page flow), but we're celebrating the compeltion of Firefox 3.5 by showcasing hacks like these! It would be great if multiple borders could simply be specified on a border property just as is possible with box-shadow. Each subsequent border defined could wrap around the previously defined borders. The property could be defined:

border: none | <border> [ , <border> ]*

In any case, the box-shadow property still has a benefit of allowing the borders to blend together by specifying the box-shadow's blur radius (see screenshot from Firefox 3.5):

I have blended rainbow borders!

It's exciting to see how Mozilla is implementing bleeding-edge CSS features in Firefox as we have become accustomed to from the WebKit team. Great work everyone!

Detecting Support for data: URIs

Updates: Added note at end to respond to V1’s comment, and fixed the “awkward CSS syntax” which was actually a big typo (thanks Harmen).

The data: URI scheme is now supported by the most current version of every major browser, including Internet Explorer. Because of this I wanted to use CSS background images encoded with data: URIs in a current project at Shepherd Interactive. Why? The first rule of High Performance Websites is to Minimize HTTP Requests. By storing background images directly in the stylesheet only one HTTP request is then necessary to fetch the stylesheet and the images all at once. Furthermore, by giving that stylesheet a far-future cache expiration date the browser will never need to request it again.

However, while every browser vendor’s current version supports data: URIs, older browsers like MSIE 7 do not. Therefore it is necessary to also have fallback CSS rules to serve externally-referenced background images. I came up a way of doing this by utilizing the following script which I place as an inline script in the document head:

var data = new Image();
data.onload = data.onerror = function(){
	if(this.width != 1 || this.height != 1)
		document.documentElement.className += " no-data-uri";
}
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";

This script attempts to load a 1×1 pixel via a data: URI. If the onload callback fires and it detects that the image’s width and height are each a single pixel, then the browser supports data: URIs. Otherwise the browser does not support such URIs and a class name is added to the document root so that fallback CSS rules can be written, for example:

#foo {
    background-image:url("data:image/png;base64,<...>");
}
html.no-data-uri #foo {
    background-image:url("images/foo.png"); /* fallback */
}

In this way, CSS rules can define background images that utilize data: URIs only for browsers that support them, while at the same time older browsers still render the content properly due to the fallback rules. Note that for browsers that support data: URIs, the fallback CSS rule above will never be applied and thus its externally-referenced background image will never be downloaded. However, if the browser does not support data: URIs, then the resources will essentially be downloaded twice, but that’s the price you pay for using an old browser. In any case, when the images are tiny (<1KB) then the overhead is minimal for non-supporting browsers, and your development process is greatly eased since you don’t have to hassle with creating image sprites (which are sometimes impossible anyway); those who use current browser versions will be rewarded as will the generations of Internet users to come.

Open Scriptures Presentation at BibleTech:2009

As previously announced, I had the privilege of presenting the Open Scriptures project at BibleTech:2009. Multimedia of the talk is available:

Newly Designed Open Scriptures Website with Blog

I haven’t formally announced this here yet, but there is a newly designed Open Scriptures website with blog. Future posts regarding Open Scriptures will be posted there. There are two new posts, the first regarding the recently-unveiled exciting Tagged Tanakh project, and the second about redeeming the ill-fated Re:Greek Open Source Initiative with a call for participation. Check them out and subscribe to the feed.

Please also follow Open Scriptures on Twitter.

Join in on the discussion on the Google Group.

“Old” Mainly Linguistics Stuff from College Days

This morning I got inspired to go over some relatively old stuff that I worked on in college. There are several linguistics projects that I think are pretty interesting (the first three especially):

And then I found an old chart I made of my racial makup.

And then there is a little web app for SPU’s Nickerson Signal which attempts to model a traffic signal so that upcoming crossing times can be predicted. (Didn’t end up accurately modeling reality.)

And finally there is the Semantic Linking tool (mentioned in my last post) which is a prototype for an upcoming tool which enables contributors to link the semantic units between manuscripts and translations.