Introducing ThemeRoller: Design & Download Custom Themes for jQuery UI

Posted by Scott on 06/08/2008

01/11/2009 Note: This article is based upon an version of jQuery UI ThemeRoller. We will be posting an updated article very soon which will detail the new features and changes in the newest version of ThemeRoller. For now, please visit our case study jQuery UI and ThemeRoller or visit the jQuery UI ThemeRoller documentation to find out about the new release.

imageWhen the jQuery team approached us to design the new de-facto visual design theme for jQuery UI, we were more than excited to help out. Here at Filament, we’re big fans of jQuery and frequently contribute plugins and ideas to the community; any opportunity to help jQuery continue to grow and gain traction is always in our best interest.

Not long after starting our work on the default theme, and some playing with alternatives, we realized our CSS work could be translated into a web application to allow others to create and share custom themes as well. Based on this idea, ThemeRoller was born.

\

ThemeRoller for jQuery UI Screencast v4 from filamentgroup on Vimeo.

So what is ThemeRoller?

ThemeRoller is a web app that offers a fun and intuitive interface for designing and downloading custom themes for jQuery UI.

Using a simple web interface, a user can configure settings for colors, background textures, and fonts — including variations for default, hover and active states — for the component pieces of all jQuery UI widgets. The system lets users experiment, easily preview the custom settings, and quickly generate a ZIP containing everything necessary for a cohesive set of styled jQuery UI components.

ThemeRoller UserInterface\

ThemeRoller puts all the parameters users need to create custom themes together

The ThemeRoller Interface

The interface for ThemeRoller is categorized mainly by the interaction states default, hover, and active. Each of these states allow configuration for the following:

  • Background Color: Utilizes the Farbtastic jQuery plugin to deliver slick inline color picker tools.
  • Background Texture: Choose from an array of textures such as glass, smooth gradients, dots, stripes and more.
  • Texture Opacity: Change the opacity of the texture.
  • Border Color
  • Text Color
  • Icon Color

In addition to the interaction states above, ThemeRoller also allows for configuring global style settings such as font family, font weight, and font size (with a choice of pixel or em units).

Custom-Generated Textures and Patterns

Color values alone can lead to a pretty boring user interface. For additional customization, ThemeRoller offers a choice of the following custom textures and patterns:

Textures:

Flat Glass HighlightSoft HighlightHard InsetSoft InsetHard

Patterns:

DiagonalsSmall DiagonalsThick DotsSmall DotsMedium WhiteLines GlossWave

Using server-side technologies, we were able to use the textures above in combination with theme preferences to generate customized background images and icons for the themes.

image

We used server-side technologies to combine color, texture, and texture opacity in theme backgrounds.

The resulting images are completely opaque PNGs, allowing them to look nice in older versions of Internet Explorer without any alpha-transparency hacks.

Downloading Themes — all images and styles included

What good would a tool like ThemeRoller be without the ability to use your theme in the end? Thankfully, ThemeRoller has a “Download Theme” button built-in which will generate a ZIP file containing all of theme assets. Images included in your download will be generated to your specifications and saved as high-quality PNG files.

As for the CSS, one stylesheet will be included containing styles for all of the current jQuery UI components. Each component’s styles are neatly separated from the rest and have no other dependencies, so you should be able to plug them right into your site without trouble. Themes are also constructed using EMs, so the components will scale and size proportionately to their text size. All of the themes are tested to work on all modern browsers such as Safari, Firefox, Opera, and of course Internet Explorer.

The Theme Gallery: Pre-Rolled Themes

ThemeRoller themes can be viewed via permalink URLs, so we included a gallery of pre-designed themes to choose from. The theme gallery is accessible through the tab strip located at the top of the application interface. In addition to providing a visual example of the theme’s style, each “thumbnail” is also entirely functional jQuery UI component that let users see and interact with hover and active states!

Theme Gallery

The Theme Gallery shows visual and interactable examples of each theme.

How we roll(ed)

ThemeRoller is actually the sum of many rounds of experiments with theming and rebranding that we’ve gone through at Filament Group. Usually, our rebranding configurations are handled primarily on the front-end, taking advantage of CSS @import directives to compile themes from a complex separation of structural and theme-specific styles. While this approach tends to be very effective, it also requires a certain level of discipline and hands-on care to maintain it as project development continues. In the case of ThemeRoller, we were fortunate to have access to back-end technologies such as PHP and its graphics library; which we found to be incredibly powerful in delivering fast stylesheet and image manipulation back to the front end.

The magic behind ThemeRoller begins with the not-so-abstract concept of a variablized CSS file. By storing CSS rules in variables, we were able to repeat values across many component styles to create visually cohesive themes. Generally speaking, CSS as a language has no concept of any dynamic values such as variables; so in order to take advantage of variables in a stylesheet it must be generated using a server-side language such as PHP. The PHP involved in creating a dynamic stylesheet is actually quite simple, basically declaring variables for any commonly used CSS rules and assigning their values based on defaults (with an option to override). What that boils down to is something like this:

//declare a default background color variable
//and assign it a value of 'e6e6e6' (light gray)
   $bgColorDefault = 'e6e6e6';
//if there's a get request specifying a different default background color, use its value instead
   if(isset($_GET['bgColorDefault'])) {$bgColorDefault = $_GET['bgColorDefault'];}

As you can see, we declared a variable for the default background color and assigned it a value. Then we checked to see if any “get” request exists that specifies an override of that value, and if so, we redefine our default background color using that value instead. This is the foundation upon which ThemeRoller works, repeating this process for any repetitive styles across all of the jQuery UI components.

Rolling custom images with phpThumb

To generate these images based on user preferences, ThemeRoller leverages PHP’s GD lib and a helpful library known as phpThumb. phpThumb is a fantastic graphics library developed by James Heinrich of silisoftware.com. Using phpThumb, we are able to generate images via a querystring, utilizing many techniques commonly known to desktop applications such as Adobe Photoshop. In ThemeRoller, these query strings are compiled using the same variables as above, assuring the same style preferences cascade through the entire interface; right down to the color of the icons and the transparency of the textures. For example, the following is a query string used to generate our default background image in the jQuery UI themes:

$bgImgUrlDefault = "images/?new=$bgColorDefault&w=$bgWD&h=$bgHD&f=png&q=100&fltr[]=over|textures/$bgTextureDefault|0|0|$bgImgOpacityDefault";

Looks confusing at first, but let’s break it down to its component variables:

  • new = $bgColorDefault Create a new image with a background color specified by the variable $bgColorDefault.
  • w = $bgWD Set the image width to the value specified in the variable $bgWD.
  • h = $bgHD Set the image height to the value specified in the variable $bgHD.
  • f = png Return the image as a PNG file.
  • q = 100 Set the image quality to 100%
  • fltr[] = over|textures/$bgTextureDefault|0|0|$bgImgOpacityDefault Apply a filter for an overlay image. Use the image file specified in the $bgTextureDefault variable. Set its opacity to the value of the $bgImgOpacityDefault variable. Filter parameters are delimited by vertical bars.

As you can see above, phpThumb gives us access to some very powerful image editing capabilities; entirely from query string parameters. For more info on using phpThumb, visit the phpThumb project page.

Sprinkling-on some Ajax Enhancements

For users with modern browsers, most changes made to a theme will instantly reflect in the theme preview beneath the application interface. This quick update is handled by appending a new CSS file to the HEAD section of the page, including a query string containing the parameters chosen in the current ThemeRoller settings. To be fair, calling this “Ajax” isn’t entirely accurate, but it does work asynchronously to update the page, giving it an Ajax-like feel.

image

Saving the State

Also updating as changes are made is the theme URL. At any point during a ThemeRoller session, the URL can be bookmarked or copied for later reference. We do this through URL hash fragments identical to the query strings used to generate a theme. If you happen to open a ThemeRoller URL containing a hash fragment, it will be quickly converted to a query string and an appropriate theme will be generated.

Rolling on Progressive Enhancement

Like much of what we do at Filament Group, ThemeRoller is built using the principles of progressive enhancement. This means that while the application makes use of advanced scripting and presentation, it will still work on devices that don’t support javascript at all. Without javascript, the color pickers appear as regular text inputs, and the textures are still accessible as HTML select menus. A “Preview” button, not visible to javascript users, allows for viewing any changes made to a theme. Previewing a theme will also generate a bookmarkable, shareable url to the current theme state. The ThemeRoller interface, as viewed by a non-javascript device, can be seen below.

ThemeRoller interface withoutjavascript

Let us know what you think!

ThemeRoller can be found in the Themes section of the jQuery UI website. You can also reach it by direct url at ThemeRoller.com. We hope you enjoy using ThemeRoller as much as we’ve enjoyed building it! If you get a chance to try it out, we’d love to hear what you think. Please leave a comment for us below.

600

Comments

<div id="commentNumber1" class="commentEntry">
<p>Great work !!!

btw, in FF 3 RC2 it doesn’t update colors when making custom theme.

</div>
    <p class="posted"><a href="#commentNumber1">Comment</a> by

Claudio on 06/09  at  05:14 AM

<div id="commentNumber2" class="commentEntry">
<p>This is realy REALY cool stuff !

</div>
    <p class="posted"><a href="#commentNumber2">Comment</a> by

Rick on 06/09  at  05:25 AM

<div id="commentNumber3" class="commentEntry">
<p>when I download my custom theme, it’ll contain the default textures.

</div>
    <p class="posted"><a href="#commentNumber3">Comment</a> by

Claudio on 06/09  at  10:18 AM

<div id="commentNumber4" class="commentEntry">
<p>That’s a really nice tool that makes life easier. Hopefully we’ll see more projects similar to this one in the future.

</div>
    <p class="posted"><a href="#commentNumber4">Comment</a> by

Dan Cole on 06/09  at  10:19 AM

<div id="commentNumber5" class="commentEntry fg">
<p>@ Claudio : Thanks. We’ve posted a small message at the top of this post noting that a few features are still getting tuned to the new server. The jQuery UI team is close to having a fix on the theme download issue though.

We will post an update comment here when things are good to go.

</div>
    <p class="posted"><a href="#commentNumber5">Comment</a> by

Scott (Filament) on 06/09  at  10:22 AM

<div id="commentNumber6" class="commentEntry fg">
<p>@ Rick, @Dan, @Claudio: Thanks, we’re glad you like it! Be sure to check it again later today when the traffic dies down; the UI server is getting hit hard at the moment!

</div>
    <p class="posted"><a href="#commentNumber6">Comment</a> by

Scott (Filament) on 06/09  at  10:24 AM

<div id="commentNumber7" class="commentEntry">
<p>it’s so cool that...you’re really sure the traffic will die down? :-)

</div>
    <p class="posted"><a href="#commentNumber7">Comment</a> by

Claudio on 06/09  at  10:31 AM

<div id="commentNumber8" class="commentEntry">
<p>This is FANTASTIC!!! Thank you so much!!! Now I can finally develop my cool looking web apps with confidence!

</div>
    <p class="posted"><a href="#commentNumber8">Comment</a> by

unclef on 06/09  at  01:29 PM

<div id="commentNumber9" class="commentEntry fg">
<p>@ unclef: Glad you like it. Enjoy!

</div>
    <p class="posted"><a href="#commentNumber9">Comment</a> by

Scott (Filament) on 06/09  at  02:10 PM

<div id="commentNumber10" class="commentEntry fg">
<p>Update: ThemeRoller is now optimized and MUCH faster to use (Thanks John Resig). The download generator should be working well now too. Enjoy!

</div>
    <p class="posted"><a href="#commentNumber10">Comment</a> by

Scott (Filament) on 06/09  at  03:13 PM

<div id="commentNumber11" class="commentEntry">
<p>is ThemeRoller open source? can I download this theme roller app?

</div>
    <p class="posted"><a href="#commentNumber11">Comment</a> by

steve on 06/10  at  08:15 AM

<div id="commentNumber12" class="commentEntry">
<p>Excellent!

But what could possibly make it better?

Two textures per setting, the second overlaying the first.

Why?

What a shame that stripes and dots can’t be reflective. So, instead of just millions of possibilities, why not gazillions with extra artistic choice and flair?

I bet that would take the sharp minds at Filament all of 30 minutes to implement.

Anyone else care for blended textures?

</div>
    <p class="posted"><a href="#commentNumber12">Comment</a> by

David on 06/10  at  10:35 PM

<div id="commentNumber13" class="commentEntry">
<p>So, the first items would be:

Background Color

Background Texture
Background Texture Opacity

Foreground Texture Overlay
Foreground Texture Overlay Opacity

Just a thought.

</div>
    <p class="posted"><a href="#commentNumber13">Comment</a> by

David on 06/10  at  10:50 PM

<div id="commentNumber14" class="commentEntry fg">
<p>@David: Thanks, we’re glad you like ThemeRoller. The effect you’re suggesting could probably be achieved by adding some combined texture images to the menus (glossy stripes, etc). This could offer more design options without letting the interface become overwhelming. We’ll likely add some more textures in the near future so stay tuned!

</div>
    <p class="posted"><a href="#commentNumber14">Comment</a> by

Scott (Filament) on 06/12  at  10:40 AM

<div id="commentNumber15" class="commentEntry">
<p>Excellent tool. Unfortunately (for me), not very right-to-left friendly. Some elements reversed, some misaligned, etc.... However, easily fixable. Thanks!

</div>
    <p class="posted"><a href="#commentNumber15">Comment</a> by

Felix Gartsman on 06/13  at  04:23 AM

<div id="commentNumber16" class="commentEntry">
<p>This is fabulously useful and smart!

But why not include already in the theme roller the menu and button components from your other article http://www.filamentgroup.com/lab/developer_your_own_jquery_themeroller_ready_components/ ?

Looking forward to the new version including the grid and layout widgets!

This is hot, hot, hot!

</div>
    <p class="posted"><a href="#commentNumber16">Comment</a> by

Ernest on 08/05  at  09:43 AM

<div id="commentNumber17" class="commentEntry">
<p>This is awesome app.I just to love use it again and again.

</div>
    <p class="posted"><a href="#commentNumber17">Comment</a> by

speedovation on 08/14  at  12:05 PM

<div id="commentNumber18" class="commentEntry">
<p>does anyone know the Tabs app that is used in the ThemeRoller, the one with the floating tabs about the content (lower left side) of the demo

</div>
    <p class="posted"><a href="#commentNumber18">Comment</a> by

patrick on 08/19  at  10:44 AM

<div id="commentNumber19" class="commentEntry fg">
<p>@patrick: All of the theme-able widgets shown in the demo are part of jQuery UI, based on the jQuery library.&nbsp; You can customize a theme and download sample markup here: <a href="http://themeroller.com/" rel="nofollow">http://themeroller.com/</a>.&nbsp; You’ll also need to download the latest jQuery UI scripts: <a href="http://ui.jquery.com/download" rel="nofollow">http://ui.jquery.com/download</a>.

</div>
    <p class="posted"><a href="#commentNumber19">Comment</a> by

Maggie (Filament) on 08/19  at  11:14 AM

<div id="commentNumber20" class="commentEntry">
<p>I’ve just been adding jquery ui tabs to an app, but since I dislike the default “flora” theme I thought I’d try to use themeroller…  Unfortunately I ran into several serious snags :(

1) themeroller has been taking several eons to load up.  this is further exacerbated when one wishes to use the “theme gallery”
2) I wished to use the “cupertino” theme, but there seems to be no option to download that exact theme, just one that has been generated based upon it
3) the generated theme that I downloaded seems to be incomplete - when I attempt to use it my tabs (which work with the flora theme, code identical to the documentation example) do not get styled as tabs

Having run into 3 I thought I was stuck and would have to revert using “flora"… I have since discovered by reading the source code of the “demo” file that if I adjust my html and give the <li> items I’m using for my tabs the “ui-tabs-nav-item” class then it will work.

The theme generated by themeroller is thus unfortunately incomplete.  If the tabs stuff is incomplete, it makes me wonder what else is incomplete.  It was rather frustrating.  :(

</div>
    <p class="posted"><a href="#commentNumber20">Comment</a> by

Steve on 09/18  at  06:14 AM

<div id="commentNumber21" class="commentEntry">
<p>There seems to be a problem with phpThumb where it generates error images when you use a 3-character hex value (#fff) instead of the full six. You might want to put some error messaging on those text fields —&nbsp;it’s a mistake that likely to be repeated semi-frequently.

</div>
    <p class="posted"><a href="#commentNumber21">Comment</a> by

Chad T. on 09/18  at  06:05 PM

<div id="commentNumber22" class="commentEntry fg">
<p>@Steve: Sorry you ran into trouble.

1) Agreed. The whole jQuery site is undergoing some server upgrades now to address the speed issues.
2) I’m not sure I follow. If you click the Cupertino theme, it will reload ThemeRoller with that theme’s settings. From there, you can either make additional tweaks or just click the download button.
3) We’ll take a look at that. You’re right that those classes should be added by the plugin. For now though, it probably wouldn’t hurt much to just add them to your markup so you can use themeroller themes.
We’ll check it out, though. I think our selectors could be based off of the parent ui-tabs selector instead, but I think we were trying not to use elements in our selectors. Consider it on the to-do list :)
Good luck and thanks for the feedback!

@Chad: Thanks. We’ve been meaning to add some validation for those. Will do.

</div>
    <p class="posted"><a href="#commentNumber22">Comment</a> by

Scott (Filament) on 09/23  at  12:19 AM

<div id="commentNumber23" class="commentEntry">
<p>Excellent work on ThemeRoller!

I’m viewing it via IE 7 and I noticed at the Tabs section demo that the ‘tabs’ are ‘detached’ to its boxed content.

Was this an IE only bug? Looks okay on FF 3.0.2 and the latest build of Google Chrome.

</div>
    <p class="posted"><a href="#commentNumber23">Comment</a> by

don go on 09/26  at  02:32 PM

<div id="commentNumber24" class="commentEntry">
<p>this is hot!

</div>
    <p class="posted"><a href="#commentNumber24">Comment</a> by

Noah on 10/21  at  10:47 AM

<div id="commentNumber25" class="commentEntry">
<p>good work!

做的很好

</div>
    <p class="posted"><a href="#commentNumber25">Comment</a> by

arn gu on 11/29  at  12:33 PM

<div id="commentNumber26" class="commentEntry">
<p>Hi all,

Theme roller behaves ugly in IE6…
Greate job ‘til now but still not completed…

</div>
    <p class="posted"><a href="#commentNumber26">Comment</a> by

Francisco on 11/30  at  12:44 PM

<div id="commentNumber27" class="commentEntry">
<p>hot.... phew---

</div>
    <p class="posted"><a href="#commentNumber27">Comment</a> by

michael f. odsinada on 04/16  at  10:11 PM

<div id="commentNumber28" class="commentEntry">
<p>Thanks for a great tool.

A. It would be useful if the dates on these comments had the year also.
B. The link at the bottom of your article labeled “Themes section of the jQuery UI website” points back to this article. I think it should point to http://jqueryui.com/themeroller/

</div>
    <p class="posted"><a href="#commentNumber28">Comment</a> by

RobShaver on 04/30  at  01:57 PM

<div id="commentNumber29" class="commentEntry">
<p>is it me or the rounded corners are still missing for IE??

http://www.marblehost.com/uptime-guarantee.php

</div>
    <p class="posted"><a href="#commentNumber29">Comment</a> by

99.9% Uptime Guarantee Hosting on 05/06  at  02:08 AM

<div id="commentNumber30" class="commentEntry">
<p>Excellent tool!&nbsp; Except for one thing.&nbsp; When I download the zip for the custom theme (using the “Download” button on the right side), WinZip reports the zip file is invalid, “bummer!”

If I use the quick download link “Current (stable)” this zip file is good.
BTW - I’m using WinZip Pro version 11.  And I’ve also tried this on three different computers, one on a completely different network connection.  WinZip says its invalid in all three cases.

</div>
    <p class="posted"><a href="#commentNumber30">Comment</a> by

Mike Witherspoon on 05/15  at  12:46 PM

<div id="commentNumber31" class="commentEntry fg">
<p>@Mike: Sorry about that. The download builder issue is currently being worked out. The fix will go up soon. It currently works fine on Mac but there are issues on Windows machines.

</div>
    <p class="posted"><a href="#commentNumber31">Comment</a> by

Scott (Filament) on 05/15  at  04:59 PM

<div id="commentNumber32" class="commentEntry">
<p>Issues!&nbsp; Windows!&nbsp; No way.

I did eventually find a link on the UI disscussion group reguarding this issue, http://groups.google.com/group/jquery-ui/browse_thread/thread/e8de54f7d97787ac
There is a link here to download all the available themes.
Thanks.

</div>
    <p class="posted"><a href="#commentNumber32">Comment</a> by

Mike Witherspoon on 05/15  at  05:33 PM

<div id="commentNumber33" class="commentEntry">
<p>Very nice work and the Firefox Add-on comes in handy. Is the server-side code that handles the theme generation publicly available? You mention the basics of how it works in this post, I was just wondering if the source is there to see how it all comes together? Cheers.

</div>
    <p class="posted"><a href="#commentNumber33">Comment</a> by

Baz on 07/29  at  07:17 AM

<div id="commentNumber34" class="commentEntry">
<p>Are you planning on open sourcing themeroller? I would love to understand how it was developed and contribute enhancements.

</div>
    <p class="posted"><a href="#commentNumber34">Comment</a> by

Andrew Blank on 10/06  at  10:23 AM

<div id="commentNumber35" class="commentEntry fg">
<p>Hi Andrew - We’ve donated ThemeRoller to the jQuery UI project and the team has decided to keep the tool closed sourced until the theming system matures a bit more. Eventually, TR will be open source, but it won’t be in the short term.

</div>
    <p class="posted"><a href="#commentNumber35">Comment</a> by

Todd (Filament) on 10/06  at  10:35 AM

<div id="commentNumber36" class="commentEntry">
<p>Thanks for a great tool.

But is there a way to reload a custom theme into ThemeRoller? When I load a link with the theme in the hash, the page gets that theme, but ThemRoller still defaults to Smoothness.

</div>
    <p class="posted"><a href="#commentNumber36">Comment</a> by

Dan Kloke on 11/09  at  07:57 PM

<div id="commentNumber37" class="commentEntry">
<p>How would I create “apple-like” dialogs?&nbsp; Thanks!

</div>
    <p class="posted"><a href="#commentNumber37">Comment</a> by

Kevin on 11/24  at  07:48 AM

<div id="commentNumber38" class="commentEntry">
<p>ThemeRoller not downloading :(

Very good..

</div>
    <p class="posted"><a href="#commentNumber38">Comment</a> by

Oğuzhan SARI on 12/13  at  11:34 PM

<div id="commentNumber39" class="commentEntry">
<p>hi, thanks for your job, great!

..but i’ve got a problem: when i download my custom theme i can’t find css directory unless i set the theme folder name… and if i set it, in the zip file i dowload i can’t find the customization i made! there’s something wrong in your scripts? hope you can correct it, cause themeroller is a wonderful tools!!! thanks again (and sorry for my english...)

</div>
    <p class="posted"><a href="#commentNumber39">Comment</a> by

mbz on 03/30  at  02:28 PM

<div id="commentNumber40" class="commentEntry">
<p>Simply awesome. just started playing around with it today and I can’t thank you enough for helping me in solving my css issues (i am bad at it). Now I just use this and have a site wide styling and need not depend on a designer to make a jquery ready theme

</div>
    <p class="posted"><a href="#commentNumber40">Comment</a> by

Ramjee on 05/14  at  11:36 AM

<div id="commentNumber41" class="commentEntry">
<p>Absolutely love this, thanks!

</div>
    <p class="posted"><a href="#commentNumber41">Comment</a> by

Addy Yeow on 05/20  at  01:41 AM

<div id="commentNumber42" class="commentEntry">
<p>Great Tool. I use the themeroller in two of my websites. Unfortunately, the themeroller uses allways the standardtheme, if the website is loading. Because it is not possible to define another starttheme (cross-site-scripting is not allowed), it would be nice, if I can define my own theme at start with the url-parameters (for example: “#ffDefault=Lucida+Grande&amp;#x2C;+Lucida+Sans...").

</div>
    <p class="posted"><a href="#commentNumber42">Comment</a> by

Erik on 09/10  at  04:38 AM