After much fruitless Googling and consulting with webdev experts, I couldn't find a fix. And like most solutions, I had to stumble upon it at the eleventh hour: adding a background color or image to the container element will fix the IE opacity rendering problem.

Friday, April 22, 2005

Ugliest line trunc hack EVER

The challenge: given some text of abitrary length, figure out where to best truncate the text so that only the first two lines are displayed, regardless of the width of the containing element.

By the way, the element is inline, you have no control over its dimensions, and the spot where you truncate the text must end in an ellipsis (…) Don't ask. Q: can't we just cut it at 20 characters and call it a day? A: no, it must fully fill the two lines, do as we say or we will be cranky.

Given that the fonts used were not fixed-width, I threw out the idea of counting character widths. However, I knew that the line-height CSS rule for this element was 14 pixels, and using offsetHeight I could determine if the height of the containing element, in this case a SPAN. (Word to the wise: offsetHeight is what you want. In the absence of a specific rule, the computed CSS height property for an element seems to be either blank, undefined or "auto", none of which are particularly helpful.)

Armed with this knowledge, I set out to write the ugliest hack I could manage:

In a nutshell: take the text, shave off the last character, append an ellipsis HTML entity, then shove the text back into the element and measure the height. Repeat until the SPAN is finally 28px high (twice the line height == two visible lines).

Ugh. I'm lucky that the strings I was working with were no more than 30 characters long, and only 3-5 strings had to be dealt with in any given page. Excuse me while I go take a shower.

Thursday, April 21, 2005

DOM 0 with XHTML caveat

Here's an interesting gotcha, unearthed from Bobby van der Sluis' popular article on JavaScript good practices that's making the rounds: when you serve an XHTML document as application/xhtml+xml, the good old DOM Level 0 collections like document.images and document.forms go bye-bye, at least in Mozilla-based browsers.

I'm okay with this, but I love me some backwards-compatible DOM 0, especially when I know exactly which element I need to access via script. Luckily, it's perfectly okay to serve XHTML 1.0 as "HTML compatible" text/html. It's when you start serving XHTML 1.1 as text/html that people start yelling and pointing.

Monday, April 18, 2005

Odd and ends 4/18/2005

If you sent me a message in the past month, my apologies: I forgot to turn on Gmail forwarding and just discovered a backlog of SZOJ email. I'll catch up in a few.

Speaking of Gmail, here's some reverse JS Zen: Gmail now works in nearly all browsers, including some legacy ones. Gmail falls back on a basic HTML version if it detects that the browser can't support the more advanced features. So while you might not have all the real-time widgetry, you'll never be locked out of your account when you're stuck with Netscape 4.

I've heard lots of comments from developers in years past about how users have to expect a greatly degraded experience if they're not willing or able to upgrade at the client end. Unfortunately, "degraded" often means "not even minimally supported." The Gmail developers weren't willing to settle for that, and neither should the rest of us. Design your web app for the web first. (Now, if only we can get more Flash developers to buy in to this.)

On a different tangent: earlier this week I wrote a post about what I thought about the whole "controversy" over the use of "Ajax" as a suitable term to describe DOM + JS + behind-the-scenes HTTP. I ended up scrapping it because I want this weblog to focus on practical stuff. Leave it to Matt to sum up my thoughts, nearly to the letter. So I'm going allow myself a (hopefully infrequent) opinionated post: hello, our technology just became interesting again to the world at large, and y'all want to complain about buzzwords? Who the heck cares what they end up calling it?

I hereby call a moratorium on the snarkiness, name-calling and faux outrage over something we failed to do ourselves: make DHTML popular.

A quick overview of what's happening here. c is the 6-character hex color (sans the "#"). The first JS statement uses the substring function to break the hex color string into its three 2-character hex pairs, which are then passed to parseInt to convert them to decimal values. Then we find the average by adding them and dividing by 3.

The function then looks at this average and, using 100 as its "bias" point, either adds or subtracts 100 (an arbitrary value that produced the best results for our needs). The last line returns a greyscale RGB value (perfectly valid in CSS! No need to convert back to hex!).

Now the fun: I sent this off to another webdev for review and challenged him to make it even shorter. He came back with this:

Nice, but I pointed out that av wasn't being calculated correctly without an additional set of parenthesis. Plus, we could shave off a few characters by replacing substring with the shorter substr to the same effect. I countered with this:

Tuesday, April 12, 2005

Memory leaks explained

If you're new to building complex web apps that use tons of JavaScript-powered DOM manipulation, you are hereby required to read Joel Webber's excellent article DHTML Leaks Like A Sieve, which eloquently summarizes the challenge of memory leakage in JS-heavy applications.

You may in fact wish to bookmark Joel's weblog and follow along as he unearths neato facts about Google Maps and other modern web apps.

This function worked great in Firefox but nothing was happening in IE6. I tried a bunch of different tweaks, none of which worked. Adding an alert(n.style.filter); at the tail end of the function returned "alpha(opacity=50)" indicating that the value was being set correctly for IE6. But the element still rendered at 100% opacity.

Finally, I threw the function out altogether and applied the filter directly to the DIV element via CSS:

I really needed the opacity applied to both the text and image. I was about to give up when it occurred to me that maybe the image width and height dimensions has something to do with it. By default, a block element takes on the width of its containing element and height of its content, but maybe IE6 was ignoring this when applying the alpha filter. So I tried this:

Yes! Opacity was now being applied to both the image and the text. I removed opacity rule from the DIV and was then able to correctly set opacity via the JavaScript function.

I don't have the luxury of testing this across the different flavors of IE, but it appears that alpha opacity in IE6 requires certain elements to have a specified width and height. What's funny is that when I tried Googling for answers to my problem, I found a ton of working examples that used opacity in IE6 successfully. Looking back now, all of those examples specified a CSS width and height on the element, but didn't make any specific mention of it as a requirement for IE. Removing the width and height caused those examples to fail, too.