I’ve made some progress getting my recent
slide
show to display on IE. For the moment, I’m not
focusing on presentational aspects, like rounded corners and the
absurdly wide gutter that IE puts between the title and
content. That will come later.
The reason why I am doing this is that I have been experimenting
with presentation styles for years, and I am finally feel like I am
getting closer to something that fits my style. Ultimately, I
will likely produce a stylesheet designed explicitly for a fixed
1024x768 display, and use images for rounded corners. As well
as produce a script that automates the portions I did manually.
Anyway, the point of this post is to document a few of the
obstacles I have encountered, and capture what I have done so
far.
Terminating Scripts
It may be XHTML (still served as text/html at the moment, even
to browsers that support XHTML), but the following doesn’t
work with IE:
<script src="pager.js" type="text/javascript" />
Instead, the reference to the script must be done this way:
With Firefox, you get three elements. With IE, there is an
additional fourth element with a value of
undefined.
Replacing styles
With Firefox, you can replace the innerHTML for a <style>
element, and thus affect the presentation of multiple elements on
the page. With both IE6 and IE7, this results in an
“Unknown Runtime Error”. See
this
demonstration.
The alternative is to update each of the individual
style attributes on each element separately.
getAttribute
Finding the element with a given class value is made a bit more
challenging with IE as getAttribute("class")
doesn’t seem to return this value.
Apparently that the most portable approach is to iterate over
all the attributes.
For those keeping track, what once was finding a single element
and replacing its innerHTML has become:
var span = document.getElementsByTagName('span');
for (var j=0; j<span.length; j++) {
for (var k=0; k<span[j].attributes.length; k++) {
if (span[j].attributes.item(k).nodeName == 'class') {
if (span[j].attributes.item(k).nodeValue == instructions[i]) {
span[j].style[instructions[i+1]] = instructions[i+2];
}
}
}
}
Making things go away... and come back
CSS is interpreted differently between the two browsers.
Marking something as visibility: hidden doesn’t
necessarily collapse the space that the text would have
taken. To really make it go away, adding width: 1px;
position: absolute; overflow: hidden gets the job
done. Making it come back, and in the right place, in both
browsers, one also needs to set display: inline.
setTimeout vs XHTML
An unsolved problem to date is that the Javascript function
setTimeout does not work as expected when the DOCTYPE
is XHTML. I haven’t managed to find a solution to this
just yet. A similar problem was reported
here.
delays
As near as I can tell, Firefox updates the display in the background, so
setTimeout is effective immediately. IE, by contrast,
does’t seems to wait until the page is updated before it starts
the timer. The net effect is one where IE appears to significantly
underperform Firefox.
It may be XHTML (still served as text/html at the moment, even to browsers that support XHTML),
Which means, for the browsers that receive it, it isn’t XHTML but just HTML with some funny extra slashes. The XHTML appendix C guidelines say not to use the minimized form for element whose content model is not EMPTY.
It’s a bit weird that Firefox supports these type of unclosed script elements in HTML-parsing mode. Opera 9 introduces support for it as well, to be compatible with Firefox. Your slide slow worked reasonably well in Opera 9, as long as I didn’t try to go ‘back’. Using OperaShow (for example with the OSF or S5 format) would work even better of course.
For hiding/showing elements: I’ve always found that { visibility: hidden; display: none; } will do the trick across the board, with the added bonus you don’t need to play with other properties.
display:none should be enough. As far as I can tell the distinction between visibility:hidden and display:noneis that with visibility:hidden the element is there but you cannot see it, with display:none the element (and any that it contains) isn’t there at all and therefor doesn’t claim any space.
The ‘visibility’ property specifies whether the boxes generated by an element are rendered. Invisible boxes still affect layout (set the ‘display’ property to ‘none’ to suppress box generation altogether).
So if Firefox is in fact collapsing boxes with visibility: hidden; it’s a pretty major bug. However I don’t see that; on a few tests, the browsers appear to me to behave identically.
As far as getAttribute('class') is concerned, IE thinks it’s called className as it makes no distinction between an attribute and a property. Using element.className works cross-browser; alternatively you can use:
Iterating over all the attributes is really a sledgehammer to crack a nut, particularly given that IE’s attributes collection has an entry for every possible attribute, whether it’s in the source or not.
passing a function reference to setTimeout() works in XHTML
switching classnames is not practical given the amount of animation I am doing
display:none also makes my newlines disappear. I could introduce more spans, but for now, making the lines 1px in height works best
the real problem I was having with XHTML was that specifying font-height of 24 was incorrect, it needs to be 24px.
I now have learned a lot about the block model of CSS, and have everything working with FF 1.0.7 (I have an issue with FF 1.5!), and functional (but less pretty) with IE.
I still have more work to do to enable serving this as application/xhtml+xml to browsers that support it.
Given an empty instance of an element whose content model is not EMPTY (for example, an empty title or paragraph) do not use the minimized form (e.g. use <p></p> and not <p />).
Sam Ruby has a nice post on the cross-browser obstacles he’s recently encountered. The first two are exactly the problems I had with getting Quisition working on IE. The very first one had me stumped for ages even though it’s dead simple (following...