Thursday, January 16, 2014

Showing Tick Marks On Sliders

With sliders, you can specify a step. This is the value distance the slider handle will move, when moved by the mouse or keyboard. The step value defaults to 1, providing a smooth transition from one position to the next. When the step value increases, that's when you start to notice the jumps from one spot to the next, when moving the slider handle. Often, it makes sense to have these larger increments, like when precision doesn't matter. With the min, max, and step values, there are a pre-defined set of "slots" that the handle can sit in. This aren't marked, of course, but we can enhance the slider widget to allow for displaying tick marks.

Although the step option makes in obvious what the step value is, it doesn't become obvious till the user starts interacting with the handle. Displaying tick marks can provide a subtle visual indicator of where the handle can be moved. It removes uncertainty for the user.

I was able to implement the following slider extension, which adds a new ticks option. When true, the slider that's rendered looks something like this.

There isn't much too this extension aside from adding the new ticks option. Let's take a look at the code that actually renders the div elements representing the ticks.

var cnt = this.options.min + this.options.step,
    background = this.element.css( "border-color" ),
while ( cnt < this.options.max ) {
    left = ( cnt / this.options.max * 100 ).toFixed( 2 ) + "%";
    $( "<div/>" ).addClass( "ui-slider-tick" )
                 .appendTo( this.element )
                 .css( { left: left, background: background } );
    cnt += this.options.step;

You may have noticed that the tick marks aren't rendered in the first or last positions of the slider. They look kind of silly with the rounded corners, and, they're really not needed there anyway. For this reason, the cnt variable starts with the next step up from min. The background variable holds a sampling of the slider border-color property. This is the color we'd like applied to the tick marks to give the widget a unified look-and-feel.

Next we start the rendering loop, which continues while cnt is less than the max option. This prevents the last tick mark from displaying. The left value is used to horizontally position the tick div. This is computed as the cnt percentage of max. So with each iteration, the position moves further to the right, till we reach the end.

The tick div element is then created. This gets the ui-slider-tick class applied to it, which defines some standard CSS properties shared by all ticks. For example, the width is 2px, and the z-index is -1, forcing it behind the slider bar — we only care to show the little bit sticking out from the bottom. The new div is then added to the slider element, and computed CSS values — left and background — are directly applied. The cnt is incremented by the step value for the next tick rendering.