jQuery custom content scroller
Highly customizable custom scrollbar jQuery plugin. Features include vertical and/or horizontal scrollbar(s), adjustable scrolling momentum, mouse-wheel (via jQuery mousewheel plugin), keyboard and touch support, ready-to-use themes and customization via CSS, RTL direction support, option parameters for full control of scrollbar functionality, methods for triggering actions like scroll-to, update, destroy etc., user-defined callbacks and more.
Current version 3.1.5 (Changelog)
Upgrading from version 2
How to use it
Get started by downloading the archive which contains the plugin files (and a large amount of HTML demos and examples). Extract and upload jquery.mCustomScrollbar.concat.min.js, jquery.mCustomScrollbar.css and mCSB_buttons.png to your web server (alternatively you can load plugin files from a CDN).
HTML
Include jquery.mCustomScrollbar.css in the head tag your HTML document (more info)
<link rel="stylesheet" href="/path/to/jquery.mCustomScrollbar.css" />
Include jQuery library (if your project doesn’t use it already) and jquery.mCustomScrollbar.concat.min.js in the head tag or at the very bottom of your document, just before the closing body tag
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="/path/to/jquery.mCustomScrollbar.concat.min.js"></script>
CSS
The element(s) you want to add scrollbar(s) should have the typical CSS properties of an overflowed block which are a height (or max-height) value, an overflow value of auto (or hidden) and content long enough to require scrolling. For horizontal scrollbar, the element should have a width (or max-width) value set.
If you prefer to set your element’s height/width via javascript, you can use the setHeight
/setWidth
option parameters.
Initialization
Initialize via javascript
After files inclusion, call mCustomScrollbar function on the element selector you want to add the scrollbar(s)
<script> (function($){ $(window).on("load",function(){ $(".content").mCustomScrollbar(); }); })(jQuery); </script>
Initialize via HTML
Add the class mCustomScrollbar
to any element you want to add custom scrollbar(s) with default options. Optionally, set its axis via the HTML data attribute data-mcs-axis
(e.g. "x"
for horizontal and "y"
for vertical) and its theme via data-mcs-theme
. For example:
<div class="mCustomScrollbar" data-mcs-theme="dark"> <!-- your content --> </div>
Basic configuration & option parameters
axis
By default, the script applies a vertical scrollbar. To add a horizontal or 2-axis scrollbars, invoke mCustomScrollbar function with the axis option set to "x"
or "yx"
respectively
$(".content").mCustomScrollbar({ axis:"x" // horizontal scrollbar });
$(".content").mCustomScrollbar({ axis:"yx" // vertical and horizontal scrollbar });
theme
To quickly change the appearance of the scrollbar, set the theme option parameter to any of the ready-to-use themes available in jquery.mCustomScrollbar.css, for example:
$(".content").mCustomScrollbar({ theme:"dark" });
Configuration
You can configure your scrollbar(s) using the following option parameters on mCustomScrollbar function
Usage $(selector).mCustomScrollbar({ option: value });
setWidth: false
- Set the width of your content (overwrites CSS width), value in pixels (integer) or percentage (string).
setHeight: false
- Set the height of your content (overwrites CSS height), value in pixels (integer) or percentage (string).
setTop: 0
- Set the initial css top property of content, accepts string values (css top position).
Example:setTop: "-100px"
.
setLeft: 0
- Set the initial css left property of content, accepts string values (css left position).
Example:setLeft: "-100px"
.
axis: "string"
- Define content’s scrolling axis (the type of scrollbars added to the element: vertical and/of horizontal).
Available values:"y"
,"x"
,"yx"
.axis: "y"
– vertical scrollbar (default)axis: "x"
– horizontal scrollbaraxis: "yx"
– vertical and horizontal scrollbars
scrollbarPosition: "string"
- Set the position of scrollbar in relation to content.
Available values:"inside"
,"outside"
.
SettingscrollbarPosition: "inside"
(default) makes scrollbar appear inside the element. SettingscrollbarPosition: "outside"
makes scrollbar appear outside the element. Note that setting the value to"outside"
requires your element (or parent elements) to have CSSposition: relative
(otherwise the scrollbar will be positioned in relation to document’s root element).
scrollInertia: integer
- Set the amount of scrolling momentum as animation duration in milliseconds.
Higher value equals greater scrolling momentum which translates to smoother/more progressive animation. Set to0
to disable.
autoDraggerLength: boolean
- Enable or disable auto-adjusting scrollbar dragger length in relation to scrolling amount (same bahavior with browser’s native scrollbar).
SetautoDraggerLength: false
when you want your scrollbar to (always) have a fixed size.
autoHideScrollbar: boolean
- Enable or disable auto-hiding the scrollbar when inactive.
SettingautoHideScrollbar: true
will hide the scrollbar(s) when scrolling is idle and/or cursor is out of the scrolling area.
Please note that some special themes like “minimal” overwrite this option.
autoExpandScrollbar: boolean
- Enable or disable auto-expanding the scrollbar when cursor is over or dragging the scrollbar.
alwaysShowScrollbar: integer
- Always keep scrollbar(s) visible, even when there’s nothing to scroll.
alwaysShowScrollbar: 0
– disable (default)alwaysShowScrollbar: 1
– keep dragger rail visiblealwaysShowScrollbar: 2
– keep all scrollbar components (dragger, rail, buttons etc.) visible
snapAmount: integer
- Make scrolling snap to a multiple of a fixed number of pixels. Useful in cases like scrolling tabular data, image thumbnails or slides and you need to prevent scrolling from stopping half-way your elements. Note that your elements must be of equal width or height in order for this to work properly.
To set different values for vertical and horizontal scrolling, use an array:[y,x]
snapOffset: integer
- Set an offset (in pixels) for the snapAmount option. Useful when for example you need to offset the snap amount of table rows by the table header.
mouseWheel:{ enable: boolean }
- Enable or disable content scrolling via mouse-wheel.
mouseWheel:{ scrollAmount: integer }
- Set the mouse-wheel scrolling amount (in pixels). The default value
"auto"
adjusts scrolling amount according to scrollable content length.
mouseWheel:{ axis: "string" }
- Define the mouse-wheel scrolling axis when both vertical and horizontal scrollbars are present.
Setaxis: "y"
(default) for vertical oraxis: "x"
for horizontal scrolling.
mouseWheel:{ preventDefault: boolean }
- Prevent the default behaviour which automatically scrolls the parent element when end or beginning of scrolling is reached (same bahavior with browser’s native scrollbar).
mouseWheel:{ deltaFactor: integer }
- Set the number of pixels one wheel notch scrolls. The default value “auto” uses the OS/browser value.
mouseWheel:{ normalizeDelta: boolean }
- Enable or disable mouse-wheel (delta) acceleration. Setting
normalizeDelta: true
translates mouse-wheel delta value to -1 or 1.
mouseWheel:{ invert: boolean }
- Invert mouse-wheel scrolling direction. Set to
true
to scroll down or right when mouse-wheel is turned upwards.
mouseWheel:{ disableOver: [array] }
- Set the tags that disable mouse-wheel when cursor is over them.
Default value:["select","option","keygen","datalist","textarea"]
scrollButtons:{ enable: boolean }
- Enable or disable scrollbar buttons.
scrollButtons:{ scrollAmount: integer }
- Set the buttons scrolling amount (in pixels). The default value
"auto"
adjusts scrolling amount according to scrollable content length.
scrollButtons:{ scrollType: "string" }
- Define the buttons scrolling type/behavior.
scrollType: "stepless"
– continuously scroll content while pressing the button (default)scrollType: "stepped"
– each button click scrolls content by a certain amount (defined in scrollAmount option above)
scrollButtons:{ tabindex: integer }
- Set a tabindex value for the buttons.
keyboard:{ enable: boolean }
- Enable or disable content scrolling via the keyboard.
The plugin supports the directional arrows (top, left, right and down), page-up (PgUp), page-down (PgDn), Home and End keys.
keyboard:{ scrollAmount: integer }
- Set the keyboard arrows scrolling amount (in pixels). The default value
"auto"
adjusts scrolling amount according to scrollable content length.
keyboard:{ scrollType: "string" }
- Define the keyboard arrows scrolling type/behavior.
scrollType: "stepless"
– continuously scroll content while pressing the arrow key (default)scrollType: "stepped"
– each key release scrolls content by a certain amount (defined in scrollAmount option above)
contentTouchScroll: integer
- Enable or disable content touch-swipe scrolling for touch-enabled devices.
To completely disable, setcontentTouchScroll: false
.
Integer values define the axis-specific minimum amount required for scrolling momentum (default:25
).
documentTouchScroll: boolean
- Enable or disable document touch-swipe scrolling for touch-enabled devices.
advanced:{ autoExpandHorizontalScroll: boolean }
- Auto-expand content horizontally (for
"x"
or"yx"
axis).
If set totrue
, content will expand horizontally to accommodate any floated/inline-block elements.
Setting its value to2
(integer) forces the non scrollHeight/scrollWidth method. A value of3
forces the scrollHeight/scrollWidth method.
advanced:{ autoScrollOnFocus: "string" }
- Set the list of elements/selectors that will auto-scroll content to their position when focused.
For example, when pressing TAB key to focus input fields, if the field is out of the viewable area the content will scroll to its top/left position (same bahavior with browser’s native scrollbar).
To completely disable this functionality, setautoScrollOnFocus: false
.
Default:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']"
advanced:{ updateOnContentResize: boolean }
- Update scrollbar(s) automatically on content, element or viewport resize.
The value should betrue
(default) for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements etc.
advanced:{ updateOnImageLoad: boolean }
- Update scrollbar(s) automatically each time an image inside the element is fully loaded.
Default value isauto
which triggers the function only on"x"
and"yx"
axis (if needed).
The value should betrue
when your content contains images and you need the function to trigger on any axis.
advanced:{ updateOnSelectorChange: "string" }
- Update scrollbar(s) automatically when the amount and size of specific selectors changes.
Useful when you need to update the scrollbar(s) automatically, each time a type of element is added, removed or changes its size.
For example, settingupdateOnSelectorChange: "ul li"
will update scrollbars each time list-items inside the element are changed.
Setting the value totrue
, will update scrollbars each time any element is changed.
To disable (default) set tofalse
.
advanced:{ extraDraggableSelectors: "string" }
- Add extra selector(s) that’ll release scrollbar dragging upon mouseup, pointerup, touchend etc.
Example:extraDraggableSelectors: ".myClass, #myID"
advanced:{ releaseDraggableSelectors: "string" }
- Add extra selector(s) that’ll allow scrollbar dragging upon mousemove/up, pointermove/up, touchend etc.
Example:releaseDraggableSelectors: ".myClass, #myID"
advanced:{ autoUpdateTimeout: integer }
- Set the auto-update timeout in milliseconds.
Default timeout:60
theme: "string"
- Set the scrollbar theme.
View all ready-to-use themes
All themes are contained in plugin’s CSS file (jquery.mCustomScrollbar.css).
Default theme:"light"
callbacks:{ onCreate: function(){} }
- A function to call when plugin markup is created.
Example:
callbacks:{ onCreate:function(){ console.log("Plugin markup generated"); } }
callbacks:{ onInit: function(){} }
- A function to call when scrollbars have initialized (demo).
Example:
callbacks:{ onInit:function(){ console.log("Scrollbars initialized"); } }
callbacks:{ onScrollStart: function(){} }
- A function to call when scrolling starts (demo).
Example:
callbacks:{ onScrollStart:function(){ console.log("Scrolling started..."); } }
callbacks:{ onScroll: function(){} }
- A function to call when scrolling is completed (demo).
Example:
callbacks:{ onScroll:function(){ console.log("Content scrolled..."); } }
callbacks:{ whileScrolling: function(){} }
- A function to call while scrolling is active (demo).
Example:
callbacks:{ whileScrolling:function(){ console.log("Scrolling..."); } }
callbacks:{ onTotalScroll: function(){} }
- A function to call when scrolling is completed and content is scrolled all the way to the end (bottom/right) (demo).
Example:
callbacks:{ onTotalScroll:function(){ console.log("Scrolled to end of content."); } }
callbacks:{ onTotalScrollBack: function(){} }
- A function to call when scrolling is completed and content is scrolled back to the beginning (top/left) (demo).
Example:
callbacks:{ onTotalScrollBack:function(){ console.log("Scrolled back to the beginning of content."); } }
callbacks:{ onTotalScrollOffset: integer }
- Set an offset for the onTotalScroll option.
For example, settingonTotalScrollOffset: 100
will trigger the onTotalScroll callback 100 pixels before the end of scrolling is reached.
callbacks:{ onTotalScrollBackOffset: integer }
- Set an offset for the onTotalScrollBack option.
For example, settingonTotalScrollBackOffset: 100
will trigger the onTotalScrollBack callback 100 pixels before the beginning of scrolling is reached.
callbacks:{ alwaysTriggerOffsets: boolean }
- Set the behavior of calling onTotalScroll and onTotalScrollBack offsets.
By default, callback offsets will trigger repeatedly while content is scrolling within the offsets.
SetalwaysTriggerOffsets: false
when you need to trigger onTotalScroll and onTotalScrollBack callbacks once, each time scroll end or beginning is reached.
callbacks:{ onOverflowY: function(){} }
- A function to call when content becomes long enough and vertical scrollbar is added.
Example:
callbacks:{ onOverflowY:function(){ console.log("Vertical scrolling required"); } }
callbacks:{ onOverflowX: function(){} }
- A function to call when content becomes wide enough and horizontal scrollbar is added.
Example:
callbacks:{ onOverflowX:function(){ console.log("Horizontal scrolling required"); } }
callbacks:{ onOverflowYNone: function(){} }
- A function to call when content becomes short enough and vertical scrollbar is removed.
Example:
callbacks:{ onOverflowYNone:function(){ console.log("Vertical scrolling is not required"); } }
callbacks:{ onOverflowXNone: function(){} }
- A function to call when content becomes narrow enough and horizontal scrollbar is removed.
Example:
callbacks:{ onOverflowXNone:function(){ console.log("Horizontal scrolling is not required"); } }
callbacks:{ onBeforeUpdate: function(){} }
- A function to call right before scrollbar(s) are updated.
Example:
callbacks:{ onBeforeUpdate:function(){ console.log("Scrollbars will update"); } }
callbacks:{ onUpdate: function(){} }
- A function to call when scrollbar(s) are updated.
Example:
callbacks:{ onUpdate:function(){ console.log("Scrollbars updated"); } }
callbacks:{ onImageLoad: function(){} }
- A function to call each time an image inside the element is fully loaded and scrollbar(s) are updated.
Example:
callbacks:{ onImageLoad:function(){ console.log("Image loaded"); } }
callbacks:{ onSelectorChange: function(){} }
- A function to call each time a type of element is added, removed or changes its size and scrollbar(s) are updated.
Example:
callbacks:{ onSelectorChange:function(){ console.log("Scrollbars updated"); } }
live: "string"
- Enable or disable applying scrollbar(s) on all elements matching the current selector, now and in the future.
Setlive: true
when you need to add scrollbar(s) on elements that do not yet exist in the page. These could be elements added by other scripts or plugins after some action by the user takes place (e.g. lightbox markup may not exist untill the user clicks a link).
If you need at any time to disable or enable the live option, setlive: "off"
and"on"
respectively.
You can also tell the script to disable live option after the first invocation by settinglive: "once"
.
liveSelector: "string"
- Set the matching set of elements (instead of the current selector) to add scrollbar(s), now and in the future.
Plugin methods
Ways to execute various plugin actions programmatically from within your script(s).
update
Usage $(selector).mCustomScrollbar("update");
Call the update method to manually update existing scrollbars to accommodate new content or resized element(s). This method is by default called automatically by the script (via updateOnContentResize
option) when the element itself, its content or scrollbar size changes.
scrollTo
Usage $(selector).mCustomScrollbar("scrollTo",position,options);
Call the scrollTo method to programmatically scroll the content to the position parameter (demo).
position parameter
Position parameter can be:
"string"
- e.g. element selector:
"#element-id"
- e.g. special pre-defined position:
"bottom"
- e.g. number of pixels less/more:
"-=100"
/"+=100"
- e.g. element selector:
integer
- e.g. number of pixels:
100
- e.g. number of pixels:
[array]
- e.g. different y/x position:
[100,50]
- e.g. different y/x position:
object/function
- e.g. jQuery object:
$("#element-id")
- e.g. js object:
document.getelementbyid("element-id")
- e.g. function:
function(){ return 100; }
- e.g. jQuery object:
Pre-defined position strings:
"bottom"
– scroll to bottom"top"
– scroll to top"right"
– scroll to right"left"
– scroll to left"first"
– scroll to the position of the first element within content"last"
– scroll to the position of the last element within content
Method options
scrollInertia: integer
- Scroll-to duration, value in milliseconds.
Example:
$(selector).mCustomScrollbar("scrollTo","bottom",{ scrollInertia:3000 });
scrollEasing: "string"
- Scroll-to animation easing, values:
"linear"
,"easeOut"
,"easeInOut"
.
Example:
$(selector).mCustomScrollbar("scrollTo","bottom",{ scrollEasing:"easeOut" });
moveDragger: boolean
- Scroll scrollbar dragger (instead of content).
Example:
$(selector).mCustomScrollbar("scrollTo",80,{ moveDragger:true });
timeout: integer
- Set a timeout for the method (the default timeout is 60 ms in order to work with automatic scrollbar update), value in milliseconds.
Example:
$(selector).mCustomScrollbar("scrollTo","top",{ timeout:1000 });
callbacks: boolean
- Trigger user defined callbacks after scroll-to completes.
Example:
$(selector).mCustomScrollbar("scrollTo","left",{ callbacks:false });
stop
Usage $(selector).mCustomScrollbar("stop");
Stops any running scrolling animations (usefull when you wish to interupt a previously scrollTo method call).
disable
Usage $(selector).mCustomScrollbar("disable");
Calling disable method will temporarily disable the scrollbar (demo). Disabled scrollbars can be re-enable by calling the update method.
To disable the scrollbar and reset its content position, set the method’s reset parameter to true
$(selector).mCustomScrollbar("disable",true);
destroy
Usage $(selector).mCustomScrollbar("destroy");
Calling destroy method will completely remove the custom scrollbar and return the element to its original state (demo).
Scrollbar styling & themes
You can design and visually customize your scrollbars with pure CSS, using jquery.mCustomScrollbar.css which contains the default/basic styling and all scrollbar themes.
The easiest/quickest way is to select a ready-to-use scrollbar theme. For example:
$(selector).mCustomScrollbar({ theme:"dark" });
You can modify the default styling or any theme either directly in jquery.mCustomScrollbar.css or by overwriting the CSS rules in another stylesheet.
Creating a new scrollbar theme
Create a name for your theme (e.g. “my-theme”) and set it as the value of the theme option
$(selector).mCustomScrollbar({ theme:"my-theme" });
Your element will get the class “mCS-my-theme” (your theme-name with “mCS” prefix), so you can create your CSS using the .mCS-my-theme
in your rules. For instance:
.mCS-my-theme.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: red; } .mCS-my-theme.mCSB_scrollTools .mCSB_draggerRail{ background-color: white; } /* and so on... */
In the same manner you can clone any existing theme (e.g. “dark”), change its selector (e.g. .mCS-dark
) to your own theme name (e.g. .mCS-my-theme
) and modify its CSS rules.
Scrollbar markup
The plugin applies specific id (unique) and/or classes to every scrollbar element/component, meaning that you can target and modify any scrollbar in more than one ways.
For example, every element with a scrollbar gets a unique class in the form of _mCS_1
, _mCS_2
etc. Every scrollbar container element gets a unique id in the form of mCSB_1_scrollbar_vertical
, mCSB_2_scrollbar_vertical
etc. Every scrollbar dragger gets a unique id in the form of mCSB_1_dragger_vertical
, mCSB_2_dragger_vertical
etc. in addition to the class mCSB_dragger
. All these mean that you can do stuff like:
._mCS_1 .mCSB_dragger .mCSB_dragger_bar{ background-color: red; } ._mCS_2 .mCSB_dragger .mCSB_dragger_bar{ background-color: green; } #mCSB_3_dragger_vertical .mCSB_dragger_bar{ background-color: blue; } #mCSB_1_scrollbar_vertical .mCSB_dragger{ height: 100px; } #mCSB_1_scrollbar_horizontal .mCSB_dragger{ width: 100px; } .mCSB_1_scrollbar .mCSB_dragger .mCSB_draggerRail{ width: 4px; }
User-defined callbacks
You can trigger your own js function(s) by calling them inside mCustomScrollbar callbacks option parameter
$(".content").mCustomScrollbar({ callbacks:{ onScroll:function(){ myCustomFn(this); } } }); function myCustomFn(el){ console.log(el.mcs.top); }
In the example above, each time a scroll event ends and content has stopped scrolling, the content’s top position will be logged in browser’s console. There are available callbacks for each step of the scrolling event:
onScrollStart
– triggers the moment a scroll event startswhileScrolling
– triggers while scroll event is runningonScroll
– triggers when a scroll event completesonTotalScroll
– triggers when content has scrolled all the way to bottom or rightonTotalScrollBack
– triggers when content has scrolled all the way back to top or left
You can set an offset value (pixels) for both onTotalScroll
and onTotalScrollBack
by setting onTotalScrollOffset
and onTotalScrollBackOffset
respectively (view example).
By default, onTotalScroll
and onTotalScrollBack
callbacks are triggered repeatedly. To prevent multiple calls when content is within their offset, set alwaysTriggerOffsets
option to false
(view example).
Additional callbacks:
onInit
onOverflowY
onOverflowX
onOverflowYNone
onOverflowXNone
onUpdate
onImageLoad
onSelectorChange
Returning values
The script returns a number of values and objects related to scrollbar that you can use in your own functions
this
– the original element containing the scrollbar(s)this.mcs.content
– the original content wrapper as jquery objectthis.mcs.top
– content’s top position (pixels)this.mcs.left
– content’s left position (pixels)this.mcs.draggerTop
– scrollbar dragger’s top position (pixels)this.mcs.draggerLeft
– scrollbar dragger’s left position (pixels)this.mcs.topPct
– content vertical scrolling percentagethis.mcs.leftPct
– content horizontal scrolling percentagethis.mcs.direction
– content’s scrolling direction (y or x)
Plugin-specific jQuery expressions
$("#myID:mcsInView")
- Select element(s) in your content that are within scrollable viewport.
As condition:$("#myID").is(":mcsInView");
$(".content:mcsOverflow")
- Select overflowed element(s) with visible scrollbar.
As condition:$(".content").is(":mcsOverflow");
$("#myID:mcsInSight")
$("#myID:mcsInSight(exact)")
- Select element(s) in your content that are in view of the scrollable viewport. Using the
exact
parameter will include elements that have any part of them (even 1 pixel) in view of the scrollable viewport.
As condition:$("#myID").is(":mcsInSight");
,$("#myID").is(":mcsInSight(exact)");
Plugin dependencies & requirements
- jQuery version 1.6.0 or higher
- Mouse-wheel support
License
This work is released under the MIT License.
You are free to use, study, improve and modify it wherever and however you like.
https://opensource.org/licenses/MIT
Donating helps greatly in developing and updating free software and running this blog 🙂
I used in ajax:
onComplete: function() {
jQuery(“.content”).mCustomScrollbar({
axis:”yx”,
scrollButtons:{enable:true},
theme:”3d”,
scrollbarPosition:”outside”
});
}
but it doesn’t work….can you tell me why?
The custom scrollbar function seems correct, so maybe the problem is in your ajax call? I can’t really know…
So, i’ve set some options for the scroller, that just does not want to apply for some reason.
Created the following fiddle to describe the problem: http://jsfiddle.net/pz0jb1t4/
Why aren’t the options stated in the js section applying to the result!?
The way to do it is:
$(".SLIDEOUT_CONTAINER").mCustomScrollbar({ scrollInertia: 0, mouseWheel: { scrollAmount: "5vh", snapAmount: "5vh", deltafactor: "5vh" }, keyboard: { scrollAmount: "5vh" }, });
Still ain’t working.. 🙁
http://jsfiddle.net/pz0jb1t4/2/
Ah yes… You need to remove the mCustomScrollbar class from the element (you can’t initialize the plugin both in HTML and JS).
Thank you very much! – for both, taking the time to help people out, and for making this plugin!
Keep up the nice work man!
Hello! this is an excellent work about scrollbar, I am using your code and I have one problem. In a table when i have a row with only one data there is a scrollbar. How can i do to avoid this one?
Hello,
Can you create a fiddle or send me a link in order to understand the issue you’re having?
Hello!
I’ve got a problem with your scrollbar. I’ve got a friend panel (like Facebook’s friends online in chat) and I’m using jquery to show more info about friends on hover (so I use overflow:visible), but when I include your scrollbar, these info windows are showing inside my div with horizontal scrollbar. How can I make overflow-x to be always visible?
Thanks for your reply!
Without knowing your markup and code, I’d say that what you describe might not be possible as you cannot combine overflow hidden with visible on the same element (CSS limitation)
There’s a code:
http://codepen.io/anon/pen/XbWjNG
When you add your scrollbar to the left panel “Online priatelia”, info about friends won’t appear.
Thanks for reply!
Hi again.
I’m using your script for another site. Something strange is happening to my layout when I call the script – it looks like something is overriding my CSS.
Would you mind taking a look at http://barbaraungarophotography.com/published_NEW_LAYOUT.php
the horizontally scrolling pane should be 70% of the browser window width, but calling the script seems to truncate it to much less than that and only part of the content is scrollable.
Many thanks!
You probably need to enable autoExpandHorizontalScroll option parameter:
advanced:{ autoExpandHorizontalScroll: true }
Since your elements are not wrapped by a div wider than your element, you need the option above to let the script adjust (expand) the width automatically.
That works thanks. I missed that option in the instruction.
Is there a way I can disable the funny animations/quirky scrolling? All I need is the pretty scrollbar without all of these very fancy effects and movements..
See scrollInertia option parameter. You need to set it to zero:
scrollInertia: 0
Hello, sorry but if you initiate with HTML, do you still have to declare options such as scrollInertia in JS? I tried to ass data-mcs in front of it like for the axis but it doesn’t seem to be the way…
Data attributes work only for the basic options like “theme” and “axis”. For all others (like scrollInertia) you need JS.
I guess this sort of works but what I’m looking for is simply returning to the normal scrolling pattern of my browser. Setting inertia to 0 makes the scrolling (on a touchpad) very unstable. Any way to return back to default scrolling?
Great plugin BTW!
There’s no other option that affects animation. If you need to disable the custom scrollbar on mobile browsers/devices (but keep it on desktops etc.) you’ll have to use a library like WURFL.
Hi Malihu,
Thanks for the great plugin.
When i use this plugin for horizontal scrollbar in touch mobile device,
i can scroll correctly using slide touch to left and right.
But i can’t scroll down to bottom of the web content, since it can’t slide touch up and down.
How can i do to get all work together? slide right and right to scroll right and left on your scroll bar, but still can slide up and down inside container to scroll to up and down on the web content?
Thank you
Can you post your device/OS/browser combination?
Now you’ve said that. I tested in firefox on android it’s working. But chrome on android not working.
Yes indeed. Chrome on Android is the issue (it works on other browsers, iOS etc.). This is a known issue which I’ll try to fix on the next version.
Hi malihu, is it possible to replace the default browser scrollbar?
I tried something like this:
$(window).load(function(){
$(“body”).mCustomScrollbar();
});
but it doesnt work, any idea? Thanks 🙂
Hello Richard,
Your code seems correct. When you say it doesn’t work what happens exactly? Do you see the default scrollbar or there’s no scrollbar at all?
If you see the default scrollbar, do you get any console errors?
If there’s no scrollbar (custom or default), does your html/body element have a height value set? Does your content consists solely absolute positioned elements?
Thanks for the reply 🙂
Well im using the scrollbar on one page for some nested content, this works fine. But on the other page (and basically every page) im trying to use it on body and this doesnt work, the default scrollbar is shown.
And there are no console errors at all.
And no height on html/body except for this:
html { // position: relative; // min-height: 100%; }
Try the following:
html,body{ height: 100%; } body{ overflow: auto; }
That kind of worked, but then it showed both the custom and default scrollbar, i fixed this with overflow: hidden, so now it works on my second page. Thanks for help 🙂
I have found another problem now, targeting both the
$('body, .some-content')
is causing some layout problems, but targeting just the.some-content
worked fine.I think this might be due to the fact that .some-content is a child of absolutely positioned parent. But I dont want to bother you with this, its probably out of scope of this plugin, which is really great btw 🙂
Hi,
I’m using your plugin since a year ago, It is working perfect. Now i need to do few modification on callbacks, I’m using onTotalScroll event to load more content by AJAX, it is going good but the thing i need now is to call this event before its actually firing may be few pixel before end of scroll.
I’m sure you can help me out.
thanks
Hi,
You can determine an offset of pixels to fire the onTotalScroll callback by using the onTotalScrollOffset option.
For example, the following
callbacks:{ onTotalScroll: function(){ /* your function */ }, onTotalScrollOffset: 100 }
will trigger onTotalScroll 100 pixels before the end of scrolling is reached.
In addition, there’s also the alwaysTriggerOffsets option parameter to help determine the way callback offsets are used (see here for more info).
Plugin archive contains the infinite_scroll_example.html that makes use of the above.
Hi Manolis,
Thank you for the plug-in and being very responsive when giving feedback to the comments posted here.
However we have an issue that I didn’t manage to find a solution for in those comments.
Here it is. When searching a text on the page having a content scroller in it.
When the browser search navigates to the keyword found in the invisible part of the scrolable section the scrollbar of (1) the section disappears, (2) and when hovering the mouse pointer over the section and trying to scroll (e.g. with mouse wheel) the current position of the content is discarded and scrolled to the upmost point.
Could you please advice how can we overcome this issue.
Thanks,
Mkhitar
Hello,
This is actually a plugin usability feature to enable users to search for text within the content that has custom scrollbars (as they would with the default one). Unfortunately, there’s no way for javascript to detect or access this functionality in the browser (“Find in page”), so the script has to a)temporarily disable the custom scrollbar and b)reset the scrolling position afterwards.
Hi,
First of all, thanks for this wonderful plugin. 🙂
I would like to addClass when scroll event fired/starts, and removeClass when it comes back to top. Can you please guide me? How can I achieve this? Waiting for your quick response. 🙂
Thanks,
Javaid Chawwal
Hello,
You can do this by using plugin’s callbacks onScrollStart and onTotalScrollBack. For example:
$(".content").mCustomScrollbar({
callbacks:{
onScrollStart:function(){
$(this).addClass("your-class");
},
onTotalScrollBack:function(){
$(this).removeClass("your-class");
}
}
});
Hello,
Scroll amount when using wheel is about the same on Chrome And IE11, but it’s different for safari on windows. I’m gonna show my work to a person who uses MAC so is there any way to make it static for cross-browser ? Or did I screw up something? Thank you in advance… Great work!!!
Ps: Here’s the work i did:
You can set the mouseWheel scrollAmount to a fixed pixels value, e.g.
mouseWheel:{ scrollAmount: 40 }
Keep in mind that in general, mouse-wheel scrolling differs according to browser, OS and input device (mouse, trackpad, touch etc.).
Hi there, I am trying to implement your scrollbars (dark-2 theme with default settings) but have run into a couple of problems that I cannot find an answer to in the comments (is there a search facility for them?)
1. On pages with lots of content there is a list of hyperlinks (outside the scrolling section) which point to IDs to enable the reader to jump to the required point in the text.
My problem is that if I scroll through say 5o% of the text, I can then only navigate to those hyperlinks below the 50% line – i.e. non of the hyperlinks for the first 50% of the text work, they simply return you to the 50% scroll point.
This is even worse if the reader clicks on the last hyperlink and scrolls even a tiny amount as it then locks out ALL the hyper links, meaning a very long scroll to get back to the top
Tested on Chrome and IE11
2. After clicking on hyperlinks or going to other tabs in the browser, the scrollbars do not always re-appear when scrolling commences. The scrolling action is fine. Unfortunately, this issue is harder to consistently reproduce, hence the sometimes part.
Any help would be most appreciated
Forgot to mention that when you jump to a location using the hyperlink and then start scrolling, the test restarts from the top of the content, not the hyper-linked location.
Can you please recommend some settings as obviously I am not setting something correctly, but I assumed the default settings should be such that standard browser operations like these function normally.
Many thanks in advance
Hello,
To scroll-to an id within content that has custom scrollbar(s), you need to use plugin’s scrollTo method in your script(s). For example:
$(".content").mCustomScrollbar("scrollTo","#id");
Having simple links with href “#id” won’t scroll-to properly. You need the scrollTo method within a script to handle your links. For example you could do something like:
$("a[href*='#']").click(function(e){ e.preventDefault(); $(".content").mCustomScrollbar("scrollTo",$(this).attr("href")); });
You may also check the scrollTo_demo.html included in plugin archive.
Perfect!!! Many thanks, that cured all my problems in one go!
Just one cheeky question…. since I have used the HTML method of initialisation (i.e. calling the class & theme in the is there a method of applying your fix for ScrollTo functionality as well or do I need to change all the pages on the site to initialise via js (as per my now working test page)?
Thanks again for your great work
As long as your selector(s) is correct (e.g. “.content” in the example above) you don’t have to change anything. Is the selector an issue?
You could easily extend the click function to automatically get the proper selector for each target id (its parent element), so you don’t need to touch the markup at all… I could post such code if you want(?)
I just published a code example with a similar function that handles such links and finds the selector automatically:
http://manos.malihu.gr/code-example/scroll-to-id-within-element-with-custom-scrollbars/
Changing themes from 3d-thick to 3d-thick-dark and vice versa doesn’t seem to change the arrow color.
Ah, I guess calling .mCustomScrollbar({theme: theme}) again doesn’t change anything. Is there any way to change the theme after creation then?
Okay replacing css classes (from mCS-3d-thick to mCS-3d-thick-dark) seems to work.
On an unrelated note, is it possible to make it work with mwheelIntent to avoid nested scrollpanes from messing with wheel scrolling?
Maybe you need to use mouseWheel preventDefault option(?)
mouseWheel:{ preventDefault: true }
Hi. It seems to be a great tool. I have got an only need left.
I am trying to make vertical mcsb_scrolltools float over the full page content, I mean setting scrollbarPosition not “inside” nor “outside” but floating over the whole body content of the page. Just like the way NiceScroll does, for instance.
If I set it to “inside” the page content does not reach the right edge of the browser. Setting it to “outside” it appends the scrollbar to the right, but the horizontal scrollbar appears and you need to move it to the right to see our vertical custom scrollbar.
Is there a way with your jQuery Custom Content Scroller?
Thank you very much.
You can set it “outside” and change its right position via CSS by either editing jquery.mCustomScrollbar.css (line: 71) or by overwriting the rule in your own stylesheet, e.g.
.my-element .mCSB_scrollTools{ right: -20px; }
Everything regarding the scrollbar design, position etc. is done with CSS.
Hello Malihu.
I have a little problem with your scrollbar. I don’t really know if it’s correct behaviour but when I hover over item and just scroll down/up the hover stays on the item, but mouse is already gone. Do you have some solution for this?
Regards,
Vladimir.
This is how CSS :hover works with browsers. Most times you have to move the mouse over/out of an element to trigger :hover. If the mouse is still and only content is moving it might not trigger :hover.
I am seeing some very odd behavior when the scrollbar is applied to some image grids in firefox 37.0.1. When you hover, images appear to swap with each other in various places in the grid. I did not see this behavior in FF 36 and don’t see it in Chrome and IE11. Any thoughts on what might be causing it?
e.g., People grid in People & Insights slide
It appears this issue is related to FF 37. The nearest I can see so far is that when an image is inside a container that is not its original dimensions, it behaves very oddly. I haven’t gotten this far yet, but it’s possible that it only happens inside an tag.
Hi,
if I chance this line:
width: 800px;
in
width: 1200px;
The scroolbar doesn’t work . Why?
Thanks
.content{ overflow: auto; position: relative; padding-top:20px; width: 800px; max-width: 97%; height: 400px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
If it works with 800px width, it should also work with 1200px. Maybe with 1200px width the content doesn’t need scrolling?
Hello Malihu,
i wrote here like 1-2 months ago. I had problem with dynamic-content. Your answer was right, that i need use forx. (append) to add new content.
I dont understand why this code doesnt work.
<div class="pop_up_result"> <div id="wrapper_result"> </div> <button onclick="close_result();" id="close_result" type="button">close</button> </div> //initializaction scrollbar $("#wrapper_result").mCustomScrollbar({ axis: "y", // horizontal scrollbar theme: "dark" }); //after i click on some button, i append new content to wrapper_result function show_result(element) { $(".pop_up_result #wrapper_result").append("<p class=\"red\">" + escapeHtml("some_content") + "</p>"); // OK now my experimentation , what i read in documentation there are two ways ... 1. I tried use this option, when i call mCustomScrollbar() -> advanced:{ updateOnContentResize: boolean } Ok this doesnt help, scrollbar doesnt react on change content in wrapper_result. 2. I tried call this after i append new content. $("#wrapper_result").mCustomScrollbar("update"); Ok this doesnt help. 3. I was success only in this methods - find id of container forx. mCSB_13_container and append content here. or //destroy and run again mCustomScrollbar after i append new content. $("#wrapper_result").mCustomScrollbar("destroy"); $("#wrapper_result").mCustomScrollbar({ axis: "y", // horizontal scrollbar theme: "dark" }); }
My content is 100% added in my div id wrapper_result, i check it. Can be some problem in CSS? I have no idea where could be a problem… My two solutions ,what i wrote are success, but they are not apropriate.
I write here output from HTML, dunno if this help u, i had every time same output with automatic update.
.
.
.
// MY CONTENT HERE WHY? 🙁 .
“….”
close
Thank you for response
DC
Sorry for formating. again
I write here output from HTML, dunno if this help u, i had every time same output with automatic update.
<div class="pop_up_result" style="display: block;"> <div id="wrapper_result" class="mCustomScrollbar _mCS_4 mCS_no_scrollbar"> <div id="mCSB_4" class="mCustomScrollBox mCS-dark mCSB_vertical mCSB_inside" tabindex="0"> . . . </div> // MY CONTENT HERE WHY? :-( // This should be in div upper <p class="red"> "..." </p> </div> <button id="close_result" type="button" onclick="close_result();">close</button> </div>
I think you need to change:
$(".pop_up_result #wrapper_result").append("<p class=\"red\">" + escapeHtml("some_content") + "</p>");
to:
$(".pop_up_result #wrapper_result .mCSB_container").append("<p class=\"red\">" + escapeHtml("some_content") + "</p>");
Let me know if this helps
Does it not work with dynamic content? All it did for me was add a lot of space before actual content in every scrollable element, and the original scrollbars were still there.
Basically the content now looks like:
<div class="scroll-y"> <div id="mCSB_1" ...></div> <!-- actual content here --> </div>
Yes it does. If you want to append new content to any element that already has custom scrollbar(s), you need to add the new content inside the .mCSB_container div and not directly in the element itself. For example:
//initialization $(".content").mCustomScrollbar(); //later on... $(".content .mCSB_container").append("new content");
Does this help?
Hi, I’m trying to use minimal-dark theme on my website, but I don’t know how to do it, as u can see on it, it deleted content and doesn’t showed the scrollbar.
I have:
<body onload="document.getElementById('nacitamcstr').innerHTML='';" class="content mCustomScrollbar light" data-mcs-theme="minimal-dark">
and
(function($){ $(window).load(function(){ $(".content").mCustomScrollbar(); }); })(jQuery);
used, but it doesn’t working and I haven’t got good English enough to read full content of this website and earlier comments 🙁
Please help 🙁
You cannot use both ways of plugin initialization on the same element. To initialize via js, remove:
mCustomScrollbar
class and
data-mcs-theme="minimal-dark"
from body and make your script like this:
(function($){ $(window).load(function(){ $(".content").mCustomScrollbar({ theme:"minimal-dark" }); }); })(jQuery);
Awesome plugin..!! I am trying to use with html canvas with i-text. When ever I click on i-text the scroll bar is moving to the top automatically. I tried to disable all the updates but still couldn’t figure it out where the scroll bar is getting reset.
advanced:{
updateOnContentResize: false,
updateOnSelectorChange: “false”
}
Thanks.
Hi,
Maybe you need to disable autoScrollOnFocus option parameter instead?
advanced:{ autoScrollOnFocus: false }
Hi. How to scroll always stops at the bottom.how Fixed bottom ?
Hi,
I don’t really understand exactly what you need but I suspect you need to prevent page/parent scrolling when scrolling has reached the bottom(?)
If yes, you need to enable mouseWheel.preventDefault option:
mouseWheel:{ preventDefault: true }
its not smooth in mobile phone.. any solution?
Performance may vary due to many factors. Try disabling (one or both) of the following options and see if it gets smoother:
advanced:{ updateOnImageLoad: false, updateOnContentResize: false }
i did whatever you said. it still sucks..
also i have read from somewhere that , this plugin does not work well with mobile touch.
do you have any solid solution???
here is website: http://24by7freelancers.com/sandyporter/
this is my competitor website:
http://www.gavinoneill.com/latestwork
and it works fine there , on mobile device
this is my competitor website:
http://www.gavinoneill.com/latestwork
if you check this website in mobile. the mobile touch is very smooth.
Hi
I think there’s a problem with how the script implements the “live” option. If I set live to true, everytime an element with the selector class is created runtime, the scrollbar will not only initialize the new element, but also all previous elements, giving previous elements double scrollbars. Is this intended and is there a way to stop this? Thanks!
Regards, Mike
Hello,
Which plugin version are you using? The plugin script should not add double scrollbars on elements that already have a scrollbar…
Can you send me a test page/link?
Hi i’m having a strange problem, probably easily fixed if anyone has a spare minute to help.
I’ve succesfully used this custom scrollbar for a div inside my page… however i tried to apply it to the BODY in order to replace the default browser one altogether.
For some reason as you can see on this page: http://we0215.coursifage.net/guillaume/Pages/Concerts.html
The custom bar works perfectly for navigating the page, but the default bar remains also, and can only scroll up/down a few pixels.
I simply used the javascript as such:
(function($){
$(window).load(function(){
$(“body”).mCustomScrollbar();
$(“.EventBox”).mCustomScrollbar();
$(“#upcoming”).mCustomScrollbar();
});
})(jQuery);
//Where the .EventBox and #upcoming are 2 divs in my page, both of which are working correctly.
Any help or suggestions to remove the default bar altogether would be very appreciated, thank you.
In your CSS you need to set:
body{ overflow: hidden; }
Thank you so much, that did it 🙂
I am using this plugin and I think it is great, it is the first really easy to use plugin of it’s kind I have come across and much less ‘buggy’ than JScrollPane.
I have been able to customise the look of the scroll bar quite easily I just have a few questions.
1. When I colour the Dragger Bar using the
.mCSB_Dragger_bar
it seems to have a filter so if I set it to one colour, for example blue it will turn out a slightly different colour as if it has a filter and I have looked at the css code that comes with the plugin and cannot work out what is causing this affect.2. I am struggling to use scroll attributes listed above to make the scrolling more like the native chrome effect. The scroll inertia is having little effect and when the dragger bar gets to the top of the rail it suddenly moves much more slowly.
I hope that someone can help with this problem…
Thanks in Advance
1. The scrollbar opacity changes according to its state (dragging, hover etc.). You can find the CSS applied in jquery.mCustomScrollbar.css in section 6 (from line 340 for the default theme). You can change the rules directly or overwrite them in your stylesheet.
2. You can completely disable scrolling inertia by setting its value really low or zero:
scrollInertia: 0
Thanks, will that apply to both scrolling on a mouse and on a touchpad…
I have been doing some more testing and the problem with the slow scrolling speed disappears with a mouse and only is a problem with a touchpad…
Hi,
I am doing some experiments with the custom scroll bar and I have encountered the following issue:
I have the following html:
<div id="content-7" style="overflow:auto; height:550px; width:200px; max-width:200px; position:relative" > <div style="position: absolute; left:0px; width:100px; height:500px; background-color:red"> </div> <div style="position: absolute; left:100px; width:100px;height:500px;background-color:blue"> </div> <div style="position: absolute; left:200px; width:100px; height:500px;background-color:green"> </div> <div style="position: absolute; left:300px; width:100px;height:500px;background-color:orange"> </div> <div style="position: absolute; left:400px; width:100px; height:500px;background-color:brown"> </div> </div>
and the following jquery:
$("#content-7").mCustomScrollbar({ axis:"x", scrollButtons:{ enable: true }, theme:"dark-3", }); }); })(jQuery);
The problem is that once the jquery is called, the content disappears. After doing some experiments I found out that the problem is the absolute position. I was looking at other comments and there was a mention of creating a wrapper with fixed height but it did not solve the problem, since the scroll bar still did not show. In the scenario I need to use this, I need to use absolute position, so I cannot remove the absolute position. Any ideas please?
Thanks and Regards
Jason
For a horizontal scrollbar you’d need a wrapper with a fixed width (instead of height). In any case, since your elements have a fixed width (100px) why you need the absolute position? Or is this just a test?
this is a test example. In the scenario I want to use this it is more complex. Can you please give me an example of the wrapper? I have tried doing the following but still the contents is disappearing.
<div id="content-7" style="overflow:auto; height:550px; width:200px; max-width:200px;" > <div style="width:200px; position:relative;"> <div style="position: absolute; left:0px; width:100px; height:500px; background-color:red"> </div> <div style="position: absolute; left:100px; width:100px;height:500px;background-color:blue"> </div> <div style="position: absolute; left:200px; width:100px; height:500px;background-color:green"> </div> <div style="position: absolute; left:300px; width:100px;height:500px;background-color:orange"> </div> <div style="position: absolute; left:400px; width:100px; height:500px;background-color:brown"> </div> </div> </div>
Hello,
I have this custom scrollbar on my site and it works great, but it sometimes freezes on touch devices. I tried to debug it in Chrome and I found out that it freezes after a `touchend` event. This event does not occur every time you scroll the page, mostly it’s just `touchmove`. But when `touchend` occurs, bad luck. The scrollbar stops reactivng to touch events until you click somewhere on the page.
No such problems on your demo pages though. Maybe it’s because I use it inside an iframe or because the content inside is not a simple text.
Is it possible to provide the scroll bar to object tag i.e. I am showing PDF in that object so Can I apply this scroll bar effect to that object tag.
Thanks,
Ronak