Vertical Radio Buttons

Applying new styles to the jQuery UI buttonset widget to get a vertical layout.

HTML

<div id="radio77">
    <input type="radio" id="radio1" name="radio" />
    <label for="radio1">Choice 1</label>
    <input type="radio" id="radio2" name="radio" checked="checked" />
    <label for="radio2">Choice 2</label>
    <input type="radio" id="radio3" name="radio" />
    <label for="radio3">Choice 3</label>
    <input type="radio" id="radio4" name="radio" />
    <label for="radio4">Choice 4</label>
</div>

CSS

body {
    font-size: 0.8em;
}

/*
 * The buttonset container needs a width so we can stack them vertically.
 *
 */
#radio {
    width: 30%;
}

/*
 * Make each label stack on top of one another.
 *
 */
.ui-buttonset-vertical label {
    display: block;
}

/*
 * Handle colliding borders. Here, we're making the bottom border
 * of every label transparent, except for labels with the
 * ui-state-active or ui-state-hover class, or if it's the last label.
 *
 */
.ui-buttonset-vertical label:not(:last-of-type):not(.ui-state-hover):not(.ui-state-active) {
    border-bottom: transparent;
}

/*
 * For lables in the active state, we need to make the top border of the next
 * label transparent.
 *
 */
.ui-buttonset-vertical label.ui-state-active + input + label {
    border-top: transparent;
}

/*
 * Oddly enough, the above style approach doesn't work for the
 * hover state. So we define this class that's used by our JavaScript
 * hack.
 *
 */
.ui-buttonset-vertical label.ui-transparent-border-top {
    border-top: transparent;
}

JavaScript

// Creates the buttonset.
$( "#radio" ).buttonset()

             // Adds our custom CSS class which changes the orientation.
             .addClass( "ui-buttonset-vertical" )

             // Remove the corner classes that don't amke sense with the new layout.
             .find( "label" ).removeClass( "ui-corner-left ui-corner-right" )

             // Hack needed to adjust the top border on the next label uring hover.
             .on( "mouseenter", function( e ) {
                 $( this ).next().next().addClass( "ui-transparent-border-top" );
              })

             // Hack needed to adjust the top border on the next label uring hover.
             .on( "mouseleave", function( e ) {
                 $( this ).next().next().removeClass( "ui-transparent-border-top" );
              })

             // Apply proper corner styles.
             .filter( ":first" ).addClass( "ui-corner-top" )
             .end()
             .filter( ":last" ).addClass( "ui-corner-bottom" );