Saturday 21st of January 2017 06:19:46 PM

Creating Themes with CSS and JavaScript


You probably have already heard about themes, but you might not know how to incorporate them into your own site.

Commonly, a theme refers to a set of graphics, color, and layout definitions that can be applied to a user interface to give it a specific look and feel. A "theme-able" application lets a user select between different looks of this application.

A well-known representative is Winamp or Netscape 6. The concept of themes is a relatively new and important development in the evolution of modern GUI applications. Themes give users the ability to choose or create individual interfaces easily for enabled applications without the need to recompile them. You might even consider this as an end-user related aspect of the growing open-source idea.

However, back to some Essential JavaScript and web application development. Clean markup, a set of style sheets, some cookie crumbs, and a pinch of JavaScript will let your visitors choose between different looks of your site and store this as their preference. However, even if you're not interested in doing this, you might read on to learn a little more about "good style."

System requirements

Basically, you only need a very basic set of technologies for the solution: some CSS support and a working JavaScript engine. This means you can run our script in, for example, both Netscape Navigator and Microsoft Internet Explorer versions 4 and up, Mozilla, Opera 4 and up, and Konqueror.

The drawback is that it may not be possible to use CSS in full effect for older 4.x platforms because of erroneous and incomplete CSS support. As a rule of thumb you should only try it with the newest browsers available (IE 5.5, Netscape 6, Opera 5, and Konqueror). The RichInStyle site provides a good list of CSS bugs and support.

Some background

Basically any application has to match one important prerequisite to switch between different themes: it must separate the data of the application -- the model -- from the view of the data. Both components are connected and controlled by a controller.

In terms of OOP, this is called the model-view-controller (MVC) concept, Java's GUI toolkit Swing is probably the most famous representative.

Unless you're totally new to web development, this concept should sound familiar to you. HTML and XML-based languages are designed to probably fairly safe, but trying to push an element upward on thepage is a generally bad idea.

There is one other way for a floated element to exceed itsparent's inner left and right edges, and that's when thefloated element is wider than its parent. In that case, the floatedelement will simply overrun the right or left inneredge -- depending on which way the element is floated -- in itsbest attempt to display itself correctly. This will lead to a resultlike give structure to information, allowing you to form a model of your data. In addition to that, you can define the presentation -- the view -- of any element using CSS. JavaScript is the active glue between the two static components. Hosted in a browser, it forms the controller component.


After identifying the components, let's specify their roles in relation to our task:


1. Prepare your documents

As explained above, your HTML files should only contain structural markup after the first step. A good place to learn more about separating model and presentation is Jakob Nielsen's UseIt site. Other great places to start are pages about accessible design, such as the Web Content Accessibility Guidelines and the accompanying Techniques for Web Content Accessibility Guidelines.

2. Create themes

This step assumes at least some basic knowledge of the attributes supported in CSS. If you're new to CSS, you should read some introductory material first.

After organizing your information, you're ready to give it a visual representation. You can define styles for a certain element type, classes of elements, and individual elements, and apply them using CSS selectors. With CSS, you can also define elements to become invisible, this allows you to have even greater control over your layouts. It's especially important to identify all parts you want to give distinct views in different themes and to use a clever naming system.

After you create a default stylesheet, just copy it and use it as a template for additional style sheets, or themes. Store all style sheet files in a single common folder. To import a style sheet into an HTML document after creation, you write:

<link rel="stylesheet" type="text/css" href="Path to your style sheet file">

3. Implementation in JavaScript

Now that we have the static parts, it's JavaScript's task to make this dynamic. What needs to be done?

We need a solution to dynamically import a style sheet. This can't be done in JavaScript only, so we need an old friend's help, document.writeln(). The trick is simply to write into your document while it's being loaded, a browser will parse this like any other content and load the defined style sheet file, which is applied to the document:

document.writeln('<link href="'+THEMES_FOLDER_PATH+s+'.css" type="text/css" rel="stylesheet">');

To make this reusable, you have to consider two points. First, of course, you have to wrap it in a function (see insertStyleSheet()).

It's very important to use absolute paths -- paths that are evaluated starting from your document root folder. This is necessary because you'll have to adjust the path every time you insert the script into a new document which has a different relative location to your style sheet files -- which isn't really a reusable script solution. When you look at the code line above, you'll also find the variable s, which holds the name of the theme, the file suffix .css is added statically. Actually, s should hold one of your theme's name that you stored in the common folder (whose name is specified in THEMES_FOLDER_PATH).

Next we need a method to let users choose between different styles, so we create a reusable function called setTheme(), which receives the name of a theme as an argument. This is how to call it:

<a href="javascript:setTheme('default')">Default Theme</a>

To store a theme's name after setting it, we use cookies, which allow us to store data across sessions. This is needed because HTTP, the underlying web protocol, is a stateless protocol -- it doesn't know about you the next time you request a resource from a server. From the JavaScript programmer's perspective, a cookie is a semicolon delimited string of key/value pairs. Since we're lazy and don't want to reinvent the wheel, we'll use an existing cookie library that I took from O'Reilly's JavaScript Application Cookbook by Jerry Bradenbaugh. This small library contains the basic methods needed to work with cookies.

Inside setTheme(), we store the name of the theme with a specified key in our cookies with SetCookie() after deleting an old value with DeleteCookie(). To apply the new style sheet, the last step is to reload the current document which is easily done by resetting the current location. Since it comes, in most cases, from your memory cache, we're not generating network noise.

While the document is reloaded insertStyleSheet() gets called again. Using GetCookie(), we're trying to access the name of a theme, if specified. If none is found, the script uses a default style and writes the <link> element into the document, see above.

4. Step: Add the script and correct settings

The last step is to include the JavaScript library into your documents. What we didn't consider so far is what happens to clients with JavaScript disabled. To avoid breaking your documents, you also need a <NOSCRIPT> element, which is only handled by clients that have disabled JavaScript:

<script src="/themes.js"></script>
<noscript><link href="/styles/default.css" type="text/css" rel="stylesheet"></noscript>

After you create the snippet with the correct (absolute) paths, you can just cut and paste it anywhere in your site's documents.

You must take care that you always point to the same default style sheet (in case you're not supplying a style sheet for users without JavaScript). This must be specified as a constant variable, DEFAULT_THEME, in the script. The last step is to adjust the path to your themes folder in THEMES_FOLDER_PATH (be sure to end your path with a slash) and you're done.


As we saw, implementing your own themes is easy as long as you understand the underlying principles and technologies. Also, keep in mind, that CSS support is not as consistent as it should be. For sites with a large audience, you should stick to the old dirty way. While we didn't discuss all the complexities in this article, hopefully, you've become curious for more -- and that's really all I wanted. Stay tuned!

Figure 7-87

Figure 7-87. Bringing it all together

The values for list-style can be listed in any order, and any of them can be omitted. As long as one is present, the rest will fill in their default values. For instance, the following two rules will have the same visual effect:

LI.norm {list-style: url(img42.gif);}
LI.odd {list-style: url(img42.gif) disc outside;} /* the same thing */

They will also override any previous rules in the same way. Take the following markup: required to fully support negative margins, using the phrase,"A negative value is allowed, but there may beimplementation-specific limits." In the world of web browsers,though Navigator 4.x, Explorer 4.x/5.x, and Opera 3.x do permitnegative margins:

Negative margins have an impact on vertical formatting, affecting howmargins are collapsed. If there are negative vertical margins, thenthe browser should take the absolute

XML documents are easily committed to a persistence layer

XML documents may be stored in files or databases. When stored in files, XML documents are simply plain text files with tags (and possibly DTDs). It is very easy to save your XML documents to a text file and pass the text file around to other machines, platforms and programs (as long as they can understand the data). In the worst case scenario, XML documents (files) can be viewed in a text editor on just about any platform.

XML documents are also naturally committed to a database (relational or object) or any other kind of XML document store. There are commercial products available which allow you to save XML documents to an XML storage layer (which is not a database per se), like Datachannel's XStore and ODI's eXcelon. These XML store solutions are quite expensive ($10,000 to $20,000 range).

XML documents are also quite naturally retrieved from a persistence layer (databases, file systems, XML stores). This lends XML to be used in real world applications where the information being used by different parts of a system is the most important thing.

Another use for color is to draw attention to certain types of text.For example, boldfaced text is already fairlyobvious, but you could give it a different color to make it stand outeven further:

B {color: maroon;}

Then you decide that you want all table cells with a class ofhighlight to contain yellow text:

TD.highlight {color: yellow;}