PDA

View Full Version : Dynamically changing ref to linked css file



AlistairH
06-25-2005, 01:06 PM
I have a page that uses a linked css file. I'd like the user to change the colour scheme of the page simply be selecting an option from a menu. This should then change the page's reference to a different css file containing the settings required, presumably with the page having to be reloaded/refreshed as part of the process.

How do I go about doing this?

mwinter
06-25-2005, 03:07 PM
I have a page that uses a linked css file. I'd like the user to change the colour scheme of the page simply be selecting an option from a menu. This should then change the page's reference to a different css file containing the settings required, presumably with the page having to be reloaded/refreshed as part of the process.There is already a mechanism that facilitates this sort of thing, through what is know as alternate style sheets. Decent browsers like Firefox and Opera will allow a user to select any of these alternatives at will. But first, some background. There are three types of style sheet: persistent, preferred, and alternate.

The former - persistent - is a style sheet that is always applied, no matter what alternates the user might choose. Clearly, this type is useful for specifying rules that will be common to all of the other style sheets you might have produced. It is also useful when there is only style sheet, which might be the case for print style sheets. Persistent style sheets are included in the way you're accustomed:


<link rel="stylesheet" type="text/css" href="..."
[OPTIONAL: media="..."]>The next - preferred - is basically a default. Unless a user chooses otherwise, the browser will present the page using the combined rules from both the persistent and preferred style sheets. The link element used to include preferred style sheets is exactly the same as the one above, with the addition of a title attribute. The value of this attribute names a group of style sheets, and is presented to the user.


<link rel="stylesheet" type="text/css" href="..."
title="..." [OPTIONAL: media="..."]>When this name is chosen by the user, all style sheets with the same name will be applied.

The latter - alternate - is exactly like preferred, except that alternate style sheets are not applied automatically. They are included in the same way, too, with the addition of 'alternate' in the rel attribute:


<link rel="alternate stylesheet" type="text/css" href="..."
title="..." [OPTIONAL: media="..."]>Alternate style sheets are mutually exclusive: when one is selected, all of the others are disabled.

If you want to experiment, you can find the list of alternates that a document contains in the View > Page Style menu in Firefox, and View > Style in Opera. The W3C's CSS portal (http://www.w3.org/Style/CSS/) uses alternate style sheets.

Typically, Microsoft never implemented this, so another mechanism can be handy. There are two methods, and they can be combined.

The first is to generate the link elements dynamically on the server. A simple implementation in PHP might go:


<?php

$style = empty($_GET['style'])
? '...' /* Set default here */
: $_GET['style']; /* Pass preferred name in URL: ?style=... */
?>

<!-- Persistent -->
<link rel="stylesheet" type="text/css" href="...">

<!-- Alternates -->
<link rel="<?php if('metallic' != $style) {echo 'alternate ';} ?>stylesheet" type="text/css" href="..." title="metallic">
<link rel="<?php if('traditional' != $style) {echo 'alternate ';} ?>stylesheet" type="text/css" href="..." title="traditional">For more complicated cases, you could create an associative array that contains properties to write out.

The second approach is to disable style sheets via the DOM. However, this has limited support.


function activateStyleSheet(title) {
var c, i, t;

if(!(c = document.styleSheets)) {return;}

i = c.length;
while(i--) {
if((t = c[i].title)) {
c[i].disabled = (title != t);
}
}
}Combining the two is trivial:


<a href="?style=metallic" onclick="activateStyleSheet('metallic'); return false;">Metallic</a>

Mike

AlistairH
06-25-2005, 05:30 PM
Just what I'm looking for. Thanks Mike.

mwinter
06-25-2005, 08:23 PM
function activateStyleSheet(title) {
var c, i, t;

if(!(c = document.styleSheets)) {return;}

i = c.length;
while(i--) {
if((t = c[i].title)) {
c[i].disabled = (title != t);
}
}
}Combining the two is trivial:


<a href="?style=metallic" onclick="activateStyleSheet('metallic'); return false;">Metallic</a>That needs to be changed to:


function activateStyleSheet(title) {
var c, i, t;

if(!(c = document.styleSheets)) {return true;}

i = c.length;
while(i--) {
if((t = c[i].title)) {
c[i].disabled = (title != t);
}
}
return false;
}Combining the two is trivial:


<a href="?style=metallic" onclick="return activateStyleSheet('metallic');">Metallic</a>The changes might seem superficial, but they're quite important if you're trying to allow failed script execution to fall back to the server-side alternative. If not (you're just using a client-side script), then the first version is fine.

Mike

AlistairH
06-27-2005, 09:49 AM
Thanks Mike.

I'm just using the javascript with it running on the client - working a treat. The ISP that I'm with at the moment doesn't allow PHP. Once my broadband connection with them has run its contract term I'll be moving to someone who can give more functionality.

IanMarlowe
07-04-2005, 07:14 AM
this is all very interesting...