Thursday, September 21, 2006

Mini Howto: CSS + JSP

On a recent project I noticed that I was duplicating a bunch of CSS code. Because this duplication is evil, and would keep me up at night, I decided to do something about it.

I quickly noticed that all the code that was being duplicated depended on one magic parameter, lets call it foo. If only, I thought, I could parameterize the value of foo, I'd be all set. But you simply can't do that in CSS (gosh I dislike languages that don't give you basic abstraction capabilities, like variables).

But I do have a language handy which does do what I want - JSP. JSP, after all, does exactly what I want for HTML files, so why can't I apply that to CSS. Of course I can. And did. Here's the recipe.

First, start with your separate files, like:

/* basic_look.css */
body { background-image: url('images/basic_bg.gif'); }

/* fancy_look.css */
body { background-image: url('images/fancy_bg.gif'); }

Next, put them in a single file, and make use of your token:

/* look.css.jsp <-- notice the .jsp here */
body { background-image: url('images/${foo}_bg.gif'); }

At this point, you might think the final step is to update the document that uses this as so:

<!-- Old Approach -->
<link rel="StyleSheet" href="basic_look.css"  type="text/css"/>
<link rel="StyleSheet" href="fancy_look.css"  type="text/css"/>


<!-- New Approach -->
<link rel="StyleSheet" href="look.css.jsp"  type="text/css"/>

But if you did just that, you would actually be wrong. (Hence the need to write up this howto, so 2 years from now when I want to recall how to do this, I can search my blog and find out how again.)

The problem is that a .jsp document, by default, produces a header that says the content type is text/html. This is usually a good thing. Except when it's not. And now it's not.

So you need to make the above change and change your .css.jsp file to:

<%@ page language="java" contentType="text/css" %>
/* look.css.jsp <-- notice the .jsp here */
body { background-image: url('images/${foo}_bg.gif'); }

Now you're all set. Whew, with that taken care of I should have no problem sleeping at night.


  1. Anonymous2:31 AM

    You might also consider using SiteMesh decorators to help with this kind of stuff. One advantage there is that it's pluggable into just about any MVC framework.

    PS - I hate this Blogger signin crap, why they can't cookie this stuff correctly is beyond me. C'mon google!