Monday, August 24, 2009

Beyond Sprites - The New WAR

I was just looking at a set of image files which are used to decorate custom form elements. I was analyzing how best to turn them into sprites1. One particular set of 3 images caused me to dream up a 'new' web standard: a resource tar.

The set was a left end-cap, a right end-cap, and a repeatable middle section to accommodate a control of fixed height but variable width. The end caps were say, 20px wide, but the repeatable middle section image was - and only needed to be - 1px wide. Now, if I were to combine the 3 in a stacked sprite, the 1px wide middle section would have to be stretched to the 20px width to match the end-caps. True, widening the middle section would compress well in PNG or GIF format - as it was destined to become -- but these were just 3 of the 20 or so images. I could make the tiny sacrifices along the way and probably create 7 sprites out of the 20 images .. but that's still 7 http requests.

Maybe right now you're thinking what I was - there should be a way to send all 7 at once. And if there was a way to do *that* - then why muss about with all this sprite nonsense at all2? Just leave the images alone in their 20 separate files, but send them all in one jar. It would be the browser's responsibility to interpret a jar file that came from "http://site.com/path/to/jars/jarfile.jar" and had an internal directory structure of
/.
/img/
/img/1.gif
/img/2.gif
...
so that the images could be referenced in CSS as "http://site.com/path/to/jars/img/1.gif", "http://site.com/path/to/jars/img/2.gif"...

So what's with the title phrase "the new WAR"? Sending along the image assets for custom controls is just one application of this new "jar" or "war" file concept. Another is to send a packet that has the base images for a site: the logo and primary site decoration elements. Other people may conceive of other sets of resources that it make sense to combine and send along together in one packet.

1 For an excellent description of sprites, including some fantastic examples, see The Mystery Of CSS Sprites: Techniques, Tools And Tutorials.

2 Ok, the reason to still create the sprites is so that 'older' browsers - you know, the ones that don't have this as-yet unproposed feature - will still have 7 http requests instead of 20 (instead of the 1 they could have with this!)

Saturday, August 22, 2009

Auto-close open overlays


GLOBAL = {
    //...
    //...
    init:function(){
        //...
        //...
        //wire up language selection .. assuming it will be on [nearly] all pages.
        $('#glb-hdr-toolbar .heading').bind('click keypress',function(e){
            if(!e.keyCode || e.keyCode == 32 || e.keyCode == 13){ //32=space, 13=enter
                var p = this.parentNode;
                $(p).toggleClass('open')
                //keep track of open overlays so that we are able to intelligently auto-close-open-overlays
                GLOBAL.overlays.pushUnique(p);
            }
        });
        
        //wire up intelligent auto-close-open-overlays
        // part of the convention, or 'magic', is that a className of "open" is used to control whether the overlay is 'open'.
        $('body').bind('click keypress',function(e){
            if(!e.keyCode || e.keyCode == 32 || e.keyCode == 13){ //32=space, 13=enter
                var targ = e.target,
                    i = 0,
                    keepOpen,
                    list = GLOBAL.overlays.list;
                ///
                while(targ && ++i<10){
                    for(var j in list){
                        if(targ == list[j]){
                            keepOpen = list[j];
                        }
                    }
                    targ = targ.parentNode;
                }
                
                for(var j in list){
                    if(keepOpen != list[j]){
                        $(list[j]).removeClass('open'); //or, we could just .hide() it... or similar... 
                    }
                }
                
            }
        });
    },
    
    //keep track of open overlays so that we are able to intelligently auto-close-open-overlays
    overlays:{
        list:[],
        pushUnique:function(o){
            var l = GLOBAL.overlays.list;
            for(var i in l){
                if(l[i] == o) return;
            }
            l.push(o);
        }
    },
    //...
    //...
};

Wednesday, August 12, 2009

Offscreen, not invisible.

Ran into this .. had a container that I was hiding with visibility:hidden, while loading markup into it.

Worked great except, of course, for all versions of IE. IE wouldn't show the badge until you moused over it. I tried all the usual IE slap-in-the-face-so-you-behave tricks to no avail (zoom, position, z-index, background, borders).

So I chose to hide the container by positioning it offscreen with left:-9999px. Bingo.

The particular content I was loading was a linkedin iframe badge - the "inline" version off their developer api page. I was loathe to switch over to the "popup" version, and am glad I dodged that bullet.

Wednesday, July 8, 2009

custom scrollbar

jScrollPane .. I've heard bad things about it.

fleXscroll .. I've used it, it's nice, but it's not free.

jsScrolling .. I haven't used it, but it looks nice and it's free.

Improved email validation, plus multiple emails validation

jQuery validation plugin .. was causing ff2 to choke. It also didn't have a multiple-email validator .. or a split-up phone validator -- although on that last one, I highly advise you push back - a phone # field should just be ONE INPUT.


Tuesday, July 7, 2009

The *real* way to disable text selection

I was recently asked by UX to make the text of my fancy custom dropdown selects unselectable. A lot of silly scripts out there that disable text selection are application-unfriendly. They go beyond unselectable and make the element totally non-interactive. But I still want the dropdown to work when you click it. Solution = css for the "good" browsers, and javascript for internet explorer.

CSS


.unselectable{
    -moz-user-select: none;
    -webkit-user-select: none;
}


JS


if(document.attachEvent){
    function returnFalseFn(){
        return false;
    }
    jQuery('.unselectable').each(function(){
        this.attachEvent('onselectstart', returnFalseFn);
    });
}

Wednesday, June 24, 2009

Strange IE6 bug - show/hide select, hemorrhage option innerHTML

We've all had to code up those ever-so-fun branching selects. I chose to implement it by showing or hiding (display:block/none) the container of the label+select corresponding to the appropriate branch. And IE6 decided to hemorrhage option innerHTML onto the page - for 1 of the 3 branches: the middle one. I solved it by adding "position:absolute" to the css for the container.