ScrollView's main use case is to provide a scrollable content widget for touch devices on which overflow scrollbars are not natively supported. However, it is built on top of YUI's cross-platform/browser gesture and transition layers, so it can also be used to provide flickable scrolling on mouse-based devices across on all the A-grade browsers.
The ScrollViewScrollbars
plugin can be added to the base scrollview to provide a scroll indicator. The ScrollViewPaginator
plugin can be added to provide a cross-platform paginated scrolling implementation (a simple carousel).
To include the source files for ScrollView and its dependencies, first load the YUI seed file if you haven't already loaded it.
<script src="http://yui.yahooapis.com/3.18.1/build/yui/yui-min.js"></script>
Next, create a new YUI instance for your application and populate it with the
modules you need by specifying them as arguments to the YUI().use()
method.
YUI will automatically load any dependencies required by the modules you
specify.
<script> // Create a new YUI instance and populate it with the required modules. YUI().use('scrollview', function (Y) { // ScrollView is available and ready for use. Add implementation // code here. }); </script>
For more information on creating YUI instances and on the
use()
method, see the
documentation for the YUI Global Object.
Note: be sure to add the yui3-skin-sam
classname to the
page's <body>
element or to a parent element of the widget in order to apply
the default CSS skin. See Understanding Skinning.
<body class="yui3-skin-sam"> <!-- You need this skin class -->
ScrollView
extends the Widget
class, and hence follows the same pattern as any widget constructor, accepting a configuration object to set the initial configuration for the widget.
A ScrollView widget is instantiated from markup by specifying the srcNode
which contains the content to be scrolled. The content is usually in the form of a list, but doesn't necessarily have to be:
<div id="scrollable" class="yui3-scrollview-loading"> <ul> <li>AC/DC</li> <li>Aerosmith</li> <li>Bob Dylan</li> <li>Bob Seger</li> ... </ul> </div>
The yui3-scrollview-loading
class is applied by the developer to progressively enhanced markup, and can be used along with the yui3-js-enabled
class applied to the document element, to hide the scrollview markup from view, while the JS is being loaded. The examples show how to set up a yui3-scrollview-loading
rule to hide progressively enhanced content.
When instantiating from markup, a reference to the srcNode
is provided to the constructor as part of the configuration object. This reference can be a node reference, or a selector string which can be used to identify the node. If the selector string is too broad (returns multiple nodes), the first node found will be used.
The following code references the markup shown above, while constructing the scrollview:
YUI({...}).use("scrollview", function(Y) { var scrollview = new Y.ScrollView({ srcNode:"#scrollable", height:"20em" }); });
Generally, a ScrollView widget will be scrollable either horizontally (along the X axis) or vertically (along the Y axis). The ScrollView determines which direction it can scroll in based on whether or not its content is taller (vertically scrolled) or wider (horizontally scrolled) than its height or width respectively, as you would expect from native overflow handling. In the above example the widget is given a fixed height, so that it will scroll vertically, when the content gets larger than the specified height. In most use cases you will provide either a height or a width to the ScrollView widget constructor.
Following instantiation, a call to render
is required to have the ScrollView's state reflected in the DOM, as with all YUI 3 widgets:
var scrollview = new Y.ScrollView({ ... }); scrollview.render();
ScrollView provides the following core attributes, in addition to the attributes provided by the base Widget class:
Attribute | Description |
---|---|
scrollX | The number of pixels to scroll the widget's content by, along the X axis (vertically). |
scrollY | The number of pixels to scroll the widget's content by, along the Y axis (horizontally). |
Additionally, the following attributes control the sensitivity and scroll dynamics, per instance:
Attribute | Description | Default |
---|---|---|
axis | A string which specifies the axis (or axes) should be scrolled on. Valid values are x , y , or xy . This is an optional attribute, so if unspecified, ScrollView will attempt to determine the desired scroll axis based off the overflow of content. | auto calculation |
bounce | A drag coefficient, which defines how quickly the velocity of the scrollview content decreases after a flick, when it's past the min and max bounds for the widget. Can be set to 0 to disable bounce behavior. | 0.1 |
bounceRange | The default bounce distance in pixels. | 150 |
deceleration | A drag coefficient, which defines how quickly the velocity of the scrollview content decreases after a flick, when it's still with in the min and max bounds for the widget. The closer this is to 1, the less friction there is after a flick. | 0.98 |
easing | The default easing used when scrolling to a given X or Y. | cubic-bezier(0, 0.1, 0, 1.0) |
flick | An object which specifies the minimum distance and minimum velocity (in pixels/ms - generally around 0.5) which should constitute a flick gesture. Can be set to false to disable flick support, in which case the ScrollView content can only be dragged to scroll it. | {minDistance:10, minVelocity:0.3} |
frameDuration | The default time interval used when animating the flick deceleration. | 30 |
snapDuration | The default duration (in ms) used for the snap back animation when scrolled past the min or max bounds for the widget. | ease-out |
snapEasing | The default easing used for the snap back animation when scrolled past the min or max bounds for the widget. | ease-out |
The final rendered ScrollView has the markup structure shown below (shown for a vertical scrollview):
<!-- Bounding Box, with overflow setting and fixed dimension (in this case height) --> <div class="yui3-widget yui3-scrollview yui3-scrollview-vert" style="height: 310px;"> <!-- Content Box, which is scrolled using either top/left, or transform:translate, where supported --> <div class="yui3-scrollview-content" id="scrollable" style="left: 0px; top: 0px;"> ... scrollable content. generally a list ... </div> <!-- Scrollbar indicator, if Scrollbar Plugin is added (added by default for the "scrollview" module) --> <div class="yui3-scrollview-scrollbar yui3-scrollview-scrollbar-vert"> <span class="yui3-scrollview-child yui3-scrollview-first"></span> <span class="yui3-scrollview-child yui3-scrollview-middle"></span> <span class="yui3-scrollview-child yui3-scrollview-last"></span> </div> </div>
The yui3-scrollview-vert
, or yui3-scrollview-horiz
classes applied to the bounding box can be used to style the scrollview based on its scroll orientation.
The core structural css for the ScrollView is shown below, and is pretty straightforward. It simply sets up the bounding box and the content box as positioned elements, and sets overflow hidden, so that the content beyond the bounding box area is hidden, until scrolled into view.
/* Bounding Box */ .yui3-scrollview { position: relative; /* To provide positioning context */ overflow: hidden; /* To clip scrolled content */ ... } /* Content Box */ .yui3-scrollview-content { position:relative; /* To allow positioning */ }
Since the scrollable content is commonly set up as a list (for semantic reasons), the core css for ScrollView also ships with a rule targeting list items (LI
s), so that list content works out of the box, for both vertical and horizontal scrollviews (inline-block is used so that we can trivially support the horizontal use case):
.yui3-scrollview-content ul { margin:0; padding:0; } .yui3-scrollview-content li { padding:0; margin:0; list-style:none; /* cross browser inline block */ display: -moz-inline-stack; display: inline-block; *display: inline; ... }
The above rules can of course be over-ridden for cases in which you don't want lists inside ScrollView handled specially.
The ScrollBar plugin provides a visual scroll indicator to let the user know how much scrollable content there is, and the current scroll position they're at.
When using the scrollview
module, the ScrollViewScrollbars
plugin is automatically pulled down and plugged in for all ScrollView instances (plugged in at the class level).
However, the user can also choose to pull down just the base scrollview module (scrollview-base
) and add scrollbar support optionally (when and if required).
YUI({...}).use("scrollview-base", "scrollview-scrollbars", function(Y) { /* ScrollView without scrollbar indicator */ var scrollview = new Y.ScrollView({ srcNode:"#scrollable", height:"20em" }); /* Add scrollbar indicator support */ scrollview.plug(Y.Plugin.ScrollViewScrollbars); /* scrollview.scrollbars is an instance of the ScrollViewScrollbars plugin */ scrollview.scrollbars.hide(); scrollview.scrollbars.show(); scrollview.scrollbars.flash(); });
When the ScrollViewScrollbars
plugin is plugged in to a ScrollView instance, a scrollbars
property (the namespace for the plugin) is added to the ScrollView instance, which points to an instance of the plugin, as shown above. The plugin provides public hide()
, show()
and flash()
methods for the scroll indicator.
The ScrollViewPaginator
plugin adds pagination support to ScrollView, so that it recognizes, and stops at, discrete page boundaries within its content, as opposed to scrolling continuously (it effectively makes ScrollView behave like a simple Carousel).
Adding the scrollview-paginator
module to the use
statement will pull down and add the Plugin.ScrollViewPaginator
plugin class to the YUI instance. It can then be plugged in to ScrollView instances requiring pagination support, as shown below:
YUI({...}).use("scrollview-base", "scrollview-paginator", function(Y) { /* ScrollView without paginator */ var scrollview = new Y.ScrollView({ srcNode:"#scrollable", height:"20em" }); /* Plug in pagination support */ scrollview.plug(Y.Plugin.ScrollViewPaginator, { selector: "li" // elements definining page boundaries }); /* scrollview.pages is an instance of the ScrollViewPaginator plugin */ scrollview.pages.set("index", 3); scrollview.pages.scrollTo(3, 0.6, "ease-in"); scrollview.pages.next(); scrollview.pages.get("total"); });
The paginator plugin accepts a selector
attribute as part of its configuration, which selects the list of elements to be used to establish page boundaries. In the example above, each LI
within the ScrollView's content box, defines a page in the ScrollView.
When plugged in, the plugin API is available on the pages
property of the scrollview widget instance, and can be used to set the current page, or retrieve paging information.