Vertical reordering in CSS

There are plenty of techniques for reordering content horizontally in CSS (by reordering content I mean visually laying out content in an order different than the one in the source code). Usually those rely on a combination of clever floats and negative margins. YAML has a few examples.

A different objective would be to reorder content vertically, though. This could be particularly interesting for responsive design, where you would want to present content in a different order at different breakpoints, or maybe for a print stylesheet. After a bit of research I came across an interesting technique that relies on the fact that most browsers tend to render <caption> <thead> table elements above the table contents, even if the <caption> <thead> itself is at the bottom of the table in the markup. Of course, you don’t need real <table> and <caption> <thead> elements; instead making use of CSS’s table-caption table-row-header value for the display property.

Update: I got it a bit wrong; the technique used by Marat on his blog used display: table-header-group, not table-caption. Marat did some research into the problems of using table-caption; I was unfortunate to find a few other when using table-header-group.

I was not quite satisfied with the solution above — although it saved my backside a couple of times. It didn’t work in IE, and it revealed a few browser bugs on Chrome (I guess display: table-row-header is not the most well tested CSS feature). So, a bit more experimenting and I struck at this idea:

So, we simply rotate a container 180° (upside down) and then rotate each child in-place another 180°. Magic! Seems to work wonders in Firefox, Safari, Chrome… and IE9.

Of course, IE versions less than 9 don’t understand the CSS transform property, but there’s still something we can do if we need to support those browsers (which, remember, we might not have to do if we are using this technique to target responsive design). Yes, we have to rely on the icky filter property… specifically, the “matrix” filter: it allows for rotation, scaling and skewing. We just need rotation. Unfortunately, it’s been a long time since I did anything to do with matrices. Fortunately, someone else has made it easy — as easy as copy and paste. We also need to be a bit careful with preventing overlap of the filter property with transform in IE9 (since it supports both), so we use IE’s conditional comments to keep the CSS clean. Here we go:

The filter solution should play well with IE6-8, but filter is notoriously buggy. In my quick testing I found at least two issues that might be deal breakers for you:

  • <input> fields within the rotated sections don’t display the input caret correctly (the field works as normal but the blinking cursor renders in the original position — go figure)
  • rotated sections must have a background or they render as black squares, or with badly aliased text

A few more words of warning about this technique in general:

  • your markup must make semantic sense regardless of how it is presented (this might actually help towards that, if used correctly)
  • remember keyboard navigation: you might need to re-assign tabindex attributes for it to make sense to tab between links/fields
  • this is not a tried-and-tested method; expect “issues”!

Why I want to beat Java with a stick

int x = 100;
Stuff.doStuff(x);

The method doStuff(String) in the type Stuff is not applicable for the arguments (int)

int x = 100;
Stuff.doStuff(x.toString());

Cannot invoke toString() on the primitive type int

int x = 100;
Stuff.doStuff((String)x);

Cannot cast from int to String

int x = 100;
Stuff.doStuff(new Integer(x).toString());   // OMGWTFGRRRBBQ!!!

BUILD SUCCESSFUL

htmlspecialchars() for JavaScript

Creating markup with JavaScript for fun and profit is easy due to innerHTML. However, it would be nice to be able to escape output that is not trusted or known. Most references online point to encodeURI or encodeURIComponent, which will kind-of work; however those functions are intended for URI escaping, which has different rules.

So, here’s a quick solution that works pretty much like the similarly-named PHP function, htmlspecialchars:

function htmlspecialchars(str) {

    if (str === undefined) return "";
 
    return str.replace(/[<>"&]/g, function(match){
        return (match == "<") ? "&lt;" :
               (match == ">") ? "&gt;" :
               (match == '"') ? "&quot;" :
               (match == "&") ? "&amp;" : "";
    });
}

What’s missing? The “quote_style” parameter which allows deciding what will happen with single quotes (‘). If your markup is sane and under control, there should be no need for it — if it isn’t, it’s not hard to change the above function.

Making YUI ButtonGroups behave

I like YUI Buttons. Amongst other niceties they allow you to have reliable cross-browser, cross platform custom-rendered form widgets like checkboxes and radio buttons — while keeping all the accessibility concerns in check. One of the functionalities it has is to create “ButtonGroups”, i.e. a bunch of button controls that behave as a traditional radio-button group. All nice and good, except that it has one obnoxious behaviour: it forces all your radio buttons inside a common container — which might not be what you had in mind. I like my radio buttons where I put them, thank you…

So, quick fix coming up:

var radioGroup = new YAHOO.widget.ButtonGroup({ container: aDivSomewhereItDoesntMatterWhere });
var radioButtons = anArrayOfPlainNormalRadioButtons;

for (var i = 0, len = radioButtons.length; i < len; ++i) {

    var nodeIndex = getNodeIndex(radioButtons[i]),
        parentNode = radioButtons[i].parentNode,
        radioButton = new YAHOO.widget.Button(radioButtons[i]);

    // This will put the button somewhere silly
    radioGroup.addButton(radioButton);

    // Move the button back where it was
    parentNode.insertBefore(radioButton.get("element"), parentNode.childNodes[nodeIndex]);
}

So, it’s more verbose than just using the simple “new YAHOO.widget.ButtonGroup(radioButtonContainer)” syntax that does everything for you — if you are willing to have the radio buttons where YUI put them. Also… what’s that “getNodeIndex()” function?, I hear you ask. Just a simple utility off my toolbox; it gets the index of a node within all the nodes with the same parent:

var nodeIndex = function(element) {
    for (var index = 0, el = element; el = el.previousSibling; ++index);
    return index;
}

Hope that’s helpful…

Getting the category ID in WordPress

There is quite a bit of documentation in the WordPress site about categories, specifically how to retrieve data about them. Unfortunately all the available methods seem to focus on getting category data from a post, but it’s nearly impossible to figure out the category you are looking at when viewing the category page itself (i.e. the special “archive page” that lists all posts in a category).

The function is_category() falls short, since it only indicates whether or not the current page is a category page, but not which one. And get_cat_id(), get_category(), get_the_category(), and the half-dozen other “obviously”-named functions either require that you already know something about the category or provide information about a post.

So, the solution?

if (is_category()) {
   $categoryId = $GLOBALS["cat"];
}

Yes, it’s a global variable…

Making sprites

So you have a website that uses dozens of little images to make the interface more attractive. Maybe there’s a toolbar or menu, where each item or button has its own icon. It looks great, but it’s a pain to load – each image is a small file and the browser frantically struggles to manage the 20 or 30 requests for all the graphical nicety. The interface feels sluggish. Users get bored and leave. Civilisational collapse soon ensues.

Fortunately, you know how to fix the problem with the use of the great technique of CSS Sprites. If you don’t, you should. Click the link and learn about it; I will assume that you know what CSS sprites are from here on… Yes, CSS sprites are great, but they are a pain to create manually. Not only you need to stitch the images together but also there will be lots of CSS rules to position the background image correctly. Automation comes to the rescue in the form of the montage command (part of the fantastic ImageMagick collection of image-manipulation software goodness) and some quick script hacking…

Creating the sprite

This little tip will create a sprite off a directory of image files with identical size (in this case, 16×16 icons), each one named something sensible. The objective is to get one image file and a bunch of CSS rules built automatically. First, ensure that you have ImageMagick. In Ubuntu this command will do the trick:

sudo apt-get install imagemagick

There are also downloadable distributions for Windows and Mac. Once you’re ready, open a command prompt and go to the folder where your images live, and run this command:

montage *.png -alpha on -background "#ffffff00" -tile x1 -geometry 16x16 ../sprites.png

This will create a file, sprites.png, in the parent folder (in Windows, make sure that you type “..sprites.png” as the last parameter – notice the backslash), with all the images tiled side-by-side. If you require the images to be tiled top-to-bottom substitute -tile x1 with -tile 1x. And if your images are a different size than 16×16, specify that in the -geometry parameter. And if your source images are not PNGs, replace “*.png” as appropriate. I recommend that you open the sprites.png file in your editor of choice and perform any conversions or optimisations as you see fit. Don’t forget to apply OptiPNG if you use PNG as your final format (why wouldn’t you?) to get a really small final file size. Your sprites file will look a bit like this (icons off the excellent Silk Icons set):

Example of icons in sprite file

That takes care of the sprite image. Now for the CSS rules.

Auto-generating CSS rules

We’ll be defining a couple of base rules that apply to all elements (note the references to 16px, the size of the icons; adjust as necessary):

.i16:before, .i16 span {
    content: "";
    background-image: url("sprites.png");
    background-repeat: no-repeat;
    padding: 0 0 0 16px;
    margin: 0 0.25em 0 0;
    *zoom: 1;  /* For IE 6 and 7 */
}

.i16block {
    display: block;
    margin: 0 0 0 16px;
    padding: 0 0 0 0.25em;
    position: relative;
    *zoom: 1;  /* For IE 6 and 7 */
}

.i16block span {
    background-image: url("sprites.png");
    background-repeat: no-repeat;
    height: 16px;
    left: -16px;
    min-height: 1em;
    position: absolute;
    top: 0.115em;
    width: 16px;
}

And one more rule per image, which provides the correct background position. The objective is to be able to use classes like this (in this case, to obtain the PDF icon):

<a class="i16 i16pdf" href="example.pdf">PDF link</a>

Or, for links that might span multiple lines and require nice text alignment (or for IE6 support) we need an extra element:

<a class="i16block i16pdf" href="example.pdf"><span></span>PDF link</a>

First, we need to get a list of files in the directory. Each file will produce a rule, and it is important that the contents of the directory haven’t changed since the sprite was created (this is why we placed the sprite in the parent directory). So, drop to the command line and, in Linux, run this:

ls -1 *.png > filelist.txt

Or, in Windows:

dir /b *.png > filelist.txt

Now we only need a quick script to output a bunch of CSS rules. This can be done with your favourite programming language, but here is an example in Python:

rules = ""
f = open('filelist.txt', 'r')
x = 0
for name in f:
    rules = rules + ".i16Mime" + name[0].capitalize() + name[1:] + ":before"
    rules = rules + ", .i16Mime" +  name[0].capitalize() + name[1:]"
    rules = rules + " span {n    background-position: -" + str(x) + "px 50%;n}nn"
    x = x + 16
f.close()
f = open('rules.css', 'w')
f.write(rules)
f.close()

The above code can be saved as a Python script file (say, “myscript.py”) in the same directory as the images, and run from the command-line like so:

python myscript.py

This will generate a new CSS file, “rules.css”, with all the correct rules for all the icons. It should be pretty easy to rewrite the above in your language of choice (PHP, Ruby, Assembler…)   Simple apply to your links the appropriate “i16 i16type” class names and you should be good to go.

Testing for outline CSS support with jQuery

In the good spirit of testing capabilities rather than browser versions, I needed a way to find out whether or not a browser supports setting the values of the “outline” property via CSS. IE6 and 7 don’t support it, everything else seems to. So I just quickly extended the jQuery.support functionality like so:

$.support.outlineCss = function() {
    var $el = $("<div></div>").css("outline", "1px solid black"),
        outlineStyle = $el.appendTo(document.body).css("outline-style");
    $el.remove();
    return outlineStyle == "solid";
}();

Simply test if $.support.outlineCss is true and you’re good to go…