C Laurent

Navigation

Skip navigation.

Search

Site navigation

Email conversation

FromC Laurent
ToMe
SubjectYour swapstyle script
Date19 November 2009 16:48
Hello Tarquin,

First of all I'd like to thank you for this amazing site which really is
a treasure trove of knowledge!
I have a few questions concerning your swapstyle.js script and the
tutorial explaining it.

My starting point
-------------------
Being an avid supporter of good accessibility but also an absolute
javascript beginner, a few days ago I included the script on
[URL] in my
local test pages (I haven't gone online yet) and was happy with it.
(No comment expected on other people's scripts - I read your
instructions...)

Then I read somewhere that there can be problems with alternate
stylesheets with KHTML/WebKit browsers.
Since support for Chrome and Safari is important to me, I searched the
web, found your great site, and tried to follow your tutorial on
http://www.howtocreate.co.uk/tutorials/javascript/domcss, reading it
many times.

I use your swapstyle.js as is (as downloaded) and even though it works
like a charm on my local machine (Vista32 HomePremium SP2 with Firefox
3.5.5, IE6-8, Opera 9.51, unfortunately, there are a few points that I
don't understand even after several readings of the tutorial, and I
would be grateful for your explanations. (Please excuse my non-native
English which may sound a bit inappropriate at times.)

My questions
------------

(1st question)

With XHTML 1.0 Strict, is the following structure correct?

I am asking because I don't use any stylesheet with *no title* attribute
like in your example.
At some point of my reading I had the impression that you need *one*
stylesheet *without* a title that can never be disabled.
On the other hand, in your own site, you don't have a title-less
stylesheet, either, but "moosified" (with title) and the 3 alternate
stylesheets.

I now have (fancy titles):

<link rel="stylesheet" type="text/css" href="css/styles1.css"
title="white (Default)" />
<link rel="alternate stylesheet" type="text/css" href="css/styles2.css"
title="blue" />
<link rel="alternate stylesheet" type="text/css" href="css/styles3.css"
title="green" />
<link rel="alternate stylesheet" type="text/css" href="css/styles4.css"
title="black" />

styles1.css imports all major stylesheets, e.g.
@charset "UTF-8";
@import url(main.css);
@import url(print.css);
etc.,

styles2.css (alternate) imports all major stylesheets as well as
styleswitcher2.css
@charset "UTF-8";
@import url(main.css);
@import url(print.css);
@import url(styleswitcher2.css);
etc.,
with the alternate styles for styles2.css (title="blue") etc.
The same happens to styles3.css and styles4.css.

So, together with the downloaded swapstyle.js, does this mean switching
stylesheets "is supported correctly using a different syntax" by
KHTML/WebKit, esp. Chrome and Safari? Am I right that "using a different
sytnax" refers to your working example swapstyle.js, so I don't have to
add anything else to the script?

As I said, it works like a charm here, but I want to make sure I can use
your working example as is and the above structure in order to allow
switching for KHTML/WebKit browsers, because otherwise, I could have
continued with the other stylesheet switcher.

(2nd question)

On the browser support page for the swapstyle script, you say for
KHTML/WebKit etc.,
"Script works as expected with <link> tags but is known to have problems
with <style> tags."
Ok, link tags are the ones mentioned above (link rel="") -- but style
tags? Do you mean there could be problems if I was using *inline style*
tags (I don't use them), or are you referring to sth else?

(3rd question)

Sorry about the dumb question, but can I use a body id in front of
onload, eg.
<body id="contact" onload="useStyleAgain('styleTestStore');"
onunload="rememberStyle('styleTestStore',10);"> ?

(4th question)

In your example, the switch buttons are in a form.
<form method="get" action="" onsubmit="return false;">
<p>
 <input type="button" value="Use Default"
onclick="changeStyle('Default')"><br>
   etc.
</p>
</form>

Is this "part of the trick" (there's a note somewhere that Opera, e.g.,
does only fire the onunload event when the user clicks a link or submits
a form)?

So would my present choice,
<ul class="switchbuttons">
 <li><input type="button" class="switchbutton" value="white"
onclick="changeStyle('white (Default)')" /></li>
 <li><input type="button" class="switchbutton" value="black"
onclick="changeStyle('black')" /></li>
 etc.
</ul>
though working in my test pages, be incorrect?

How would you do this to switch the stylesheets *with links* (remember I
am a complete beginner in this area) instead of input buttons?


(Last question)

In your example, I see ( cookieLife * 86400000 ).
Do I have to change this if I have
onunload="rememberStyle('styleTestStore',5), i.e. for 5 days?


I am a bit ashamed for asking all these dumb questions, but everybody has to
start somewhere and I am willing to learn ;-)

Thank you very much for reading this (in case you manage that far down) and
for putting up such a valuable site.

CLaurent
FromMe
ToC Laurent
SubjectRe: Your swapstyle script
Date19 November 2009 17:53
Hi,

> I am asking because I don't use any stylesheet with *no title* attribute
> like in your example.

That's fine. This is only needed if you want to have some styles that are
always applied no matter which style theme is being used.

> I now have (fancy titles):

Looks good.

> I don't have to add anything else to the script?

Correct. The script takes care of the incompatibilities for you by using the
more reliable approach mentioned in the tutorial.

> Do you mean there could be problems if I was using *inline style*
> tags (I don't use them)

Do not use style *tags* like this: <style title="blue"> and expect it to
work properly with the switcher in those browsers. You can still use style
*attributes* like this:
<p style="color:blue;">
(That will always be applied in all browsers no matter what stylesheet is
being used)

> can I use a body id in front of onload, eg.
> <body id="contact" onload="useStyleAgain('styleTestStore');"
> onunload="rememberStyle('styleTestStore',10);"> ?

Sure, you can put any valid attributes you want on any tag you want.

> In your example, the switch buttons are in a form.
> Is this "part of the trick"

No, the form is not needed. I could safely remove it.

> So would my present choice, though working in my test pages, be incorrect?

Your markup seems fine.

> How would you do this to switch the stylesheets *with links* (remember I
> am a complete beginner in this area) instead of input buttons?

<a href="#" onclick="changeStyle('black');return false;">Black</a>

The "return false" part is needed to make sure the browser doesn't try to
open the link normally after you click it.

> In your example, I see ( cookieLife * 86400000 ).
> Do I have to change this

Leave it alone, just set the number of days you want when you call the
rememberStyle function :)

Looks like you probably already have everything working well enough, good
luck with the project.


Mark 'Tarquin' Wilton-Jones - author of http://www.howtocreate.co.uk/
FromC Laurent
ToMe
SubjectRe: Your swapstyle script
Date19 November 2009 21:33
Hello Tarquin,

I just got back home and found your reply.
Thank you very much for taking the time to answer every single one of my
questions!

Very helpful indeed and very much appreciated!

Wishing you all the best,

CLaurent
FromC Laurent
ToMe
SubjectYour swapstyle script -- follow-up
Date30 November 2009 17:16
Hello Tarquin,

A week ago I asked you a few questions concerning your excellent swapstyle
script and your answers were very helpful.
Meanwhile, I have continued testing your script and I really love the
possibilities it gives me for
enhancing both the accessibility and the usability of my planned website.

There's just one intriguing problem that I can't solve with the means at
hand, and that is a certain
restriction when a conditional comment is used for an ie-patch.css file.

<!--[if lte IE 6]>
<link rel="stylesheet" type="text/css" href="css/defaultstyle1-iepatch.css"/>
<![endif]-->

The restrictions become obvious when I want to assign different IE-only
values for different
alternate styles, since the values defined in defaultstyle1-iepatch.css are
persistent for _all_
stylesheets as seen by IE 6 (the ie-patch file in the CC being listed as the
last css file).

I'm trying to get the same versatility for lte IE 6 as for all other
browsers, so here is my humble
suggestion (remember that I am a complete beginner in javascript matters):
------------------------------------------------
Would it be possible to use a few lines of javascript to dynamically assign
e.g. the css class
.style2 to the html element as soon as the style2 button/link is clicked --
and so on with the other
alternate styles?

Then it would be very easy to change e.g. IE-6-only values that have to be
different for certain
alternate styles and therefor cannot be treated by just one definition
within one and the same
ie-patch.css file.

Example for different IE-6 settings within the same ie-patch file:

* html #element { IE-6 setting for default style 1 }
* html.style2 #element { changed IE-6 setting for style 2 }
* html.style3 #element { changed IE-6 setting for style 3 }
etc.
------------------------------------------------
I have seen similar things done in the <head>, where this is used to
distinguish between css
versions for javascript vs. non-javascript browsers in order to provide
accessible javascript, like, e.g.
<script type="text/javascript">document.documentElement.className += "js";</script>
see [URL],
but here we would need a dynamic assignment of several classes, like
.style2, .style3 etc.

What do you think? Could this be a way to solve the IE restrictions
mentioned above?
Or maybe there is a completely different way to solve this?
I am really looking forward to your comments.


(2nd question)

Speaking of accessible javascript -- right now, if a user with javascript
disabled clicks the swap
link / swap button, nothing happens.
It would be great if in such a case, the click could lead to a page where I
tell the users how they
can enable javascript with just a few clicks. Would it be possible to have
both options (js/nojs)
provided by the same link/button?


(last question)


Sorry if I have to come back for a moment to the KHTML/WebKit topic.
One of the reasons I am using your script is that it supports link tags for
alternate stylesheets in
KHTML/WebKit browsers.

I am asking myself whether the following observations are of any relevance
for the use of your
swapstyle script, above all as regards order of stylesheets and influence of
a print.css file:

In the following article [URL] somebody says in the comments,

"With regard to the bug with alternate styles: It's the same bug that Safari
has had on my site for
years, and continues to have - the on-screen display is completely littered
with print-style amends
(like placing the URL as generated content after each hyperlink). It's not
unique to Chrome (but
highly annoying anyway) - try viewing my site with Chrome or Safari, both
will screw up, suggesting it's a webkit problem."

This is also mentioned here: [URL] where the author concludes,

"Unfortunately, it appears to break sites in one very important way: it
obeys alternate stylesheets,
just as if they were normal, active stylesheets. This breaks sites who print
their alternate CSS links after active ones."
"At the moment, the only thing to do is to list alternate stylesheets before
active ones, or exclude alternate links altogether."

Do you know whether the above comments are of any relevance for your
swapstyle script?
As I said, I personally haven't experienced any problems at all so far, but
I cannot tell for Safari and Chrome.


Please excuse my long mail, but I really love your swapstyle script and
would just like to make sure
it works in KHTML/WebKit browsers, too.

Thank you very much for your help!

CLaurent
FromMe
ToC Laurent
SubjectRe: Your swapstyle script -- follow-up
Date3 December 2009 21:58
> The restrictions become obvious when I want to assign different IE-only
> values for different alternate styles

Just give your IE patch stylesheets titles that match the titles used
for their corresponding normal stylesheets:

<link rel="stylesheet" ... title="foo">
<link rel="alternate stylesheet" ... title="bar">
<!--[if lte IE 6]>
<link rel="stylesheet" ... title="foo">
<link rel="alternate stylesheet" ... title="bar">
<![endif]-->

The script will switch all matching titles at the same time.

> Would it be possible to use a few lines of javascript to dynamically
> assign e.g. the css class

Yes. The HTML element class can be set whenever you want like this:
document.documentElement.className = 'baz';
You could just set that appropriately when you are changing the active
stylesheet. But this is pointless given that you can just do it properly
as shown above.

> Speaking of accessible javascript -- right now, if a user with javascript
> disabled clicks the swap link / swap button, nothing happens.

One alternative is to put this just before it:
<noscript><p>You will need to enable JavaScript to use this
feature.</p></noscript>

However, the best thing to do is to just create the buttons with
JavaScript (document.write or whatever). That way, anyone who has
JavaScript disabled won't see anything. Anyone who has JS disabled will
have a good reason to do so, and is not going to want to enable it just
for this sort of thing anyway, so there's no point toying with them by
telling them to enable it.
http://www.howtocreate.co.uk/tutorials/javascript/writing

Alternatively, what you suggested is possible:

1. For buttons, you can use a form that sumbits to your explanation
page, with a scripted handler that cancels the submission, and make
every button a submit button, so it will submit the form.
<form action="nojs.html" onsubmit="return false;">
...
<input type="submit" value="Foo"
onclick="changeStyle('foo');">
...
</form>

2. For links, just make the href point to the explanation page, and have
the onclick handler change the style, then return false to cancel the click.
<a href="nojs.html" onclick="changeStyle('foo');return false;">

> I am asking myself whether the following observations are of any relevance
> for the use of your swapstyle script

Neither of those pages seem to be using real alternate stylesheets. They
seem to be talking about media types specified in media attributes of
the LINK tags, but they have used the wrong terminology.

My own site uses what I have suggested, and it works perfectly in those
browsers.

The script will attempt to switch print media stylesheets the same as
any others (it does not care what the media attribute says), so you
would probably want to make any print stylesheet be a persistent
stylesheet (without a title attribute) unless you want to allow people
to switch between different print stylesheets as well.

If you find that using a print media stylesheet messes up in Safari,
Chrome or Konqueror (as in; if they apply the print media stylesheet at
the same time as regular stylesheets), then one option is to take the
CSS from the print media stylesheet, and move it into a normal
stylesheet without any media attribute, and then use @media blocks
inside the stylesheet itself (I use this on my site):
http://www.howtocreate.co.uk/tutorials/css/mediatypes

If you don't see any problems, it's best to assume there aren't any
problems, and you can just ignore it.


Tarquin
FromC Laurent
ToMe
SubjectRe: Your swapstyle script -- follow-up
Date3 December 2009 23:08
Hello Tarquin,

Thank you very much for your helpful reply!

Since I am already using @media blocks in the stylesheets and no separate
print media stylesheet, your answer is even more reassuring as regards my
doubts referring to the problems described by the people I quoted.

May I ask you two short final questions that have been bothering me a bit as
I am a js beginner --  on your own site, you don't use the <body onload...>.
Is this "inline scripting" deprecated in any way and would it be better to
put this away in another js file?

And secondly, following the recent advice of some people to put the
javascript files *last* for performance sake (just before the closing 
</body>), I guess with this swapstyle script it would be best to put it
right at the top of the <head>, as you do?

Again, thank you so much for your precious help!

CLaurent 
FromMe
ToC Laurent
SubjectRe: Your swapstyle script -- follow-up
Date6 December 2009 17:05
> on your own site, you don't use the <body onload...>.
> Is this "inline scripting" deprecated in any way and would it be better to
put this away in another js file?

It is a scripted event handler defined in the markup. It is often
discouraged, as it forces scripted behaviour to be included in the markup -
many people like to keep these things separated. Personally, I do use it,
but only on rare occasions. Most of the time, I like to keep all my script
in external files to allow better caching, and make it easier to modify the
behaviour of all files at the same time by changing only the single script
file.

> And secondly, following the recent advice of some people to put the
javascript files *last* for performance sake

This is pointless.

Either way the browser will still have to pause scripts, and lockup the
parsing for a moment as it downloads the files. With the files first, the
pause usually happens before the page appears so the user does not try to
interact with a dead page. With the files last, the pause happens at the
end, so the user can see the page slightly sooner and images can begin to
load, but it doesn't respond to them. Both ways have small advantages, and
small disadvantages.

However, most users do not notice the difference either way, and network
speeds mean that there is no need for you, as an author, to worry about it.
In addition, many browsers now use speculative parsing and loading of those
resources, so they will not have to slow down at all, and the whole idea of
putting them at the end serves no purpose at all (except in rare cases where
a script uses its placement to know when parsing is complete - the script
instructions would tell you if this is the case).

Basically, you should put those scripts where it makes most sense to you as
an author. The HEAD is actually designed for this, so you can very quickly
see which scripts are being loaded, and to keep the clutter out of your
document.
FromC Laurent
ToMe
SubjectRe: Your swapstyle script -- follow-up
Date6 December 2009 17:21
Hello Tarquin,
Thank you for your answer.

>> on your own site, you don't use the <body onload...>.
>> Is this "inline scripting" deprecated in any way and would it be better
>> to put this away in another js file?

> It is a scripted event handler defined in the markup. It is often
> discouraged, as it forces scripted behaviour to be included in the markup -
> many people like to keep these things separated. Personally, I do use it,
> but only on rare occasions. Most of the time, I like to keep all my script
> in external files to allow better caching, and make it easier to modify the
> behaviour of all files at the same time by changing only the single script
> file.

I would be very grateful if you could tell me how to put this event handler
in a separate js file.

CLaurent 
FromMe
ToC Laurent
SubjectRe: Your swapstyle script -- follow-up
Date6 December 2009 19:43
> I would be very grateful if you could tell me how to put this event
> handler in a separate js file.

window.onload = function () {
  ... code goes here ...
};

You can only have one of these for the entire document (or one onload
attribute on the body). If more than one script needs to detect it, you
either need to modify all of the scripts need to share the same onload
function (simply have it run each script's code in turn), or use DOM events:
http://www.howtocreate.co.uk/tutorials/javascript/domevents
FromC Laurent
ToMe
SubjectRe: Your swapstyle script -- follow-up
Date7 December 2009 22:35
Hello Tarquin,

> window.onload = function () {
>   ... code goes here ...
> };

I am very sorry to bother you again, but your answer for the window.onload
bit doesn't help me any further :-(.
Of course, if this function for window.onload is much more code than the
scripted event handler, I
certainly cannot and do not expect you to spend your spare time for that.
If it is just a transfer of the short scripted event handler, I would be
very grateful it you could send me the code.
I normally have one to four shorter [brand] scripts on my pages with no
inline scripting in the
markup, and none of the other scripts would need to detect this external
script with the window.onload / window.onunload functions.

Don't get me wrong, I have absolute confidence in your advice, so if you
think using the scripted
event handler in the body tag is better, I'll take your advice.
It's not that I want this window.onload solution at any price. I read
comments from people that
discourage this scripted event handler, hence my question as a complete js
beginner. I would only change to this solution if you deem it reasonable.

I just want to make sure I use the best method, because I've spent quite a
bit of time understanding
and implementing your great script, and it would be a pity if I didn't make
the best out of it.

Thank you very much!

CLaurent
FromMe
ToC Laurent
SubjectRe: Your swapstyle script -- follow-up
Date11 December 2009 22:50
> I am very sorry to bother you again, but your answer for the window.onload
> bit doesn't help me any further :-(.

This:

<body onload="foo();bar();" onunload="baz();qux();">

works identically to this:

<body>
...
<script type="text/javascript">
window.onload = function () {
  foo();
  bar();
};
window.onunload = function () {
  baz();
  qux();
};
</script>

(Or the same code inside an external script file.)

You should be able to apply that knowledge to the code you already have.

> I read comments from people that discourage this scripted event handler

They're trying to tell you to use DOM events (to avoid conflicts where
several scripts need to use the same event). This is the best approach for
experienced scripters. But if you're having trouble doing something as
simple as converting a body onload attribute into an onload function, DOM
events will probably be far too confusing for you, until you have spent more
time trying to learn JavaScript properly. When you're ready, you can work
through that chapter of my tutorial.
This site was created by Mark "Tarquin" Wilton-Jones.
Don't click this link unless you want to be banned from our site.