Saturday, November 20, 2010

Google Chrome Doesn't Count

The title of this post may be a little (intentionally) misleading. I'm not arguing the validity of Google's Chrome browser - in fact I generally like it and it has become my default browser. Using Chrome to browse the web is pretty sweet. Designing pages the work in it is not, and it's driving me around the bend.

I have a web project I've been working on for a while that uses linked stylesheets. Several of them, and it also has a feature that lets users switch one of the stylesheets out with any one of three others - which is only supposed to restyle part of the layout. In Safari it works as it is supposed to. In Chrome? Not so much.

Chrome has had a bug now for over a year that still isn't fixed, or at least not entirely. When working on the files locally (that is, just opening the HTML file in the browser right off my hard drive) Chrome doesn't "see" all the stylesheets properly. I'm only certain it is loading one of them (the third one) that styles the framework of the page, and I know it's loading because, well, the frame is styled.

However, when I try to use Javascript to reference the first stylesheet it complains that I'm trying to get values of elements that don't exist. Even more oddly, it WILL swap out that stylesheet it thinks doesn't exist with another. If I try to get the length of the array of linked stylesheets with "document.styleSheets.length" it says ZERO. That's right, it is obviously loading one of the stylesheets and swapping another out but the stylesheets array is EMPTY. Now, if I copy and past the content from the external stylesheet into the HTML document, though, then the array reports "1" for the length. So it would seem the array only works for stylesheets in the head of the document - it doesn't count the linked ones.

Ah! But here's where it gets really confusing. If I access the exact same document and linked stylesheets via a web server everything works. The stylesheets array iterates correctly, there are no "null" or "undefined object" errors. In other words, over a web server, it works perfectly. It's only when no web server is involved that it won't work!

Thankfully this isn't going to burn me too badly - the project (an HTML5/CSS3/Javascript "app" of sorts) was always intended to be hosted in the cloud and therefore accessed through a web server. There were initially some plans to wrap it up in a nice package and deliver it as an Android and iPhone app that could be used locally and offline. It also means - even though this is pretty static code - I'm going to have to do my development over a web server. Good thing I already have XAMPP installed!

Oh, and for anyone else who might run into this and be looking for a solution, it seems there isn't one. Or at least not a total one. You CAN actually reference the linked stylesheet with "document.getElementById("name")" if you gave the "link" tag an "id." You can create a linked stylesheet array with "document.getElementsByTagName("link")" and that will actually show the correct number for linked stylesheets. But neither of these methods will allow you to directly query the CSS rules within the stylesheet. If you apply a class from the stylesheet to an object in the HTML page, though, you can use that object as a way to get the attributes of the class. So, as a work-around you could create an object, hide it, and apply multiple classes to it from the stylesheet and then use javascript and the DOM to get the info. Obviously, though, you wouldn't be able to apply visibility or positioning classes, so this work-around is also limited.

No comments: