Creating the perfect slider

I’ve previously discussed many times the color picker I have to create, and blogged about my findings on the way. An essential component of most color pickers is a slider control.

I won’t go through much techincal details or JavaScript code in this article (after all the usability guidelines presented don’t only apply to JavaScript applications, and this is why I used Adobe Kuler as a good or bad example for some of them), it’s been done numerous times before and I prefer being a bit original than duplicating web content. You can google it and various implementations will come up if you need a starting point.

Some might argue that I suffer from NIH syndrome, but I prefer to code things my way when I think I can do something even a bit better. After all, if nobody ever tries to reinvent the wheel, the wheel stands no chances of improvement. In this case, I wanted to build the most usable slider ever (at least for color picking uses), or -from an arguably more conservative point of view- something significantly more usable than the rest (if you think about it, the two statements are equivalent, the first one just sounds more arrogant :P ).

I started by thinking about the way I personally use sliders and other form controls, and what bothers me most in the process. Then I combined that with the previously-done accessibility guidelines and the best slider implementations I’ve encountered (from a usability perspective), and here is what I came up with.

Requirements for the perfect slider control

  1. It should be ARIA-compatible, so that disabled users can easily utilize it.
  2. It should be focusable, so that you can Tab to it.
  3. Of course the thumb should be draggable (why would you call it a slider otherwise anyway?)
  4. Of course the slider should be labeled so that the user knows what to use it for.
  5. Normal, hover and focus states should be different (at least in browsers supporting the :hover and :focus pseudo-classes)
  6. You should be able to click somewhere in the rail and have the thumb instantly move there. Many slider implementations use animations for that, and even though I admit it raises the wow factor, I don’t think it’s good for usability. When I choose something, I want it to be instantly selected, I don’t want to wait for the pretty animation to finish, even if it’s short. Other implementations don’t move the slider to the point of the rail that you clicked, but just a bit towards it. I find that very annoying. I clicked there because I want the slider to go there, not towards there! If I wanted to increment/decrement it a bit, I’d use other methods (read below).
  7. It should be keyboard-navigable. I think the ideal key-mappings are:
    • Left and right arrow keys for small adjustments
    • Page up/down and Ctrl + left and right arrow keys for big adjustments.
    • Esc to focus out (blur)
    • Home and End to navigate to the minimum and maximum respectively
  8. It should respond to the mousewheel (and this is where all current implementations I’ve tested fail misreably) when focused. Small adjustments for normal mousewheel movement, big adjustments if the Ctrl key is pressed as well. The pitfall to that is that you can’t cancel the default action (zoom in/out) in Safari. Why the Ctrl key and not Alt or Shift? Because we are accustomed to using the Ctrl key as a modifier. Alt and Shift are used more rarely. Especially designers (and for most color pickers they are a significant part of the target audience) are used in using the Ctrl key together with the mousewheel, since that’s a popular way for zooming or scrolling in most Adobe CS applications. Another important consideration when designing a mousewheel-aware slider, is to bind the event to the document element once the slider thumb is focused and unbind it when the slider thumb is blurred. Why? Because in most such cases, we don’t like to have to keep out mouse pointer on the slider to adjust it with the mousewheel. It being focused should suffice for letting the app know that this is what we want to adjust.
  9. The exact numerical choice of the user should be visible, not only in an indicator that is positioned in a static place, but also above the slider thumb and have it move as the slider thumb moves. I don’t want to have to look at two different places to see what I have selected! (the slider thumb and the indicator) Why above the slider thumb? Because if it’s below, the mouse pointer is likely to hide it. This movable indicator should be hidden once the user focuses out (as long as we provide another one that is positioned statically). Adobe Kuler does this fairly well, although it suffers from a few issues: When you click on the slider rail, the indicator doesn’t show up.
  10. The user should be able to click at some point in the rail and start dragging right away, without lifting their mouse button in the meantime. Even though this sounds common-sense, I’ve seen many implementations that fail at it (including Kuler’s).

So, that’s it! What do you think? Could you come up with anything else to add?

  • http://jlix.net/ Sander Aarts

    Sounds great!
    Personally I find it quite hard to make good intuitive and usable interfaces and judging most websites/applications others do to. It’s nice see you put the bar high (is this a real English expression or am I just thinking Dutch, writing English?).

    Some remarks though on the keyboard navigation:
    Why not use up/down arrow keys? I’d suggest the following keys:
    – left/right arrow: big steps
    – up/down arrow: small steps (fine tuning)
    – ctrl + left/right: min/max

    I associate the left/right arrow keys with bigger steps/more speed than the up/down keys, probably because they’re farther apart (well on most keyboard I know of anyway). Enabling all kinds of sliding to be done using the arrow keys makes sure the user can hold her hand in one position. Home/End could still be an alternative for min/max for people who have problems pushing two buttons at the same time (maybe because they have only one hand).

    Where does the focus go when you hit Esc?

    cheers!

  • http://leaverou.me Lea Verou

    Hi again Sander Arts! Thanks for commenting. :)

    I had a horizontal slider in mind, because this is what I actually wrote earlier. (since the results of the color survey so far display an inclination towards horizontal sliders) For vertical sliders, up and down arrow keys would be far more suitable, definitely!

    As for horizontal ones, I think the keyboard mappings you are suggesting seem equally as usable as mine (I still prefer mine, but it’s a matter of personal taste). However, we are both speculating and judging from ourselves. The best way to determine which keyboard mappings are actually better would be a usability test. However that’s not something easily done for such a purpose.

    “Putting the bar high” is an english expression AFAIK, but bare in mind that English isn’t my native language either ;)

    As for where the focus goes, I basically call blur() when the user hits Esc, so it goes to …nowhere (?). Hmmm…

    • http://jlix.net/ Sander Aarts

      But if the focus goes nowhere it means that people who use their keyboard to navigate will probably have to tab al the way from the top of the page to wherever they want to go. Maybe that’s what you want, but perhaps it’s more useful to set focus on the form submit button. Unless that one is right next to the slider anyway, cause then tab will do.

      Perhaps you can make it so that users can configure their own keyboard mapping ;-)

      • http://leaverou.me Lea Verou

        If you design the slider for a particular form, and don’t want to make it reusable, setting the focus on the form’s submit button would be a good idea. However, there’s not always 1 submit button on a form. Sometimes there are none, while other times there are more than one, so it’s not really feasible for reusable sliders.

        As for the focus, in Firefox if the user presses Tab after blur() is called, then the focus goes to the element that previously had focus (in our case, the slider thumb). In IE, Opera and Webkit, what you describe happens (the tab sequence starts over).

        I think you’re right, it doesn’t seem very useful now that I think about it. However, I can’t think of anything else that the user might want to do when hitting Esc while the slider is focused, and I also saw it in various other implementations, so I adapted it as well.

        Configurable keyboard mapping might be useful for redistributable widgets, so that the developer can set the keyboard mappings without altering the slider code. However, for the end user, it sounds a bit far-fetched (for most applications).

        • Naked Geese Reunion

          Wholeheartedly agree with the last paragraph here; key mappings for something like a color picker is /definitely/ a bit over-the-top. However, I don’t reckon this is still a big issue; the (ideal, in my opinion) Firefox functionality of returning focus to the element that got blur()’ed is easily imitated by keeping track of the last element of your color picker to receive focus.

  • Naked Geese Reunion

    It is perhaps just me, but I’ve rather always wished a slider would respond to the “fierceness” of my mousewheel actions. That is, if I just carefully push it up one tick, I’d like for the value to increase by one; if, however, I executed a very abrupt and forceful scrolling of the mousewheel down, it’d be fantastic to see the value drop by twenty or so. Just a thought… : )

    • http://leaverou.me Lea Verou

      That’s actually possible. The event.wheelDelta (or event.detail) does contain this information. However, there are differences across browsers (for instance Safari reports about 4 times larger deltas) that make it quite difficult to implement this without browser sniffing. :(

  • http://thinkweb2.com/projects/prototype/ kangax

    Another thing to have mind is to make slider degrade properly (for non-JS clients) ;)

    As far as implementation, I find callback/event-based widgets the most flexible and easy to use. For example, instead of specifying an input field where a current value would be populated, a user would instead subscribe to “onchange” event (or a callback). That event (or a callback) would carry a new value, which user would decide what to do with herself (and could, for example, format it before an actual output, or maybe do not even output but send to a server with a certain interval).

    Other additions to consider are multiple handles (e.g. for specifying ranges) and custom step values (e.g. making it possible to specify a range of 50-150 with a step of 25).

    Oh, and of course unit tests are a must for any serious script. Unfortunately, there are very few scripts on the web which pay attention to testing.

    Hope this helps.

    • http://leaverou.me Lea Verou

      I wholeheartedly agree with your remarks and already had them in mind (exept the unit tests *blush* ). However they are mostly implementation guidelines, so they are a bit out of the scope of this article (which is usability for the end user). Valid points though, all of them. :)

  • Lucas

    One thing to keep in mind is to make sure it compatible with other web browsers like firefox, google chrome, and IE (eh!).

    • Naked Geese Reunion

      Opera for the win, then, is it? ; )

      • Lucas

        Sorry, I forgot about Opera. You can really tell that Google Chrome has been influenced by it.