{"id":155,"date":"2009-12-13T13:25:39","date_gmt":"2009-12-13T20:25:39","guid":{"rendered":"http:\/\/kai.mactane.org\/blog\/?p=155"},"modified":"2020-02-29T16:57:22","modified_gmt":"2020-03-01T00:57:22","slug":"why-your-imitation-scrollbar-is-broken","status":"publish","type":"post","link":"https:\/\/kagan.mactane.org\/blog\/2009\/12\/13\/why-your-imitation-scrollbar-is-broken\/","title":{"rendered":"How Many Ways Is Your Imitation Scrollbar Broken?"},"content":{"rendered":"<p>If you&#8217;re going to reinvent the wheel, you should at least make sure your new version is somehow better than the previous kind. Reimplementing standard UI and OS widgets is one of the most common ways developers reinvent the wheel these days&nbsp;\u2014 it started with Flash developers building their own controls, and has now spread to Adobe&nbsp;AIR and Silverlight.<\/p>\n<p>It might be a welcome trend, if the replacement widgets people were building had more functionality than the OS-native ones that are available for free in any other context. But usually, the widgets I see in these frameworks have less than half the functionality of the things they try to replace. I&#8217;m going to pick on scroll bars for now, because I&#8217;ve seen them horribly mangled too many times.<\/p>\n<p>To start with one aspect of scroll bars that we often take for granted: Can you guess which of these text boxes contains more text?<\/p>\n<p><textarea style=\"float: left; width: 40%; height: 10em; margin: 0 1em;\">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Quisque est est, luctus quis suscipit et, lacinia ac odio. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Quisque est est, luctus quis suscipit et, lacinia ac odio.<\/textarea><\/p>\n<p><textarea style=\"float: left; width: 40%; height: 10em; margin: 0 1em;\">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<\/textarea><br \/>\n<br clear=\"left\"><br \/>\n<!--more--><br \/>\nOf course you can; you don&#8217;t even need to guess. The one on the left has more, and you can tell immediately because the movable slider on its scrollbar <em>is smaller<\/em>. This is a feature you get for free from the native OS widget, and one I have never seen implemented in a Flash, AIR, or similar interface.<\/p>\n<p>Here are all the things a native scrollbar does. I absolutely guarantee you, if you&#8217;ve reinvented a scrollbar, your implementation is missing at least two of these features:<\/p>\n<ol>\n<li>As mentioned above, the slider object changes size automatically, to give a general impression of how much content the scrollable area contains.<\/li>\n<li>The arrows at the top and bottom of the scrollbar are clickable, and clicking them once will move the content up and down by a small amount (typically 1 or 2 lines).<\/li>\n<li>Clicking and holding the top and bottom arrows will cause the content to scroll more rapidly.<\/li>\n<li>Clicking and dragging on the slider will scroll the content smoothly to any position the user chooses. (Yes, I have seen scrollbar implementations in which the slider <em>was not<\/em> a draggable item!)<\/li>\n<li><strong>Scroll wheel support:<\/strong> If the user&#8217;s hardware includes a scroll wheel, scrolling it will move the content up and down. This is many users&#8217; preferred method of scrolling content these days, and yet it&#8217;s totally ignored by over half the Flash interfaces I&#8217;ve encountered in the past year. I&#8217;ve bolded it because it&#8217;s the one that gets so egregiously ignored.<\/li>\n<li>The &#8220;gutter&#8221; <em>in between<\/em> the arrows and slider is also clickable. Clicking on it once will scroll the content up or down by, roughly, the size of the visible area (a &#8220;page&#8221;, as it were).<\/li>\n<li>Of course, clicking and holding in the &#8220;gutter&#8221; area will repeatedly and rapidly scroll the content. (This is rarely apparent unless you&#8217;re dealing with a tall scrollable area <em>and<\/em> a fairly long document. Try loading a 25-page or longer document into a word processing program, and set the program to full-screen.)<\/li>\n<li>When the content is scrolled (by whatever method), the slider will move up or down to indicate how far from the beginning or end you are. (Essentially the converse of item #4: Moving the slider scrolls the content, and scrolling through the content moves the slider.)<\/li>\n<li>The arrow buttons and the gutter area give a visual indication when they&#8217;ve been clicked, so the user has better feedback. (This is one of those little things that makes the user experience so much better. It&#8217;d be so easy to do, and yet I&#8217;ve seen about 2 Flash scrollbars in my life that have bothered with that feature.)<\/li>\n<li>If you set your cursor focus on the scrollable area, using the up and down arrow keys will scroll the content. Either the Home and End or Ctrl+Home and Ctrl+End keystrokes will move directly to the beginning and end of the content. The PgUp and PgDown keys may also move the content by an amount similar to clicking in the gutter.<\/li>\n<li>The scrollbar&nbsp;\u2014 including its arrows, gutter and slider&nbsp;\u2014 looks just like every other scrollbar on the user&#8217;s computer. The user can immediately identify the items and finds them familiar.<\/li>\n<\/ol>\n<p>Even if you have done a smashing job of replicating the first 10 points on this list, you simply can&#8217;t get the final one in an AIR, Silverlight, or Flash interface. If your whiz-bang interface platform provides some other benefit, then dropping that last feature might be worth it.<\/p>\n<p>But it&#8217;s no excuse for dropping all the other stuff. Most non-native scroll bars I&#8217;ve seen support only 3 or 4 of these features, which means anyone who normally uses any other ways of interacting with scrollbars winds up cursing and deciding that this broken implementation is cheap and chintzy.<\/p>\n<p>Which it is. If you&#8217;re going to reimplement the wheel, at least make it something that will roll smoothly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re going to reinvent the wheel, you should at least make sure your new version is somehow better than the previous kind. Reimplementing standard UI and OS widgets is one of the most common ways developers reinvent the wheel these days&nbsp;\u2014 it started with Flash developers building their own controls, and has now spread [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[63,37,16,60,29,8,10,9],"_links":{"self":[{"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/posts\/155"}],"collection":[{"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/comments?post=155"}],"version-history":[{"count":13,"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/posts\/155\/revisions"}],"predecessor-version":[{"id":766,"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/posts\/155\/revisions\/766"}],"wp:attachment":[{"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/media?parent=155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/categories?post=155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kagan.mactane.org\/blog\/wp-json\/wp\/v2\/tags?post=155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}