├── .gitignore ├── CHANGELOG.md ├── README.md ├── bower.json ├── index.js ├── jquery.scrollbar.css ├── jquery.scrollbar.js ├── jquery.scrollbar.min.js ├── license-gpl.txt ├── license-mit.txt ├── meteor └── tests.js ├── package.js ├── package.json ├── sass ├── Gruntfile.js ├── config.rb ├── jquery.scrollbar.scss └── package.json └── scrollbar.jquery.json /.gitignore: -------------------------------------------------------------------------------- 1 | .netbeans.xml 2 | .sass-cache 3 | node_modules 4 | nbproject -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 |

v0.2.11 (20160803)

2 | Fix bug with Mozilla FireFox 3 | 4 |

v0.2.10 (20151216)

5 | Increase version to update bower repository 6 | 7 |

v0.2.9 (20151022)

8 | Increase version to update bower repository 9 | 10 |

v0.2.8 (20150723)

11 | Add Meteor/Node modules support
12 | Fix bug when removed content does not update element's height
13 | Fix bug with textarea in non-webkit browsers
14 | Update webkit-based browser detection to ignore Microsoft Edge browser
15 | Change default values for ignoreMobile/ignoreOverlay to false
16 | 17 |

v0.2.7 (20150122)

18 | Small fixes
19 | 20 |

v0.2.6 (20141124)

21 | Re-register plugin in jQuery plugins repository
22 | 23 |

v0.2.5 (20141119)

24 | Add option ignoreOverlay with default value true
25 | Fix webkit-based browser detection
26 | Ignore Firefox in Mac OS (cannot hide native scrollbars)
27 | 28 |

v0.2.4 (20140715)

29 | Add textarea support
30 | 31 |

v0.2.3 (20140703)

32 | Default options can be overwritten via default global object
33 | Fix bug with visible native scrollbars when page is zoomed
34 | Add onScroll callback
35 | Add Angular.JS directive
36 | 37 |

v0.2.2 (20140411)

38 | Fix default options issue with multiple scrollbars initialization
39 | 40 |

v0.2.1 (20140323)

41 | Update CSS classes for custom scroll elements
42 | Set option ignoreMobile to true by default
43 | Small CSS/JS fixes
44 | 45 |

v0.2.0 (20140312)

46 | Add onUpdate callback
47 | Manage scrollbar visibility via CSS classes
48 | 49 |

v0.1.9 (20140310)

50 | Fix bug with inner div height 100%
51 | Add option autoUpdate
52 | 53 |

v0.1.8 (20140308)

54 | Fix bug with visible horizontal scrollbar if content height is less than container height
55 | 56 |

v0.1.7 (20140307)

57 | Add hack for IE9-11 with 1px diff between visible and scrollable height
58 | Fix bug with second-time plugin initialization
59 | Remove warnings from IDE
60 | 61 |

v0.1.4 (20130430)

62 | Add horizontal scrollbar handler
63 | Add option disableBodyScroll
64 | 65 |

v0.1.3 (20130423)

66 | Improve scroll simulation
67 | Fix webkit bug with text selection
68 | 69 |

v0.1.2 (20130422)

70 | Handle mousedown instead of click on scrollbar track/arrows
71 | 72 |

v0.0.2 (20130413)

73 | First version
74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

jQuery Scrollbar

2 | 3 | Cross-browser CSS customizable scrollbar with advanced features: 4 | 18 | 19 |

Basic Scrollbars Demo

20 |

Advanced Scrollbars Demo

21 |

jQuery Scrollbar as Angular.JS directive

22 | 23 |

Documentation

24 |

Changelog

25 |

Download

26 | 27 | 1 There is known issue that native browser scrollbar cannot be hidden in Firefox on Apple devices, so this plugin is not initialized and you will see native scrollbars. 28 | 2 Experimental support in master branch, styles for scrollbars are not updated 29 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.scrollbar", 3 | "version": "0.2.11", 4 | "main": [ 5 | "./jquery.scrollbar.js", 6 | "./jquery.scrollbar.css" 7 | ], 8 | "dependencies": { 9 | "jquery": ">=1.7" 10 | }, 11 | "ignore": [ 12 | ".*", 13 | "*.json", 14 | "*.md", 15 | "*.txt" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('./jquery.scrollbar'); 2 | module.exports = 'jQueryScrollbar'; 3 | 4 | -------------------------------------------------------------------------------- /jquery.scrollbar.css: -------------------------------------------------------------------------------- 1 | /*************** SCROLLBAR BASE CSS ***************/ 2 | .scroll-wrapper { 3 | overflow: hidden !important; 4 | padding: 0 !important; 5 | position: relative; 6 | } 7 | .scroll-wrapper > .scroll-content { 8 | border: none !important; 9 | box-sizing: content-box !important; 10 | height: auto; 11 | left: 0; 12 | margin: 0; 13 | max-height: none; 14 | max-width: none !important; 15 | overflow: scroll !important; 16 | padding: 0; 17 | position: relative !important; 18 | top: 0; 19 | width: auto !important; 20 | } 21 | .scroll-wrapper > .scroll-content::-webkit-scrollbar { 22 | height: 0; 23 | width: 0; 24 | } 25 | .scroll-wrapper.scroll--rtl { 26 | direction: rtl; 27 | } 28 | 29 | .scroll-element { 30 | box-sizing: content-box; 31 | display: none; 32 | } 33 | .scroll-element div { 34 | box-sizing: content-box; 35 | } 36 | .scroll-element .scroll-bar, 37 | .scroll-element .scroll-arrow { 38 | cursor: default; 39 | } 40 | .scroll-element.scroll-x.scroll-scrollx_visible, .scroll-element.scroll-y.scroll-scrolly_visible { 41 | display: block; 42 | } 43 | 44 | .scroll-textarea { 45 | border: 1px solid #cccccc; 46 | border-top-color: #999999; 47 | } 48 | .scroll-textarea > .scroll-content { 49 | overflow: hidden !important; 50 | } 51 | .scroll-textarea > .scroll-content > textarea { 52 | border: none !important; 53 | box-sizing: border-box; 54 | height: 100% !important; 55 | margin: 0; 56 | max-height: none !important; 57 | max-width: none !important; 58 | overflow: scroll !important; 59 | outline: none; 60 | padding: 2px; 61 | position: relative !important; 62 | top: 0; 63 | width: 100% !important; 64 | } 65 | .scroll-textarea > .scroll-content > textarea::-webkit-scrollbar { 66 | height: 0; 67 | width: 0; 68 | } 69 | 70 | /*************** SIMPLE INNER SCROLLBAR ***************/ 71 | .scrollbar-inner > .scroll-element, 72 | .scrollbar-inner > .scroll-element div { 73 | border: none; 74 | margin: 0; 75 | padding: 0; 76 | position: absolute; 77 | z-index: 10; 78 | } 79 | 80 | .scrollbar-inner > .scroll-element div { 81 | display: block; 82 | height: 100%; 83 | left: 0; 84 | top: 0; 85 | width: 100%; 86 | } 87 | 88 | .scrollbar-inner > .scroll-element.scroll-x { 89 | bottom: 2px; 90 | height: 8px; 91 | left: 0; 92 | width: 100%; 93 | } 94 | 95 | .scrollbar-inner > .scroll-element.scroll-y { 96 | height: 100%; 97 | right: 2px; 98 | top: 0; 99 | width: 8px; 100 | } 101 | 102 | .scrollbar-inner > .scroll-element .scroll-element_outer { 103 | overflow: hidden; 104 | } 105 | 106 | .scrollbar-inner > .scroll-element .scroll-element_outer, 107 | .scrollbar-inner > .scroll-element .scroll-element_track, 108 | .scrollbar-inner > .scroll-element .scroll-bar { 109 | -webkit-border-radius: 8px; 110 | -moz-border-radius: 8px; 111 | border-radius: 8px; 112 | } 113 | 114 | .scrollbar-inner > .scroll-element .scroll-element_track, 115 | .scrollbar-inner > .scroll-element .scroll-bar { 116 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; 117 | filter: alpha(opacity=40); 118 | opacity: 0.4; 119 | } 120 | 121 | .scrollbar-inner > .scroll-element .scroll-element_track { 122 | background-color: #e0e0e0; 123 | } 124 | 125 | .scrollbar-inner > .scroll-element .scroll-bar { 126 | background-color: #c2c2c2; 127 | } 128 | 129 | .scrollbar-inner > .scroll-element:hover .scroll-bar { 130 | background-color: #919191; 131 | } 132 | 133 | .scrollbar-inner > .scroll-element.scroll-draggable .scroll-bar { 134 | background-color: #919191; 135 | } 136 | 137 | /* update scrollbar offset if both scrolls are visible */ 138 | .scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { 139 | left: -12px; 140 | } 141 | 142 | .scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { 143 | top: -12px; 144 | } 145 | 146 | .scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 147 | left: -12px; 148 | } 149 | 150 | .scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 151 | top: -12px; 152 | } 153 | 154 | /*************** SIMPLE OUTER SCROLLBAR ***************/ 155 | .scrollbar-outer > .scroll-element, 156 | .scrollbar-outer > .scroll-element div { 157 | border: none; 158 | margin: 0; 159 | padding: 0; 160 | position: absolute; 161 | z-index: 10; 162 | } 163 | 164 | .scrollbar-outer > .scroll-element { 165 | background-color: #ffffff; 166 | } 167 | 168 | .scrollbar-outer > .scroll-element div { 169 | display: block; 170 | height: 100%; 171 | left: 0; 172 | top: 0; 173 | width: 100%; 174 | } 175 | 176 | .scrollbar-outer > .scroll-element.scroll-x { 177 | bottom: 0; 178 | height: 12px; 179 | left: 0; 180 | width: 100%; 181 | } 182 | 183 | .scrollbar-outer > .scroll-element.scroll-y { 184 | height: 100%; 185 | right: 0; 186 | top: 0; 187 | width: 12px; 188 | } 189 | 190 | .scrollbar-outer > .scroll-element.scroll-x .scroll-element_outer { 191 | height: 8px; 192 | top: 2px; 193 | } 194 | 195 | .scrollbar-outer > .scroll-element.scroll-y .scroll-element_outer { 196 | left: 2px; 197 | width: 8px; 198 | } 199 | 200 | .scrollbar-outer > .scroll-element .scroll-element_outer { 201 | overflow: hidden; 202 | } 203 | 204 | .scrollbar-outer > .scroll-element .scroll-element_track { 205 | background-color: #eeeeee; 206 | } 207 | 208 | .scrollbar-outer > .scroll-element .scroll-element_outer, 209 | .scrollbar-outer > .scroll-element .scroll-element_track, 210 | .scrollbar-outer > .scroll-element .scroll-bar { 211 | -webkit-border-radius: 8px; 212 | -moz-border-radius: 8px; 213 | border-radius: 8px; 214 | } 215 | 216 | .scrollbar-outer > .scroll-element .scroll-bar { 217 | background-color: #d9d9d9; 218 | } 219 | 220 | .scrollbar-outer > .scroll-element .scroll-bar:hover { 221 | background-color: #c2c2c2; 222 | } 223 | 224 | .scrollbar-outer > .scroll-element.scroll-draggable .scroll-bar { 225 | background-color: #919191; 226 | } 227 | 228 | /* scrollbar height/width & offset from container borders */ 229 | .scrollbar-outer > .scroll-content.scroll-scrolly_visible { 230 | left: -12px; 231 | margin-left: 12px; 232 | } 233 | 234 | .scrollbar-outer > .scroll-content.scroll-scrollx_visible { 235 | top: -12px; 236 | margin-top: 12px; 237 | } 238 | 239 | .scrollbar-outer > .scroll-element.scroll-x .scroll-bar { 240 | min-width: 10px; 241 | } 242 | 243 | .scrollbar-outer > .scroll-element.scroll-y .scroll-bar { 244 | min-height: 10px; 245 | } 246 | 247 | /* update scrollbar offset if both scrolls are visible */ 248 | .scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { 249 | left: -14px; 250 | } 251 | 252 | .scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { 253 | top: -14px; 254 | } 255 | 256 | .scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 257 | left: -14px; 258 | } 259 | 260 | .scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 261 | top: -14px; 262 | } 263 | 264 | /*************** SCROLLBAR MAC OS X ***************/ 265 | .scrollbar-macosx > .scroll-element, 266 | .scrollbar-macosx > .scroll-element div { 267 | background: none; 268 | border: none; 269 | margin: 0; 270 | padding: 0; 271 | position: absolute; 272 | z-index: 10; 273 | } 274 | 275 | .scrollbar-macosx > .scroll-element div { 276 | display: block; 277 | height: 100%; 278 | left: 0; 279 | top: 0; 280 | width: 100%; 281 | } 282 | 283 | .scrollbar-macosx > .scroll-element .scroll-element_track { 284 | display: none; 285 | } 286 | 287 | .scrollbar-macosx > .scroll-element .scroll-bar { 288 | background-color: #6C6E71; 289 | display: block; 290 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 291 | filter: alpha(opacity=0); 292 | opacity: 0; 293 | -webkit-border-radius: 7px; 294 | -moz-border-radius: 7px; 295 | border-radius: 7px; 296 | -webkit-transition: opacity 0.2s linear; 297 | -moz-transition: opacity 0.2s linear; 298 | -o-transition: opacity 0.2s linear; 299 | -ms-transition: opacity 0.2s linear; 300 | transition: opacity 0.2s linear; 301 | } 302 | 303 | .scrollbar-macosx:hover > .scroll-element .scroll-bar, 304 | .scrollbar-macosx > .scroll-element.scroll-draggable .scroll-bar { 305 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; 306 | filter: alpha(opacity=70); 307 | opacity: 0.7; 308 | } 309 | 310 | .scrollbar-macosx > .scroll-element.scroll-x { 311 | bottom: 0px; 312 | height: 0px; 313 | left: 0; 314 | min-width: 100%; 315 | overflow: visible; 316 | width: 100%; 317 | } 318 | 319 | .scrollbar-macosx > .scroll-element.scroll-y { 320 | height: 100%; 321 | min-height: 100%; 322 | right: 0px; 323 | top: 0; 324 | width: 0px; 325 | } 326 | 327 | /* scrollbar height/width & offset from container borders */ 328 | .scrollbar-macosx > .scroll-element.scroll-x .scroll-bar { 329 | height: 7px; 330 | min-width: 10px; 331 | top: -9px; 332 | } 333 | 334 | .scrollbar-macosx > .scroll-element.scroll-y .scroll-bar { 335 | left: -9px; 336 | min-height: 10px; 337 | width: 7px; 338 | } 339 | 340 | .scrollbar-macosx > .scroll-element.scroll-x .scroll-element_outer { 341 | left: 2px; 342 | } 343 | 344 | .scrollbar-macosx > .scroll-element.scroll-x .scroll-element_size { 345 | left: -4px; 346 | } 347 | 348 | .scrollbar-macosx > .scroll-element.scroll-y .scroll-element_outer { 349 | top: 2px; 350 | } 351 | 352 | .scrollbar-macosx > .scroll-element.scroll-y .scroll-element_size { 353 | top: -4px; 354 | } 355 | 356 | /* update scrollbar offset if both scrolls are visible */ 357 | .scrollbar-macosx > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 358 | left: -11px; 359 | } 360 | 361 | .scrollbar-macosx > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 362 | top: -11px; 363 | } 364 | 365 | /*************** SCROLLBAR LIGHT ***************/ 366 | .scrollbar-light > .scroll-element, 367 | .scrollbar-light > .scroll-element div { 368 | border: none; 369 | margin: 0; 370 | overflow: hidden; 371 | padding: 0; 372 | position: absolute; 373 | z-index: 10; 374 | } 375 | 376 | .scrollbar-light > .scroll-element { 377 | background-color: #ffffff; 378 | } 379 | 380 | .scrollbar-light > .scroll-element div { 381 | display: block; 382 | height: 100%; 383 | left: 0; 384 | top: 0; 385 | width: 100%; 386 | } 387 | 388 | .scrollbar-light > .scroll-element .scroll-element_outer { 389 | -webkit-border-radius: 10px; 390 | -moz-border-radius: 10px; 391 | border-radius: 10px; 392 | } 393 | 394 | .scrollbar-light > .scroll-element .scroll-element_size { 395 | background: #dbdbdb; 396 | background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiZGJkYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlOGU4ZTgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+"); 397 | background: -moz-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%); 398 | background: -webkit-gradient(linear, left top, right top, color-stop(0%, #dbdbdb), color-stop(100%, #e8e8e8)); 399 | background: -webkit-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%); 400 | background: -o-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%); 401 | background: -ms-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%); 402 | background: linear-gradient(to right, #dbdbdb 0%, #e8e8e8 100%); 403 | -webkit-border-radius: 10px; 404 | -moz-border-radius: 10px; 405 | border-radius: 10px; 406 | } 407 | 408 | .scrollbar-light > .scroll-element.scroll-x { 409 | bottom: 0; 410 | height: 17px; 411 | left: 0; 412 | min-width: 100%; 413 | width: 100%; 414 | } 415 | 416 | .scrollbar-light > .scroll-element.scroll-y { 417 | height: 100%; 418 | min-height: 100%; 419 | right: 0; 420 | top: 0; 421 | width: 17px; 422 | } 423 | 424 | .scrollbar-light > .scroll-element .scroll-bar { 425 | background: #fefefe; 426 | background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZmVmZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+"); 427 | background: -moz-linear-gradient(left, #fefefe 0%, #f5f5f5 100%); 428 | background: -webkit-gradient(linear, left top, right top, color-stop(0%, #fefefe), color-stop(100%, #f5f5f5)); 429 | background: -webkit-linear-gradient(left, #fefefe 0%, #f5f5f5 100%); 430 | background: -o-linear-gradient(left, #fefefe 0%, #f5f5f5 100%); 431 | background: -ms-linear-gradient(left, #fefefe 0%, #f5f5f5 100%); 432 | background: linear-gradient(to right, #fefefe 0%, #f5f5f5 100%); 433 | border: 1px solid #dbdbdb; 434 | -webkit-border-radius: 10px; 435 | -moz-border-radius: 10px; 436 | border-radius: 10px; 437 | } 438 | 439 | /* scrollbar height/width & offset from container borders */ 440 | .scrollbar-light > .scroll-content.scroll-scrolly_visible { 441 | left: -17px; 442 | margin-left: 17px; 443 | } 444 | 445 | .scrollbar-light > .scroll-content.scroll-scrollx_visible { 446 | top: -17px; 447 | margin-top: 17px; 448 | } 449 | 450 | .scrollbar-light > .scroll-element.scroll-x .scroll-bar { 451 | height: 10px; 452 | min-width: 10px; 453 | top: 0px; 454 | } 455 | 456 | .scrollbar-light > .scroll-element.scroll-y .scroll-bar { 457 | left: 0px; 458 | min-height: 10px; 459 | width: 10px; 460 | } 461 | 462 | .scrollbar-light > .scroll-element.scroll-x .scroll-element_outer { 463 | height: 12px; 464 | left: 2px; 465 | top: 2px; 466 | } 467 | 468 | .scrollbar-light > .scroll-element.scroll-x .scroll-element_size { 469 | left: -4px; 470 | } 471 | 472 | .scrollbar-light > .scroll-element.scroll-y .scroll-element_outer { 473 | left: 2px; 474 | top: 2px; 475 | width: 12px; 476 | } 477 | 478 | .scrollbar-light > .scroll-element.scroll-y .scroll-element_size { 479 | top: -4px; 480 | } 481 | 482 | /* update scrollbar offset if both scrolls are visible */ 483 | .scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 484 | left: -19px; 485 | } 486 | 487 | .scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 488 | top: -19px; 489 | } 490 | 491 | .scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { 492 | left: -19px; 493 | } 494 | 495 | .scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { 496 | top: -19px; 497 | } 498 | 499 | /*************** SCROLLBAR RAIL ***************/ 500 | .scrollbar-rail > .scroll-element, 501 | .scrollbar-rail > .scroll-element div { 502 | border: none; 503 | margin: 0; 504 | overflow: hidden; 505 | padding: 0; 506 | position: absolute; 507 | z-index: 10; 508 | } 509 | 510 | .scrollbar-rail > .scroll-element { 511 | background-color: #ffffff; 512 | } 513 | 514 | .scrollbar-rail > .scroll-element div { 515 | display: block; 516 | height: 100%; 517 | left: 0; 518 | top: 0; 519 | width: 100%; 520 | } 521 | 522 | .scrollbar-rail > .scroll-element .scroll-element_size { 523 | background-color: #999; 524 | background-color: rgba(0, 0, 0, 0.3); 525 | } 526 | 527 | .scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-element_size { 528 | background-color: #666; 529 | background-color: rgba(0, 0, 0, 0.5); 530 | } 531 | 532 | .scrollbar-rail > .scroll-element.scroll-x { 533 | bottom: 0; 534 | height: 12px; 535 | left: 0; 536 | min-width: 100%; 537 | padding: 3px 0 2px; 538 | width: 100%; 539 | } 540 | 541 | .scrollbar-rail > .scroll-element.scroll-y { 542 | height: 100%; 543 | min-height: 100%; 544 | padding: 0 2px 0 3px; 545 | right: 0; 546 | top: 0; 547 | width: 12px; 548 | } 549 | 550 | .scrollbar-rail > .scroll-element .scroll-bar { 551 | background-color: #d0b9a0; 552 | -webkit-border-radius: 2px; 553 | -moz-border-radius: 2px; 554 | border-radius: 2px; 555 | box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5); 556 | } 557 | 558 | .scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-bar { 559 | box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6); 560 | } 561 | 562 | /* scrollbar height/width & offset from container borders */ 563 | .scrollbar-rail > .scroll-content.scroll-scrolly_visible { 564 | left: -17px; 565 | margin-left: 17px; 566 | } 567 | 568 | .scrollbar-rail > .scroll-content.scroll-scrollx_visible { 569 | margin-top: 17px; 570 | top: -17px; 571 | } 572 | 573 | .scrollbar-rail > .scroll-element.scroll-x .scroll-bar { 574 | height: 10px; 575 | min-width: 10px; 576 | top: 1px; 577 | } 578 | 579 | .scrollbar-rail > .scroll-element.scroll-y .scroll-bar { 580 | left: 1px; 581 | min-height: 10px; 582 | width: 10px; 583 | } 584 | 585 | .scrollbar-rail > .scroll-element.scroll-x .scroll-element_outer { 586 | height: 15px; 587 | left: 5px; 588 | } 589 | 590 | .scrollbar-rail > .scroll-element.scroll-x .scroll-element_size { 591 | height: 2px; 592 | left: -10px; 593 | top: 5px; 594 | } 595 | 596 | .scrollbar-rail > .scroll-element.scroll-y .scroll-element_outer { 597 | top: 5px; 598 | width: 15px; 599 | } 600 | 601 | .scrollbar-rail > .scroll-element.scroll-y .scroll-element_size { 602 | left: 5px; 603 | top: -10px; 604 | width: 2px; 605 | } 606 | 607 | /* update scrollbar offset if both scrolls are visible */ 608 | .scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 609 | left: -25px; 610 | } 611 | 612 | .scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 613 | top: -25px; 614 | } 615 | 616 | .scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { 617 | left: -25px; 618 | } 619 | 620 | .scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { 621 | top: -25px; 622 | } 623 | 624 | /*************** SCROLLBAR DYNAMIC ***************/ 625 | .scrollbar-dynamic > .scroll-element, 626 | .scrollbar-dynamic > .scroll-element div { 627 | background: none; 628 | border: none; 629 | margin: 0; 630 | padding: 0; 631 | position: absolute; 632 | z-index: 10; 633 | } 634 | 635 | .scrollbar-dynamic > .scroll-element div { 636 | display: block; 637 | height: 100%; 638 | left: 0; 639 | top: 0; 640 | width: 100%; 641 | } 642 | 643 | .scrollbar-dynamic > .scroll-element.scroll-x { 644 | bottom: 2px; 645 | height: 7px; 646 | left: 0; 647 | min-width: 100%; 648 | width: 100%; 649 | } 650 | 651 | .scrollbar-dynamic > .scroll-element.scroll-y { 652 | height: 100%; 653 | min-height: 100%; 654 | right: 2px; 655 | top: 0; 656 | width: 7px; 657 | } 658 | 659 | .scrollbar-dynamic > .scroll-element .scroll-element_outer { 660 | opacity: 0.3; 661 | -webkit-border-radius: 12px; 662 | -moz-border-radius: 12px; 663 | border-radius: 12px; 664 | } 665 | 666 | .scrollbar-dynamic > .scroll-element .scroll-element_size { 667 | background-color: #cccccc; 668 | opacity: 0; 669 | -webkit-border-radius: 12px; 670 | -moz-border-radius: 12px; 671 | border-radius: 12px; 672 | -webkit-transition: opacity 0.2s; 673 | -moz-transition: opacity 0.2s; 674 | -o-transition: opacity 0.2s; 675 | -ms-transition: opacity 0.2s; 676 | transition: opacity 0.2s; 677 | } 678 | 679 | .scrollbar-dynamic > .scroll-element .scroll-bar { 680 | background-color: #6c6e71; 681 | -webkit-border-radius: 7px; 682 | -moz-border-radius: 7px; 683 | border-radius: 7px; 684 | } 685 | 686 | /* scrollbar height/width & offset from container borders */ 687 | .scrollbar-dynamic > .scroll-element.scroll-x .scroll-bar { 688 | bottom: 0; 689 | height: 7px; 690 | min-width: 24px; 691 | top: auto; 692 | } 693 | 694 | .scrollbar-dynamic > .scroll-element.scroll-y .scroll-bar { 695 | left: auto; 696 | min-height: 24px; 697 | right: 0; 698 | width: 7px; 699 | } 700 | 701 | .scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_outer { 702 | bottom: 0; 703 | top: auto; 704 | left: 2px; 705 | -webkit-transition: height 0.2s; 706 | -moz-transition: height 0.2s; 707 | -o-transition: height 0.2s; 708 | -ms-transition: height 0.2s; 709 | transition: height 0.2s; 710 | } 711 | 712 | .scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_outer { 713 | left: auto; 714 | right: 0; 715 | top: 2px; 716 | -webkit-transition: width 0.2s; 717 | -moz-transition: width 0.2s; 718 | -o-transition: width 0.2s; 719 | -ms-transition: width 0.2s; 720 | transition: width 0.2s; 721 | } 722 | 723 | .scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_size { 724 | left: -4px; 725 | } 726 | 727 | .scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_size { 728 | top: -4px; 729 | } 730 | 731 | /* update scrollbar offset if both scrolls are visible */ 732 | .scrollbar-dynamic > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 733 | left: -11px; 734 | } 735 | 736 | .scrollbar-dynamic > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 737 | top: -11px; 738 | } 739 | 740 | /* hover & drag */ 741 | .scrollbar-dynamic > .scroll-element:hover .scroll-element_outer, 742 | .scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer { 743 | overflow: hidden; 744 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; 745 | filter: alpha(opacity=70); 746 | opacity: 0.7; 747 | } 748 | 749 | .scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-element_size, 750 | .scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-element_size { 751 | opacity: 1; 752 | } 753 | 754 | .scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-bar, 755 | .scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-bar { 756 | height: 100%; 757 | width: 100%; 758 | -webkit-border-radius: 12px; 759 | -moz-border-radius: 12px; 760 | border-radius: 12px; 761 | } 762 | 763 | .scrollbar-dynamic > .scroll-element.scroll-x:hover .scroll-element_outer, 764 | .scrollbar-dynamic > .scroll-element.scroll-x.scroll-draggable .scroll-element_outer { 765 | height: 20px; 766 | min-height: 7px; 767 | } 768 | 769 | .scrollbar-dynamic > .scroll-element.scroll-y:hover .scroll-element_outer, 770 | .scrollbar-dynamic > .scroll-element.scroll-y.scroll-draggable .scroll-element_outer { 771 | min-width: 7px; 772 | width: 20px; 773 | } 774 | 775 | /*************** SCROLLBAR GOOGLE CHROME ***************/ 776 | .scrollbar-chrome > .scroll-element, 777 | .scrollbar-chrome > .scroll-element div { 778 | border: none; 779 | margin: 0; 780 | overflow: hidden; 781 | padding: 0; 782 | position: absolute; 783 | z-index: 10; 784 | } 785 | 786 | .scrollbar-chrome > .scroll-element { 787 | background-color: #ffffff; 788 | } 789 | 790 | .scrollbar-chrome > .scroll-element div { 791 | display: block; 792 | height: 100%; 793 | left: 0; 794 | top: 0; 795 | width: 100%; 796 | } 797 | 798 | .scrollbar-chrome > .scroll-element .scroll-element_track { 799 | background: #f1f1f1; 800 | border: 1px solid #dbdbdb; 801 | } 802 | 803 | .scrollbar-chrome > .scroll-element.scroll-x { 804 | bottom: 0; 805 | height: 16px; 806 | left: 0; 807 | min-width: 100%; 808 | width: 100%; 809 | } 810 | 811 | .scrollbar-chrome > .scroll-element.scroll-y { 812 | height: 100%; 813 | min-height: 100%; 814 | right: 0; 815 | top: 0; 816 | width: 16px; 817 | } 818 | 819 | .scrollbar-chrome > .scroll-element .scroll-bar { 820 | background-color: #d9d9d9; 821 | border: 1px solid #bdbdbd; 822 | cursor: default; 823 | -webkit-border-radius: 2px; 824 | -moz-border-radius: 2px; 825 | border-radius: 2px; 826 | } 827 | 828 | .scrollbar-chrome > .scroll-element .scroll-bar:hover { 829 | background-color: #c2c2c2; 830 | border-color: #a9a9a9; 831 | } 832 | 833 | .scrollbar-chrome > .scroll-element.scroll-draggable .scroll-bar { 834 | background-color: #919191; 835 | border-color: #7e7e7e; 836 | } 837 | 838 | /* scrollbar height/width & offset from container borders */ 839 | .scrollbar-chrome > .scroll-content.scroll-scrolly_visible { 840 | left: -16px; 841 | margin-left: 16px; 842 | } 843 | 844 | .scrollbar-chrome > .scroll-content.scroll-scrollx_visible { 845 | top: -16px; 846 | margin-top: 16px; 847 | } 848 | 849 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-bar { 850 | height: 8px; 851 | min-width: 10px; 852 | top: 3px; 853 | } 854 | 855 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-bar { 856 | left: 3px; 857 | min-height: 10px; 858 | width: 8px; 859 | } 860 | 861 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-element_outer { 862 | border-left: 1px solid #dbdbdb; 863 | } 864 | 865 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-element_track { 866 | height: 14px; 867 | left: -3px; 868 | } 869 | 870 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-element_size { 871 | height: 14px; 872 | left: -4px; 873 | } 874 | 875 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-element_outer { 876 | border-top: 1px solid #dbdbdb; 877 | } 878 | 879 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-element_track { 880 | top: -3px; 881 | width: 14px; 882 | } 883 | 884 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-element_size { 885 | top: -4px; 886 | width: 14px; 887 | } 888 | 889 | /* update scrollbar offset if both scrolls are visible */ 890 | .scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { 891 | left: -19px; 892 | } 893 | 894 | .scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { 895 | top: -19px; 896 | } 897 | 898 | .scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { 899 | left: -19px; 900 | } 901 | 902 | .scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { 903 | top: -19px; 904 | } 905 | -------------------------------------------------------------------------------- /jquery.scrollbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery CSS Customizable Scrollbar 3 | * 4 | * Copyright 2015, Yuriy Khabarov 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * 7 | * If you found bug, please contact me via email <13real008@gmail.com> 8 | * 9 | * @author Yuriy Khabarov aka Gromo 10 | * @version 0.2.11 11 | * @url https://github.com/gromo/jquery.scrollbar/ 12 | * 13 | */ 14 | ; 15 | (function (root, factory) { 16 | 'use strict'; 17 | if (typeof define === 'function' && define.amd) { 18 | define(['jquery'], factory); 19 | } else if (typeof exports !== 'undefined') { 20 | module.exports = factory(require('jquery')); 21 | } else { 22 | factory(jQuery); 23 | } 24 | }(this, function ($) { 25 | 'use strict'; 26 | 27 | // init flags & variables 28 | var debug = false; 29 | 30 | var browser = { 31 | data: { 32 | index: 0, 33 | name: 'scrollbar' 34 | }, 35 | firefox: /firefox/i.test(navigator.userAgent), 36 | macosx: /mac/i.test(navigator.platform), 37 | msedge: /edge\/\d+/i.test(navigator.userAgent), 38 | msie: /(msie|trident)/i.test(navigator.userAgent), 39 | mobile: /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent), 40 | overlay: null, 41 | scroll: null, 42 | scrolls: [], 43 | webkit: /webkit/i.test(navigator.userAgent) && !/edge\/\d+/i.test(navigator.userAgent) 44 | }; 45 | 46 | browser.scrolls.add = function (instance) { 47 | this.remove(instance).push(instance); 48 | }; 49 | browser.scrolls.remove = function (instance) { 50 | while ($.inArray(instance, this) >= 0) { 51 | this.splice($.inArray(instance, this), 1); 52 | } 53 | return this; 54 | }; 55 | 56 | var defaults = { 57 | autoScrollSize: true, // automatically calculate scrollsize 58 | autoUpdate: true, // update scrollbar if content/container size changed 59 | debug: false, // debug mode 60 | disableBodyScroll: false, // disable body scroll if mouse over container 61 | duration: 200, // scroll animate duration in ms 62 | ignoreMobile: false, // ignore mobile devices 63 | ignoreOverlay: false, // ignore browsers with overlay scrollbars (mobile, MacOS) 64 | isRtl: false, // is RTL 65 | scrollStep: 30, // scroll step for scrollbar arrows 66 | showArrows: false, // add class to show arrows 67 | stepScrolling: true, // when scrolling to scrollbar mousedown position 68 | 69 | scrollx: null, // horizontal scroll element 70 | scrolly: null, // vertical scroll element 71 | 72 | onDestroy: null, // callback function on destroy, 73 | onFallback: null, // callback function if scrollbar is not initialized 74 | onInit: null, // callback function on first initialization 75 | onScroll: null, // callback function on content scrolling 76 | onUpdate: null // callback function on init/resize (before scrollbar size calculation) 77 | }; 78 | 79 | 80 | var BaseScrollbar = function (container) { 81 | 82 | if (!browser.scroll) { 83 | browser.overlay = isScrollOverlaysContent(); 84 | browser.scroll = getBrowserScrollSize(); 85 | updateScrollbars(); 86 | 87 | $(window).resize(function () { 88 | var forceUpdate = false; 89 | if (browser.scroll && (browser.scroll.height || browser.scroll.width)) { 90 | var scroll = getBrowserScrollSize(); 91 | if (scroll.height !== browser.scroll.height || scroll.width !== browser.scroll.width) { 92 | browser.scroll = scroll; 93 | forceUpdate = true; // handle page zoom 94 | } 95 | } 96 | updateScrollbars(forceUpdate); 97 | }); 98 | } 99 | 100 | this.container = container; 101 | this.namespace = '.scrollbar_' + browser.data.index++; 102 | this.options = $.extend({}, defaults, window.jQueryScrollbarOptions || {}); 103 | this.scrollTo = null; 104 | this.scrollx = {}; 105 | this.scrolly = {}; 106 | 107 | container.data(browser.data.name, this); 108 | browser.scrolls.add(this); 109 | }; 110 | 111 | BaseScrollbar.prototype = { 112 | destroy: function () { 113 | 114 | if (!this.wrapper) { 115 | return; 116 | } 117 | 118 | this.container.removeData(browser.data.name); 119 | browser.scrolls.remove(this); 120 | 121 | // init variables 122 | var scrollLeft = this.container.scrollLeft(); 123 | var scrollTop = this.container.scrollTop(); 124 | 125 | this.container.insertBefore(this.wrapper).css({ 126 | "height": "", 127 | "margin": "", 128 | "max-height": "" 129 | }) 130 | .removeClass('scroll-content scroll-scrollx_visible scroll-scrolly_visible') 131 | .off(this.namespace) 132 | .scrollLeft(scrollLeft) 133 | .scrollTop(scrollTop); 134 | 135 | this.scrollx.scroll.removeClass('scroll-scrollx_visible').find('div').addBack().off(this.namespace); 136 | this.scrolly.scroll.removeClass('scroll-scrolly_visible').find('div').addBack().off(this.namespace); 137 | 138 | this.wrapper.remove(); 139 | 140 | $(document).add('body').off(this.namespace); 141 | 142 | if ($.isFunction(this.options.onDestroy)) { 143 | this.options.onDestroy.apply(this, [this.container]); 144 | } 145 | }, 146 | init: function (options) { 147 | 148 | // init variables 149 | var S = this, 150 | c = this.container, 151 | cw = this.containerWrapper || c, 152 | namespace = this.namespace, 153 | o = $.extend(this.options, options || {}), 154 | s = {x: this.scrollx, y: this.scrolly}, 155 | w = this.wrapper, 156 | cssOptions = {}; 157 | 158 | var initScroll = { 159 | scrollLeft: c.scrollLeft(), 160 | scrollTop: c.scrollTop() 161 | }; 162 | 163 | // do not init if in ignorable browser 164 | if ((browser.mobile && o.ignoreMobile) 165 | || (browser.overlay && o.ignoreOverlay) 166 | || (browser.macosx && !browser.webkit) // still required to ignore nonWebKit browsers on Mac 167 | ) { 168 | if ($.isFunction(o.onFallback)) { 169 | o.onFallback.apply(this, [c]); 170 | } 171 | return false; 172 | } 173 | 174 | // init scroll container 175 | if (!w) { 176 | this.wrapper = w = $('
').addClass('scroll-wrapper').addClass(c.attr('class')) 177 | .css('position', c.css('position') === 'absolute' ? 'absolute' : 'relative') 178 | .insertBefore(c).append(c); 179 | 180 | if (o.isRtl) { 181 | w.addClass('scroll--rtl'); 182 | } 183 | 184 | if (c.is('textarea')) { 185 | this.containerWrapper = cw = $('
').insertBefore(c).append(c); 186 | w.addClass('scroll-textarea'); 187 | } 188 | 189 | cssOptions = { 190 | "height": "auto", 191 | "margin-bottom": browser.scroll.height * -1 + 'px', 192 | "max-height": "" 193 | }; 194 | cssOptions[o.isRtl ? 'margin-left' : 'margin-right'] = browser.scroll.width * -1 + 'px'; 195 | 196 | cw.addClass('scroll-content').css(cssOptions); 197 | 198 | c.on('scroll' + namespace, function (event) { 199 | var scrollLeft = c.scrollLeft(); 200 | var scrollTop = c.scrollTop(); 201 | if (o.isRtl) { 202 | // webkit 0:100 203 | // ie/edge 100:0 204 | // firefox -100:0 205 | switch (true) { 206 | case browser.firefox: 207 | scrollLeft = Math.abs(scrollLeft); 208 | case browser.msedge || browser.msie: 209 | scrollLeft = c[0].scrollWidth - c[0].clientWidth - scrollLeft; 210 | break; 211 | } 212 | } 213 | if ($.isFunction(o.onScroll)) { 214 | o.onScroll.call(S, { 215 | maxScroll: s.y.maxScrollOffset, 216 | scroll: scrollTop, 217 | size: s.y.size, 218 | visible: s.y.visible 219 | }, { 220 | maxScroll: s.x.maxScrollOffset, 221 | scroll: scrollLeft, 222 | size: s.x.size, 223 | visible: s.x.visible 224 | }); 225 | } 226 | s.x.isVisible && s.x.scroll.bar.css('left', scrollLeft * s.x.kx + 'px'); 227 | s.y.isVisible && s.y.scroll.bar.css('top', scrollTop * s.y.kx + 'px'); 228 | }); 229 | 230 | /* prevent native scrollbars to be visible on #anchor click */ 231 | w.on('scroll' + namespace, function () { 232 | w.scrollTop(0).scrollLeft(0); 233 | }); 234 | 235 | if (o.disableBodyScroll) { 236 | var handleMouseScroll = function (event) { 237 | isVerticalScroll(event) ? 238 | s.y.isVisible && s.y.mousewheel(event) : 239 | s.x.isVisible && s.x.mousewheel(event); 240 | }; 241 | w.on('MozMousePixelScroll' + namespace, handleMouseScroll); 242 | w.on('mousewheel' + namespace, handleMouseScroll); 243 | 244 | if (browser.mobile) { 245 | w.on('touchstart' + namespace, function (event) { 246 | var touch = event.originalEvent.touches && event.originalEvent.touches[0] || event; 247 | var originalTouch = { 248 | pageX: touch.pageX, 249 | pageY: touch.pageY 250 | }; 251 | var originalScroll = { 252 | left: c.scrollLeft(), 253 | top: c.scrollTop() 254 | }; 255 | $(document).on('touchmove' + namespace, function (event) { 256 | var touch = event.originalEvent.targetTouches && event.originalEvent.targetTouches[0] || event; 257 | c.scrollLeft(originalScroll.left + originalTouch.pageX - touch.pageX); 258 | c.scrollTop(originalScroll.top + originalTouch.pageY - touch.pageY); 259 | event.preventDefault(); 260 | }); 261 | $(document).on('touchend' + namespace, function () { 262 | $(document).off(namespace); 263 | }); 264 | }); 265 | } 266 | } 267 | if ($.isFunction(o.onInit)) { 268 | o.onInit.apply(this, [c]); 269 | } 270 | } else { 271 | cssOptions = { 272 | "height": "auto", 273 | "margin-bottom": browser.scroll.height * -1 + 'px', 274 | "max-height": "" 275 | }; 276 | cssOptions[o.isRtl ? 'margin-left' : 'margin-right'] = browser.scroll.width * -1 + 'px'; 277 | cw.css(cssOptions); 278 | } 279 | 280 | // init scrollbars & recalculate sizes 281 | $.each(s, function (d, scrollx) { 282 | 283 | var scrollCallback = null; 284 | var scrollForward = 1; 285 | var scrollOffset = (d === 'x') ? 'scrollLeft' : 'scrollTop'; 286 | var scrollStep = o.scrollStep; 287 | var scrollTo = function () { 288 | var currentOffset = c[scrollOffset](); 289 | c[scrollOffset](currentOffset + scrollStep); 290 | if (scrollForward == 1 && (currentOffset + scrollStep) >= scrollToValue) 291 | currentOffset = c[scrollOffset](); 292 | if (scrollForward == -1 && (currentOffset + scrollStep) <= scrollToValue) 293 | currentOffset = c[scrollOffset](); 294 | if (c[scrollOffset]() == currentOffset && scrollCallback) { 295 | scrollCallback(); 296 | } 297 | } 298 | var scrollToValue = 0; 299 | 300 | if (!scrollx.scroll) { 301 | 302 | scrollx.scroll = S._getScroll(o['scroll' + d]).addClass('scroll-' + d); 303 | 304 | if (o.showArrows) { 305 | scrollx.scroll.addClass('scroll-element_arrows_visible'); 306 | } 307 | 308 | scrollx.mousewheel = function (event) { 309 | 310 | if (!scrollx.isVisible || (d === 'x' && isVerticalScroll(event))) { 311 | return true; 312 | } 313 | if (d === 'y' && !isVerticalScroll(event)) { 314 | s.x.mousewheel(event); 315 | return true; 316 | } 317 | 318 | var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail; 319 | var maxScrollValue = scrollx.size - scrollx.visible - scrollx.offset; 320 | 321 | // fix new mozilla 322 | if (!delta) { 323 | if (d === 'x' && !!event.originalEvent.deltaX) { 324 | delta = event.originalEvent.deltaX * 40; 325 | } else if (d === 'y' && !!event.originalEvent.deltaY) { 326 | delta = event.originalEvent.deltaY * 40; 327 | } 328 | } 329 | 330 | if ((delta > 0 && scrollToValue < maxScrollValue) || (delta < 0 && scrollToValue > 0)) { 331 | scrollToValue = scrollToValue + delta; 332 | if (scrollToValue < 0) 333 | scrollToValue = 0; 334 | if (scrollToValue > maxScrollValue) 335 | scrollToValue = maxScrollValue; 336 | 337 | S.scrollTo = S.scrollTo || {}; 338 | S.scrollTo[scrollOffset] = scrollToValue; 339 | setTimeout(function () { 340 | if (S.scrollTo) { 341 | c.stop().animate(S.scrollTo, 240, 'linear', function () { 342 | scrollToValue = c[scrollOffset](); 343 | }); 344 | S.scrollTo = null; 345 | } 346 | }, 1); 347 | } 348 | 349 | event.preventDefault(); 350 | return false; 351 | }; 352 | 353 | scrollx.scroll 354 | .on('MozMousePixelScroll' + namespace, scrollx.mousewheel) 355 | .on('mousewheel' + namespace, scrollx.mousewheel) 356 | .on('mouseenter' + namespace, function () { 357 | scrollToValue = c[scrollOffset](); 358 | }); 359 | 360 | // handle arrows & scroll inner mousedown event 361 | scrollx.scroll.find('.scroll-arrow, .scroll-element_track') 362 | .on('mousedown' + namespace, function (event) { 363 | 364 | if (event.which != 1) // lmb 365 | return true; 366 | 367 | scrollForward = 1; 368 | 369 | var data = { 370 | eventOffset: event[(d === 'x') ? 'pageX' : 'pageY'], 371 | maxScrollValue: scrollx.size - scrollx.visible - scrollx.offset, 372 | scrollbarOffset: scrollx.scroll.bar.offset()[(d === 'x') ? 'left' : 'top'], 373 | scrollbarSize: scrollx.scroll.bar[(d === 'x') ? 'outerWidth' : 'outerHeight']() 374 | }; 375 | var timeout = 0, timer = 0; 376 | 377 | if ($(this).hasClass('scroll-arrow')) { 378 | scrollForward = $(this).hasClass("scroll-arrow_more") ? 1 : -1; 379 | scrollStep = o.scrollStep * scrollForward; 380 | scrollToValue = scrollForward > 0 ? data.maxScrollValue : 0; 381 | if (o.isRtl) { 382 | switch(true){ 383 | case browser.firefox: 384 | scrollToValue = scrollForward > 0 ? 0: data.maxScrollValue * -1; 385 | break; 386 | case browser.msie || browser.msedge: 387 | break; 388 | } 389 | } 390 | } else { 391 | scrollForward = (data.eventOffset > (data.scrollbarOffset + data.scrollbarSize) ? 1 392 | : (data.eventOffset < data.scrollbarOffset ? -1 : 0)); 393 | if(d === 'x' && o.isRtl && (browser.msie || browser.msedge)) 394 | scrollForward = scrollForward * -1; 395 | scrollStep = Math.round(scrollx.visible * 0.75) * scrollForward; 396 | scrollToValue = (data.eventOffset - data.scrollbarOffset - 397 | (o.stepScrolling ? (scrollForward == 1 ? data.scrollbarSize : 0) 398 | : Math.round(data.scrollbarSize / 2))); 399 | scrollToValue = c[scrollOffset]() + (scrollToValue / scrollx.kx); 400 | } 401 | 402 | S.scrollTo = S.scrollTo || {}; 403 | S.scrollTo[scrollOffset] = o.stepScrolling ? c[scrollOffset]() + scrollStep : scrollToValue; 404 | 405 | if (o.stepScrolling) { 406 | scrollCallback = function () { 407 | scrollToValue = c[scrollOffset](); 408 | clearInterval(timer); 409 | clearTimeout(timeout); 410 | timeout = 0; 411 | timer = 0; 412 | }; 413 | timeout = setTimeout(function () { 414 | timer = setInterval(scrollTo, 40); 415 | }, o.duration + 100); 416 | } 417 | 418 | setTimeout(function () { 419 | if (S.scrollTo) { 420 | c.animate(S.scrollTo, o.duration); 421 | S.scrollTo = null; 422 | } 423 | }, 1); 424 | 425 | return S._handleMouseDown(scrollCallback, event); 426 | }); 427 | 428 | // handle scrollbar drag'n'drop 429 | scrollx.scroll.bar.on('mousedown' + namespace, function (event) { 430 | 431 | if (event.which != 1) // lmb 432 | return true; 433 | 434 | var eventPosition = event[(d === 'x') ? 'pageX' : 'pageY']; 435 | var initOffset = c[scrollOffset](); 436 | 437 | scrollx.scroll.addClass('scroll-draggable'); 438 | 439 | $(document).on('mousemove' + namespace, function (event) { 440 | var diff = parseInt((event[(d === 'x') ? 'pageX' : 'pageY'] - eventPosition) / scrollx.kx, 10); 441 | if (d === 'x' && o.isRtl && (browser.msie || browser.msedge)) 442 | diff = diff * -1; 443 | c[scrollOffset](initOffset + diff); 444 | }); 445 | 446 | return S._handleMouseDown(function () { 447 | scrollx.scroll.removeClass('scroll-draggable'); 448 | scrollToValue = c[scrollOffset](); 449 | }, event); 450 | }); 451 | } 452 | }); 453 | 454 | // remove classes & reset applied styles 455 | $.each(s, function (d, scrollx) { 456 | var scrollClass = 'scroll-scroll' + d + '_visible'; 457 | var scrolly = (d == "x") ? s.y : s.x; 458 | 459 | scrollx.scroll.removeClass(scrollClass); 460 | scrolly.scroll.removeClass(scrollClass); 461 | cw.removeClass(scrollClass); 462 | }); 463 | 464 | // calculate init sizes 465 | $.each(s, function (d, scrollx) { 466 | $.extend(scrollx, (d == "x") ? { 467 | offset: parseInt(c.css('left'), 10) || 0, 468 | size: c.prop('scrollWidth'), 469 | visible: w.width() 470 | } : { 471 | offset: parseInt(c.css('top'), 10) || 0, 472 | size: c.prop('scrollHeight'), 473 | visible: w.height() 474 | }); 475 | }); 476 | 477 | // update scrollbar visibility/dimensions 478 | this._updateScroll('x', this.scrollx); 479 | this._updateScroll('y', this.scrolly); 480 | 481 | if ($.isFunction(o.onUpdate)) { 482 | o.onUpdate.apply(this, [c]); 483 | } 484 | 485 | // calculate scroll size 486 | $.each(s, function (d, scrollx) { 487 | 488 | var cssOffset = (d === 'x') ? 'left' : 'top'; 489 | var cssFullSize = (d === 'x') ? 'outerWidth' : 'outerHeight'; 490 | var cssSize = (d === 'x') ? 'width' : 'height'; 491 | var offset = parseInt(c.css(cssOffset), 10) || 0; 492 | 493 | var AreaSize = scrollx.size; 494 | var AreaVisible = scrollx.visible + offset; 495 | 496 | var scrollSize = scrollx.scroll.size[cssFullSize]() + (parseInt(scrollx.scroll.size.css(cssOffset), 10) || 0); 497 | 498 | if (o.autoScrollSize) { 499 | scrollx.scrollbarSize = parseInt(scrollSize * AreaVisible / AreaSize, 10); 500 | scrollx.scroll.bar.css(cssSize, scrollx.scrollbarSize + 'px'); 501 | } 502 | 503 | scrollx.scrollbarSize = scrollx.scroll.bar[cssFullSize](); 504 | scrollx.kx = ((scrollSize - scrollx.scrollbarSize) / (AreaSize - AreaVisible)) || 1; 505 | scrollx.maxScrollOffset = AreaSize - AreaVisible; 506 | }); 507 | 508 | c.scrollLeft(initScroll.scrollLeft).scrollTop(initScroll.scrollTop).trigger('scroll'); 509 | }, 510 | /** 511 | * Get scrollx/scrolly object 512 | * 513 | * @param {Mixed} scroll 514 | * @returns {jQuery} scroll object 515 | */ 516 | _getScroll: function (scroll) { 517 | var types = { 518 | advanced: [ 519 | '
', 520 | '
', 521 | '
', 522 | '
', 523 | '
', 524 | '
', // required! used for scrollbar size calculation ! 525 | '
', 526 | '
', // used for handling scrollbar click 527 | '
', 528 | '
', 529 | '
', 530 | '
', // required 531 | '
', 532 | '
', 533 | '
', 534 | '
', 535 | '
', 536 | '
', 537 | '
', 538 | '
' 539 | ].join(''), 540 | simple: [ 541 | '
', 542 | '
', 543 | '
', // required! used for scrollbar size calculation ! 544 | '
', // used for handling scrollbar click 545 | '
', // required 546 | '
', 547 | '
' 548 | ].join('') 549 | }; 550 | if (types[scroll]) { 551 | scroll = types[scroll]; 552 | } 553 | if (!scroll) { 554 | scroll = types['simple']; 555 | } 556 | if (typeof (scroll) == 'string') { 557 | scroll = $(scroll).appendTo(this.wrapper); 558 | } else { 559 | scroll = $(scroll); 560 | } 561 | $.extend(scroll, { 562 | bar: scroll.find('.scroll-bar'), 563 | size: scroll.find('.scroll-element_size'), 564 | track: scroll.find('.scroll-element_track') 565 | }); 566 | return scroll; 567 | }, 568 | _handleMouseDown: function (callback, event) { 569 | 570 | var namespace = this.namespace; 571 | 572 | $(document).on('blur' + namespace, function () { 573 | $(document).add('body').off(namespace); 574 | callback && callback(); 575 | }); 576 | $(document).on('dragstart' + namespace, function (event) { 577 | event.preventDefault(); 578 | return false; 579 | }); 580 | $(document).on('mouseup' + namespace, function () { 581 | $(document).add('body').off(namespace); 582 | callback && callback(); 583 | }); 584 | $('body').on('selectstart' + namespace, function (event) { 585 | event.preventDefault(); 586 | return false; 587 | }); 588 | 589 | event && event.preventDefault(); 590 | return false; 591 | }, 592 | _updateScroll: function (d, scrollx) { 593 | 594 | var container = this.container, 595 | containerWrapper = this.containerWrapper || container, 596 | scrollClass = 'scroll-scroll' + d + '_visible', 597 | scrolly = (d === 'x') ? this.scrolly : this.scrollx, 598 | offset = parseInt(this.container.css((d === 'x') ? 'left' : 'top'), 10) || 0, 599 | wrapper = this.wrapper; 600 | 601 | var AreaSize = scrollx.size; 602 | var AreaVisible = scrollx.visible + offset; 603 | 604 | scrollx.isVisible = (AreaSize - AreaVisible) > 1; // bug in IE9/11 with 1px diff 605 | if (scrollx.isVisible) { 606 | scrollx.scroll.addClass(scrollClass); 607 | scrolly.scroll.addClass(scrollClass); 608 | containerWrapper.addClass(scrollClass); 609 | } else { 610 | scrollx.scroll.removeClass(scrollClass); 611 | scrolly.scroll.removeClass(scrollClass); 612 | containerWrapper.removeClass(scrollClass); 613 | } 614 | 615 | if (d === 'y') { 616 | if (container.is('textarea') || AreaSize < AreaVisible) { 617 | containerWrapper.css({ 618 | "height": (AreaVisible + browser.scroll.height) + 'px', 619 | "max-height": "none" 620 | }); 621 | } else { 622 | containerWrapper.css({ 623 | //"height": "auto", // do not reset height value: issue with height:100%! 624 | "max-height": (AreaVisible + browser.scroll.height) + 'px' 625 | }); 626 | } 627 | } 628 | 629 | if (scrollx.size != container.prop('scrollWidth') 630 | || scrolly.size != container.prop('scrollHeight') 631 | || scrollx.visible != wrapper.width() 632 | || scrolly.visible != wrapper.height() 633 | || scrollx.offset != (parseInt(container.css('left'), 10) || 0) 634 | || scrolly.offset != (parseInt(container.css('top'), 10) || 0) 635 | ) { 636 | $.extend(this.scrollx, { 637 | offset: parseInt(container.css('left'), 10) || 0, 638 | size: container.prop('scrollWidth'), 639 | visible: wrapper.width() 640 | }); 641 | $.extend(this.scrolly, { 642 | offset: parseInt(container.css('top'), 10) || 0, 643 | size: this.container.prop('scrollHeight'), 644 | visible: wrapper.height() 645 | }); 646 | this._updateScroll(d === 'x' ? 'y' : 'x', scrolly); 647 | } 648 | } 649 | }; 650 | 651 | var CustomScrollbar = BaseScrollbar; 652 | 653 | /* 654 | * Extend jQuery as plugin 655 | * 656 | * @param {Mixed} command to execute 657 | * @param {Mixed} arguments as Array 658 | * @return {jQuery} 659 | */ 660 | $.fn.scrollbar = function (command, args) { 661 | if (typeof command !== 'string') { 662 | args = command; 663 | command = 'init'; 664 | } 665 | if (typeof args === 'undefined') { 666 | args = []; 667 | } 668 | if (!$.isArray(args)) { 669 | args = [args]; 670 | } 671 | this.not('body, .scroll-wrapper').each(function () { 672 | var element = $(this), 673 | instance = element.data(browser.data.name); 674 | if (instance || command === 'init') { 675 | if (!instance) { 676 | instance = new CustomScrollbar(element); 677 | } 678 | if (instance[command]) { 679 | instance[command].apply(instance, args); 680 | } 681 | } 682 | }); 683 | return this; 684 | }; 685 | 686 | /** 687 | * Connect default options to global object 688 | */ 689 | $.fn.scrollbar.options = defaults; 690 | 691 | 692 | /** 693 | * Check if scroll content/container size is changed 694 | */ 695 | 696 | var updateScrollbars = (function () { 697 | var timer = 0, 698 | timerCounter = 0; 699 | 700 | return function (force) { 701 | var i, container, options, scroll, wrapper, scrollx, scrolly; 702 | for (i = 0; i < browser.scrolls.length; i++) { 703 | scroll = browser.scrolls[i]; 704 | container = scroll.container; 705 | options = scroll.options; 706 | wrapper = scroll.wrapper; 707 | scrollx = scroll.scrollx; 708 | scrolly = scroll.scrolly; 709 | if (force || (options.autoUpdate && wrapper && wrapper.is(':visible') && 710 | (container.prop('scrollWidth') != scrollx.size || container.prop('scrollHeight') != scrolly.size || wrapper.width() != scrollx.visible || wrapper.height() != scrolly.visible))) { 711 | scroll.init(); 712 | 713 | if (options.debug) { 714 | window.console && console.log({ 715 | scrollHeight: container.prop('scrollHeight') + ':' + scroll.scrolly.size, 716 | scrollWidth: container.prop('scrollWidth') + ':' + scroll.scrollx.size, 717 | visibleHeight: wrapper.height() + ':' + scroll.scrolly.visible, 718 | visibleWidth: wrapper.width() + ':' + scroll.scrollx.visible 719 | }, true); 720 | timerCounter++; 721 | } 722 | } 723 | } 724 | if (debug && timerCounter > 10) { 725 | window.console && console.log('Scroll updates exceed 10'); 726 | updateScrollbars = function () {}; 727 | } else { 728 | clearTimeout(timer); 729 | timer = setTimeout(updateScrollbars, 300); 730 | } 731 | }; 732 | })(); 733 | 734 | /* ADDITIONAL FUNCTIONS */ 735 | /** 736 | * Get native browser scrollbar size (height/width) 737 | * 738 | * @param {Boolean} actual size or CSS size, default - CSS size 739 | * @returns {Object} with height, width 740 | */ 741 | function getBrowserScrollSize(actualSize) { 742 | 743 | if (browser.webkit && !actualSize) { 744 | return { 745 | height: 0, 746 | width: 0 747 | }; 748 | } 749 | 750 | if (!browser.data.outer) { 751 | var css = { 752 | "border": "none", 753 | "box-sizing": "content-box", 754 | "height": "200px", 755 | "margin": "0", 756 | "padding": "0", 757 | "width": "200px" 758 | }; 759 | browser.data.inner = $("
").css($.extend({}, css)); 760 | browser.data.outer = $("
").css($.extend({ 761 | "left": "-1000px", 762 | "overflow": "scroll", 763 | "position": "absolute", 764 | "top": "-1000px" 765 | }, css)).append(browser.data.inner).appendTo("body"); 766 | } 767 | 768 | browser.data.outer.scrollLeft(1000).scrollTop(1000); 769 | 770 | return { 771 | height: Math.ceil((browser.data.outer.offset().top - browser.data.inner.offset().top) || 0), 772 | width: Math.ceil((browser.data.outer.offset().left - browser.data.inner.offset().left) || 0) 773 | }; 774 | } 775 | 776 | /** 777 | * Check if native browser scrollbars overlay content 778 | * 779 | * @returns {Boolean} 780 | */ 781 | function isScrollOverlaysContent() { 782 | var scrollSize = getBrowserScrollSize(true); 783 | return !(scrollSize.height || scrollSize.width); 784 | } 785 | 786 | function isVerticalScroll(event) { 787 | var e = event.originalEvent; 788 | if (e.axis && e.axis === e.HORIZONTAL_AXIS) 789 | return false; 790 | if (e.wheelDeltaX) 791 | return false; 792 | return true; 793 | } 794 | 795 | 796 | /** 797 | * Extend AngularJS as UI directive 798 | * and expose a provider for override default config 799 | * 800 | */ 801 | if (window.angular) { 802 | (function (angular) { 803 | angular.module('jQueryScrollbar', []) 804 | .provider('jQueryScrollbar', function () { 805 | var defaultOptions = defaults; 806 | return { 807 | setOptions: function (options) { 808 | angular.extend(defaultOptions, options); 809 | }, 810 | $get: function () { 811 | return { 812 | options: angular.copy(defaultOptions) 813 | }; 814 | } 815 | }; 816 | }) 817 | .directive('jqueryScrollbar', ['jQueryScrollbar', '$parse', function (jQueryScrollbar, $parse) { 818 | return { 819 | restrict: "AC", 820 | link: function (scope, element, attrs) { 821 | var model = $parse(attrs.jqueryScrollbar), 822 | options = model(scope); 823 | element.scrollbar(options || jQueryScrollbar.options) 824 | .on('$destroy', function () { 825 | element.scrollbar('destroy'); 826 | }); 827 | } 828 | }; 829 | }]); 830 | })(window.angular); 831 | } 832 | })); 833 | -------------------------------------------------------------------------------- /jquery.scrollbar.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery CSS Customizable Scrollbar 3 | * 4 | * Copyright 2015, Yuriy Khabarov 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * 7 | * If you found bug, please contact me via email <13real008@gmail.com> 8 | * 9 | * Compressed by http://jscompress.com/ 10 | * 11 | * @author Yuriy Khabarov aka Gromo 12 | * @version 0.2.11 13 | * @url https://github.com/gromo/jquery.scrollbar/ 14 | * 15 | */ 16 | !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b("undefined"!=typeof exports?require("jquery"):a.jQuery)}(this,function(a){"use strict";function h(b){if(c.webkit&&!b)return{height:0,width:0};if(!c.data.outer){var d={border:"none","box-sizing":"content-box",height:"200px",margin:"0",padding:"0",width:"200px"};c.data.inner=a("
").css(a.extend({},d)),c.data.outer=a("
").css(a.extend({left:"-1000px",overflow:"scroll",position:"absolute",top:"-1000px"},d)).append(c.data.inner).appendTo("body")}return c.data.outer.scrollLeft(1e3).scrollTop(1e3),{height:Math.ceil(c.data.outer.offset().top-c.data.inner.offset().top||0),width:Math.ceil(c.data.outer.offset().left-c.data.inner.offset().left||0)}}function i(){var a=h(!0);return!(a.height||a.width)}function j(a){var b=a.originalEvent;return(!b.axis||b.axis!==b.HORIZONTAL_AXIS)&&!b.wheelDeltaX}var b=!1,c={data:{index:0,name:"scrollbar"},firefox:/firefox/i.test(navigator.userAgent),macosx:/mac/i.test(navigator.platform),msedge:/edge\/\d+/i.test(navigator.userAgent),msie:/(msie|trident)/i.test(navigator.userAgent),mobile:/android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent),overlay:null,scroll:null,scrolls:[],webkit:/webkit/i.test(navigator.userAgent)&&!/edge\/\d+/i.test(navigator.userAgent)};c.scrolls.add=function(a){this.remove(a).push(a)},c.scrolls.remove=function(b){for(;a.inArray(b,this)>=0;)this.splice(a.inArray(b,this),1);return this};var d={autoScrollSize:!0,autoUpdate:!0,debug:!1,disableBodyScroll:!1,duration:200,ignoreMobile:!1,ignoreOverlay:!1,isRtl:!1,scrollStep:30,showArrows:!1,stepScrolling:!0,scrollx:null,scrolly:null,onDestroy:null,onFallback:null,onInit:null,onScroll:null,onUpdate:null},e=function(b){c.scroll||(c.overlay=i(),c.scroll=h(),g(),a(window).resize(function(){var a=!1;if(c.scroll&&(c.scroll.height||c.scroll.width)){var b=h();b.height===c.scroll.height&&b.width===c.scroll.width||(c.scroll=b,a=!0)}g(a)})),this.container=b,this.namespace=".scrollbar_"+c.data.index++,this.options=a.extend({},d,window.jQueryScrollbarOptions||{}),this.scrollTo=null,this.scrollx={},this.scrolly={},b.data(c.data.name,this),c.scrolls.add(this)};e.prototype={destroy:function(){if(this.wrapper){this.container.removeData(c.data.name),c.scrolls.remove(this);var b=this.container.scrollLeft(),d=this.container.scrollTop();this.container.insertBefore(this.wrapper).css({height:"",margin:"","max-height":""}).removeClass("scroll-content scroll-scrollx_visible scroll-scrolly_visible").off(this.namespace).scrollLeft(b).scrollTop(d),this.scrollx.scroll.removeClass("scroll-scrollx_visible").find("div").addBack().off(this.namespace),this.scrolly.scroll.removeClass("scroll-scrolly_visible").find("div").addBack().off(this.namespace),this.wrapper.remove(),a(document).add("body").off(this.namespace),a.isFunction(this.options.onDestroy)&&this.options.onDestroy.apply(this,[this.container])}},init:function(b){var d=this,e=this.container,f=this.containerWrapper||e,g=this.namespace,h=a.extend(this.options,b||{}),i={x:this.scrollx,y:this.scrolly},k=this.wrapper,l={},m={scrollLeft:e.scrollLeft(),scrollTop:e.scrollTop()};if(c.mobile&&h.ignoreMobile||c.overlay&&h.ignoreOverlay||c.macosx&&!c.webkit)return a.isFunction(h.onFallback)&&h.onFallback.apply(this,[e]),!1;if(k)l={height:"auto","margin-bottom":c.scroll.height*-1+"px","max-height":""},l[h.isRtl?"margin-left":"margin-right"]=c.scroll.width*-1+"px",f.css(l);else{if(this.wrapper=k=a("
").addClass("scroll-wrapper").addClass(e.attr("class")).css("position","absolute"===e.css("position")?"absolute":"relative").insertBefore(e).append(e),h.isRtl&&k.addClass("scroll--rtl"),e.is("textarea")&&(this.containerWrapper=f=a("
").insertBefore(e).append(e),k.addClass("scroll-textarea")),l={height:"auto","margin-bottom":c.scroll.height*-1+"px","max-height":""},l[h.isRtl?"margin-left":"margin-right"]=c.scroll.width*-1+"px",f.addClass("scroll-content").css(l),e.on("scroll"+g,function(b){var f=e.scrollLeft(),g=e.scrollTop();if(h.isRtl)switch(!0){case c.firefox:f=Math.abs(f);case c.msedge||c.msie:f=e[0].scrollWidth-e[0].clientWidth-f}a.isFunction(h.onScroll)&&h.onScroll.call(d,{maxScroll:i.y.maxScrollOffset,scroll:g,size:i.y.size,visible:i.y.visible},{maxScroll:i.x.maxScrollOffset,scroll:f,size:i.x.size,visible:i.x.visible}),i.x.isVisible&&i.x.scroll.bar.css("left",f*i.x.kx+"px"),i.y.isVisible&&i.y.scroll.bar.css("top",g*i.y.kx+"px")}),k.on("scroll"+g,function(){k.scrollTop(0).scrollLeft(0)}),h.disableBodyScroll){var n=function(a){j(a)?i.y.isVisible&&i.y.mousewheel(a):i.x.isVisible&&i.x.mousewheel(a)};k.on("MozMousePixelScroll"+g,n),k.on("mousewheel"+g,n),c.mobile&&k.on("touchstart"+g,function(b){var c=b.originalEvent.touches&&b.originalEvent.touches[0]||b,d={pageX:c.pageX,pageY:c.pageY},f={left:e.scrollLeft(),top:e.scrollTop()};a(document).on("touchmove"+g,function(a){var b=a.originalEvent.targetTouches&&a.originalEvent.targetTouches[0]||a;e.scrollLeft(f.left+d.pageX-b.pageX),e.scrollTop(f.top+d.pageY-b.pageY),a.preventDefault()}),a(document).on("touchend"+g,function(){a(document).off(g)})})}a.isFunction(h.onInit)&&h.onInit.apply(this,[e])}a.each(i,function(b,f){var k=null,l=1,m="x"===b?"scrollLeft":"scrollTop",n=h.scrollStep,o=function(){var a=e[m]();e[m](a+n),1==l&&a+n>=p&&(a=e[m]()),l==-1&&a+n<=p&&(a=e[m]()),e[m]()==a&&k&&k()},p=0;f.scroll||(f.scroll=d._getScroll(h["scroll"+b]).addClass("scroll-"+b),h.showArrows&&f.scroll.addClass("scroll-element_arrows_visible"),f.mousewheel=function(a){if(!f.isVisible||"x"===b&&j(a))return!0;if("y"===b&&!j(a))return i.x.mousewheel(a),!0;var c=a.originalEvent.wheelDelta*-1||a.originalEvent.detail,g=f.size-f.visible-f.offset;return c||("x"===b&&a.originalEvent.deltaX?c=40*a.originalEvent.deltaX:"y"===b&&a.originalEvent.deltaY&&(c=40*a.originalEvent.deltaY)),(c>0&&p0)&&(p+=c,p<0&&(p=0),p>g&&(p=g),d.scrollTo=d.scrollTo||{},d.scrollTo[m]=p,setTimeout(function(){d.scrollTo&&(e.stop().animate(d.scrollTo,240,"linear",function(){p=e[m]()}),d.scrollTo=null)},1)),a.preventDefault(),!1},f.scroll.on("MozMousePixelScroll"+g,f.mousewheel).on("mousewheel"+g,f.mousewheel).on("mouseenter"+g,function(){p=e[m]()}),f.scroll.find(".scroll-arrow, .scroll-element_track").on("mousedown"+g,function(g){if(1!=g.which)return!0;l=1;var i={eventOffset:g["x"===b?"pageX":"pageY"],maxScrollValue:f.size-f.visible-f.offset,scrollbarOffset:f.scroll.bar.offset()["x"===b?"left":"top"],scrollbarSize:f.scroll.bar["x"===b?"outerWidth":"outerHeight"]()},j=0,q=0;if(a(this).hasClass("scroll-arrow")){if(l=a(this).hasClass("scroll-arrow_more")?1:-1,n=h.scrollStep*l,p=l>0?i.maxScrollValue:0,h.isRtl)switch(!0){case c.firefox:p=l>0?0:i.maxScrollValue*-1;break;case c.msie||c.msedge:}}else l=i.eventOffset>i.scrollbarOffset+i.scrollbarSize?1:i.eventOffset','
','
','
','
','
','
','
','
',"
","
",'
','
','
',"
",'
','
',"
","
","
"].join(""),simple:['
','
','
','
','
',"
","
"].join("")};return c[b]&&(b=c[b]),b||(b=c.simple),b="string"==typeof b?a(b).appendTo(this.wrapper):a(b),a.extend(b,{bar:b.find(".scroll-bar"),size:b.find(".scroll-element_size"),track:b.find(".scroll-element_track")}),b},_handleMouseDown:function(b,c){var d=this.namespace;return a(document).on("blur"+d,function(){a(document).add("body").off(d),b&&b()}),a(document).on("dragstart"+d,function(a){return a.preventDefault(),!1}),a(document).on("mouseup"+d,function(){a(document).add("body").off(d),b&&b()}),a("body").on("selectstart"+d,function(a){return a.preventDefault(),!1}),c&&c.preventDefault(),!1},_updateScroll:function(b,d){var e=this.container,f=this.containerWrapper||e,g="scroll-scroll"+b+"_visible",h="x"===b?this.scrolly:this.scrollx,i=parseInt(this.container.css("x"===b?"left":"top"),10)||0,j=this.wrapper,k=d.size,l=d.visible+i;d.isVisible=k-l>1,d.isVisible?(d.scroll.addClass(g),h.scroll.addClass(g),f.addClass(g)):(d.scroll.removeClass(g),h.scroll.removeClass(g),f.removeClass(g)),"y"===b&&(e.is("textarea")||k10?(window.console&&console.log("Scroll updates exceed 10"),g=function(){}):(clearTimeout(a),a=setTimeout(g,300))}}();window.angular&&!function(a){a.module("jQueryScrollbar",[]).provider("jQueryScrollbar",function(){var b=d;return{setOptions:function(c){a.extend(b,c)},$get:function(){return{options:a.copy(b)}}}}).directive("jqueryScrollbar",["jQueryScrollbar","$parse",function(a,b){return{restrict:"AC",link:function(c,d,e){var f=b(e.jqueryScrollbar),g=f(c);d.scrollbar(g||a.options).on("$destroy",function(){d.scrollbar("destroy")})}}}])}(window.angular)}); -------------------------------------------------------------------------------- /license-gpl.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | -------------------------------------------------------------------------------- /license-mit.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Yuriy Khabarov <13real008@gmail.com> 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /meteor/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Tinytest.add('Scrollbar integration', function (test) { 4 | 5 | var div = document.createElement('div'); 6 | div.className = 'scrollbar-inner'; 7 | div.value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam in."; 8 | var scrollBar = jQuery('.scrollbar-inner').scrollbar(); 9 | console.log(scrollBar); 10 | test.isNotNull(scrollBar, 'instantiation OK'); 11 | }); -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | // package metadata file for Meteor.js 2 | 'use strict'; 3 | 4 | var packageName = 'gromo:jquery.scrollbar'; // https://atmospherejs.com/mediatainment/switchery 5 | var where = 'client'; // where to install: 'client' or 'server'. For both, pass nothing. 6 | 7 | Package.describe({ 8 | name: packageName, 9 | version: '0.2.11', 10 | // Brief, one-line summary of the package. 11 | summary: 'Cross-browser CSS customizable scrollbar with advanced features.', 12 | // URL to the Git repository containing the source code for this package. 13 | git: 'git@github.com:gromo/jquery.scrollbar.git' 14 | }); 15 | 16 | Package.onUse(function (api) { 17 | api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0']); 18 | api.use('jquery', where); 19 | api.addFiles(['jquery.scrollbar.js', 'jquery.scrollbar.css'], where); 20 | }); 21 | 22 | Package.onTest(function (api) { 23 | api.use([packageName, 'sanjo:jasmine'], where); 24 | api.use(['webapp','tinytest'], where); 25 | api.addFiles('meteor/tests.js', where); // testing specific files 26 | }); 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.scrollbar", 3 | "version": "0.2.11", 4 | "description": "Cross-browser CSS customizable scrollbar", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/gromo/jquery.scrollbar.git" 12 | }, 13 | "keywords": [ 14 | "jquery", 15 | "scrollbar", 16 | "angular", 17 | "textarea" 18 | ], 19 | "author": "Yuriy Khabarov", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/gromo/jquery.scrollbar/issues" 23 | }, 24 | "homepage": "https://github.com/gromo/jquery.scrollbar" 25 | } 26 | -------------------------------------------------------------------------------- /sass/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.initConfig({ 3 | pkg: grunt.file.readJSON('package.json'), 4 | compass: { 5 | auto: { 6 | options: { 7 | sassDir: './', 8 | cssDir: '../' 9 | } 10 | } 11 | }, 12 | watch: { 13 | scss: { 14 | files: ['./**/*.scss'], 15 | tasks: ['compass'] 16 | } 17 | } 18 | }); 19 | grunt.loadNpmTasks('grunt-contrib-compass'); 20 | grunt.loadNpmTasks('grunt-contrib-watch'); 21 | grunt.registerTask('default', ['watch']); 22 | }; -------------------------------------------------------------------------------- /sass/config.rb: -------------------------------------------------------------------------------- 1 | require 'compass/import-once/activate' 2 | line_comments = false 3 | -------------------------------------------------------------------------------- /sass/jquery.scrollbar.scss: -------------------------------------------------------------------------------- 1 | /*************** SCROLLBAR BASE CSS ***************/ 2 | 3 | .scroll-wrapper { 4 | overflow: hidden !important; 5 | padding: 0 !important; 6 | position: relative; 7 | 8 | & > .scroll-content { 9 | border: none !important; 10 | box-sizing: content-box !important; 11 | height: auto; 12 | left: 0; 13 | margin: 0; 14 | max-height: none; 15 | max-width: none !important; 16 | overflow: scroll !important; 17 | padding: 0; 18 | position: relative !important; 19 | top: 0; 20 | width: auto !important; 21 | 22 | &::-webkit-scrollbar { 23 | height: 0; 24 | width: 0; 25 | } 26 | } 27 | &.scroll--rtl { 28 | direction: rtl; 29 | } 30 | } 31 | 32 | .scroll-element { 33 | box-sizing: content-box; 34 | display: none; 35 | 36 | div { 37 | box-sizing: content-box; 38 | } 39 | .scroll-bar, 40 | .scroll-arrow { 41 | cursor: default; 42 | } 43 | 44 | &.scroll-x.scroll-scrollx_visible, 45 | &.scroll-y.scroll-scrolly_visible { 46 | display: block; 47 | } 48 | } 49 | 50 | .scroll-textarea { 51 | border: 1px solid #cccccc; 52 | border-top-color: #999999; 53 | 54 | & > .scroll-content { 55 | overflow: hidden !important; 56 | 57 | & > textarea { 58 | border: none !important; 59 | box-sizing: border-box; 60 | height: 100% !important; 61 | margin: 0; 62 | max-height: none !important; 63 | max-width: none !important; 64 | overflow: scroll !important; 65 | outline: none; 66 | padding: 2px; 67 | position: relative !important; 68 | top: 0; 69 | width: 100% !important; 70 | 71 | &::-webkit-scrollbar { 72 | height: 0; 73 | width: 0; 74 | } 75 | } 76 | } 77 | } 78 | 79 | 80 | 81 | 82 | /*************** SIMPLE INNER SCROLLBAR ***************/ 83 | 84 | .scrollbar-inner > .scroll-element, 85 | .scrollbar-inner > .scroll-element div 86 | { 87 | border: none; 88 | margin: 0; 89 | padding: 0; 90 | position: absolute; 91 | z-index: 10; 92 | } 93 | 94 | .scrollbar-inner > .scroll-element div { 95 | display: block; 96 | height: 100%; 97 | left: 0; 98 | top: 0; 99 | width: 100%; 100 | } 101 | 102 | .scrollbar-inner > .scroll-element.scroll-x { 103 | bottom: 2px; 104 | height: 8px; 105 | left: 0; 106 | width: 100%; 107 | } 108 | 109 | .scrollbar-inner > .scroll-element.scroll-y { 110 | height: 100%; 111 | right: 2px; 112 | top: 0; 113 | width: 8px; 114 | } 115 | 116 | .scrollbar-inner > .scroll-element .scroll-element_outer { 117 | overflow: hidden; 118 | } 119 | 120 | .scrollbar-inner > .scroll-element .scroll-element_outer, 121 | .scrollbar-inner > .scroll-element .scroll-element_track, 122 | .scrollbar-inner > .scroll-element .scroll-bar { 123 | -webkit-border-radius: 8px; 124 | -moz-border-radius: 8px; 125 | border-radius: 8px; 126 | } 127 | 128 | .scrollbar-inner > .scroll-element .scroll-element_track, 129 | .scrollbar-inner > .scroll-element .scroll-bar { 130 | -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; 131 | filter: alpha(opacity=40); 132 | opacity: 0.4; 133 | } 134 | 135 | .scrollbar-inner > .scroll-element .scroll-element_track { background-color: #e0e0e0; } 136 | .scrollbar-inner > .scroll-element .scroll-bar { background-color: #c2c2c2; } 137 | .scrollbar-inner > .scroll-element:hover .scroll-bar { background-color: #919191; } 138 | .scrollbar-inner > .scroll-element.scroll-draggable .scroll-bar { background-color: #919191; } 139 | 140 | 141 | /* update scrollbar offset if both scrolls are visible */ 142 | 143 | .scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -12px; } 144 | .scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -12px; } 145 | 146 | 147 | .scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -12px; } 148 | .scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -12px; } 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | /*************** SIMPLE OUTER SCROLLBAR ***************/ 160 | 161 | .scrollbar-outer > .scroll-element, 162 | .scrollbar-outer > .scroll-element div 163 | { 164 | border: none; 165 | margin: 0; 166 | padding: 0; 167 | position: absolute; 168 | z-index: 10; 169 | } 170 | 171 | .scrollbar-outer > .scroll-element { 172 | background-color: #ffffff; 173 | } 174 | 175 | .scrollbar-outer > .scroll-element div { 176 | display: block; 177 | height: 100%; 178 | left: 0; 179 | top: 0; 180 | width: 100%; 181 | } 182 | 183 | .scrollbar-outer > .scroll-element.scroll-x { 184 | bottom: 0; 185 | height: 12px; 186 | left: 0; 187 | width: 100%; 188 | } 189 | 190 | .scrollbar-outer > .scroll-element.scroll-y { 191 | height: 100%; 192 | right: 0; 193 | top: 0; 194 | width: 12px; 195 | } 196 | 197 | .scrollbar-outer > .scroll-element.scroll-x .scroll-element_outer { height: 8px; top: 2px; } 198 | .scrollbar-outer > .scroll-element.scroll-y .scroll-element_outer { left: 2px; width: 8px; } 199 | 200 | .scrollbar-outer > .scroll-element .scroll-element_outer { overflow: hidden; } 201 | .scrollbar-outer > .scroll-element .scroll-element_track { background-color: #eeeeee; } 202 | 203 | .scrollbar-outer > .scroll-element .scroll-element_outer, 204 | .scrollbar-outer > .scroll-element .scroll-element_track, 205 | .scrollbar-outer > .scroll-element .scroll-bar { 206 | -webkit-border-radius: 8px; 207 | -moz-border-radius: 8px; 208 | border-radius: 8px; 209 | } 210 | 211 | .scrollbar-outer > .scroll-element .scroll-bar { background-color: #d9d9d9; } 212 | .scrollbar-outer > .scroll-element .scroll-bar:hover { background-color: #c2c2c2; } 213 | .scrollbar-outer > .scroll-element.scroll-draggable .scroll-bar { background-color: #919191; } 214 | 215 | 216 | /* scrollbar height/width & offset from container borders */ 217 | 218 | .scrollbar-outer > .scroll-content.scroll-scrolly_visible { left: -12px; margin-left: 12px; } 219 | .scrollbar-outer > .scroll-content.scroll-scrollx_visible { top: -12px; margin-top: 12px; } 220 | 221 | .scrollbar-outer > .scroll-element.scroll-x .scroll-bar { min-width: 10px; } 222 | .scrollbar-outer > .scroll-element.scroll-y .scroll-bar { min-height: 10px; } 223 | 224 | 225 | /* update scrollbar offset if both scrolls are visible */ 226 | 227 | .scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -14px; } 228 | .scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -14px; } 229 | 230 | .scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -14px; } 231 | .scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -14px; } 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | /*************** SCROLLBAR MAC OS X ***************/ 243 | 244 | .scrollbar-macosx > .scroll-element, 245 | .scrollbar-macosx > .scroll-element div 246 | { 247 | background: none; 248 | border: none; 249 | margin: 0; 250 | padding: 0; 251 | position: absolute; 252 | z-index: 10; 253 | } 254 | 255 | .scrollbar-macosx > .scroll-element div { 256 | display: block; 257 | height: 100%; 258 | left: 0; 259 | top: 0; 260 | width: 100%; 261 | } 262 | 263 | .scrollbar-macosx > .scroll-element .scroll-element_track { display: none; } 264 | .scrollbar-macosx > .scroll-element .scroll-bar { 265 | background-color: #6C6E71; 266 | display: block; 267 | 268 | -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 269 | filter: alpha(opacity=0); 270 | opacity: 0; 271 | 272 | -webkit-border-radius: 7px; 273 | -moz-border-radius: 7px; 274 | border-radius: 7px; 275 | 276 | -webkit-transition: opacity 0.2s linear; 277 | -moz-transition: opacity 0.2s linear; 278 | -o-transition: opacity 0.2s linear; 279 | -ms-transition: opacity 0.2s linear; 280 | transition: opacity 0.2s linear; 281 | } 282 | .scrollbar-macosx:hover > .scroll-element .scroll-bar, 283 | .scrollbar-macosx > .scroll-element.scroll-draggable .scroll-bar { 284 | -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; 285 | filter: alpha(opacity=70); 286 | opacity: 0.7; 287 | } 288 | 289 | 290 | .scrollbar-macosx > .scroll-element.scroll-x { 291 | bottom: 0px; 292 | height: 0px; 293 | left: 0; 294 | min-width: 100%; 295 | overflow: visible; 296 | width: 100%; 297 | } 298 | 299 | .scrollbar-macosx > .scroll-element.scroll-y { 300 | height: 100%; 301 | min-height: 100%; 302 | right: 0px; 303 | top: 0; 304 | width: 0px; 305 | } 306 | 307 | /* scrollbar height/width & offset from container borders */ 308 | .scrollbar-macosx > .scroll-element.scroll-x .scroll-bar { height: 7px; min-width: 10px; top: -9px; } 309 | .scrollbar-macosx > .scroll-element.scroll-y .scroll-bar { left: -9px; min-height: 10px; width: 7px; } 310 | 311 | .scrollbar-macosx > .scroll-element.scroll-x .scroll-element_outer { left: 2px; } 312 | .scrollbar-macosx > .scroll-element.scroll-x .scroll-element_size { left: -4px; } 313 | 314 | .scrollbar-macosx > .scroll-element.scroll-y .scroll-element_outer { top: 2px; } 315 | .scrollbar-macosx > .scroll-element.scroll-y .scroll-element_size { top: -4px; } 316 | 317 | /* update scrollbar offset if both scrolls are visible */ 318 | .scrollbar-macosx > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -11px; } 319 | .scrollbar-macosx > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -11px; } 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | /*************** SCROLLBAR LIGHT ***************/ 331 | 332 | .scrollbar-light > .scroll-element, 333 | .scrollbar-light > .scroll-element div { 334 | border: none; 335 | margin: 0; 336 | overflow: hidden; 337 | padding: 0; 338 | position: absolute; 339 | z-index: 10; 340 | } 341 | 342 | .scrollbar-light > .scroll-element { 343 | background-color: #ffffff; 344 | } 345 | 346 | .scrollbar-light > .scroll-element div { 347 | display: block; 348 | height: 100%; 349 | left: 0; 350 | top: 0; 351 | width: 100%; 352 | } 353 | 354 | .scrollbar-light > .scroll-element .scroll-element_outer { 355 | -webkit-border-radius: 10px; 356 | -moz-border-radius: 10px; 357 | border-radius: 10px; 358 | } 359 | 360 | .scrollbar-light > .scroll-element .scroll-element_size { 361 | background: #dbdbdb; 362 | background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiZGJkYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlOGU4ZTgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+'); 363 | background: -moz-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%); 364 | background: -webkit-gradient(linear, left top, right top, color-stop(0%,#dbdbdb), color-stop(100%,#e8e8e8)); 365 | background: -webkit-linear-gradient(left, #dbdbdb 0%,#e8e8e8 100%); 366 | background: -o-linear-gradient(left, #dbdbdb 0%,#e8e8e8 100%); 367 | background: -ms-linear-gradient(left, #dbdbdb 0%,#e8e8e8 100%); 368 | background: linear-gradient(to right, #dbdbdb 0%,#e8e8e8 100%); 369 | 370 | -webkit-border-radius: 10px; 371 | -moz-border-radius: 10px; 372 | border-radius: 10px; 373 | } 374 | 375 | .scrollbar-light > .scroll-element.scroll-x { 376 | bottom: 0; 377 | height: 17px; 378 | left: 0; 379 | min-width: 100%; 380 | width: 100%; 381 | } 382 | 383 | .scrollbar-light > .scroll-element.scroll-y { 384 | height: 100%; 385 | min-height: 100%; 386 | right: 0; 387 | top: 0; 388 | width: 17px; 389 | } 390 | 391 | .scrollbar-light > .scroll-element .scroll-bar { 392 | background: #fefefe; 393 | background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZmVmZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+'); 394 | background: -moz-linear-gradient(left, #fefefe 0%, #f5f5f5 100%); 395 | background: -webkit-gradient(linear, left top, right top, color-stop(0%,#fefefe), color-stop(100%,#f5f5f5)); 396 | background: -webkit-linear-gradient(left, #fefefe 0%,#f5f5f5 100%); 397 | background: -o-linear-gradient(left, #fefefe 0%,#f5f5f5 100%); 398 | background: -ms-linear-gradient(left, #fefefe 0%,#f5f5f5 100%); 399 | background: linear-gradient(to right, #fefefe 0%,#f5f5f5 100%); 400 | 401 | border: 1px solid #dbdbdb; 402 | -webkit-border-radius: 10px; 403 | -moz-border-radius: 10px; 404 | border-radius: 10px; 405 | } 406 | 407 | /* scrollbar height/width & offset from container borders */ 408 | 409 | .scrollbar-light > .scroll-content.scroll-scrolly_visible { left: -17px; margin-left: 17px; } 410 | .scrollbar-light > .scroll-content.scroll-scrollx_visible { top: -17px; margin-top: 17px; } 411 | 412 | .scrollbar-light > .scroll-element.scroll-x .scroll-bar { height: 10px; min-width: 10px; top: 0px; } 413 | .scrollbar-light > .scroll-element.scroll-y .scroll-bar { left: 0px; min-height: 10px; width: 10px; } 414 | 415 | .scrollbar-light > .scroll-element.scroll-x .scroll-element_outer { height: 12px; left: 2px; top: 2px; } 416 | .scrollbar-light > .scroll-element.scroll-x .scroll-element_size { left: -4px; } 417 | 418 | .scrollbar-light > .scroll-element.scroll-y .scroll-element_outer { left: 2px; top: 2px; width: 12px; } 419 | .scrollbar-light > .scroll-element.scroll-y .scroll-element_size { top: -4px; } 420 | 421 | /* update scrollbar offset if both scrolls are visible */ 422 | 423 | .scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -19px; } 424 | .scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -19px; } 425 | 426 | .scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -19px; } 427 | .scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -19px; } 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | /*************** SCROLLBAR RAIL ***************/ 439 | 440 | .scrollbar-rail > .scroll-element, 441 | .scrollbar-rail > .scroll-element div 442 | { 443 | border: none; 444 | margin: 0; 445 | overflow: hidden; 446 | padding: 0; 447 | position: absolute; 448 | z-index: 10; 449 | } 450 | 451 | .scrollbar-rail > .scroll-element { 452 | background-color: #ffffff; 453 | } 454 | 455 | .scrollbar-rail > .scroll-element div { 456 | display: block; 457 | height: 100%; 458 | left: 0; 459 | top: 0; 460 | width: 100%; 461 | } 462 | 463 | .scrollbar-rail > .scroll-element .scroll-element_size { 464 | background-color: #999; 465 | background-color: rgba(0, 0, 0, 0.3); 466 | } 467 | 468 | .scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-element_size { 469 | background-color: #666; 470 | background-color: rgba(0, 0, 0, 0.5); 471 | } 472 | 473 | .scrollbar-rail > .scroll-element.scroll-x { 474 | bottom: 0; 475 | height: 12px; 476 | left: 0; 477 | min-width: 100%; 478 | padding: 3px 0 2px; 479 | width: 100%; 480 | } 481 | 482 | .scrollbar-rail > .scroll-element.scroll-y { 483 | height: 100%; 484 | min-height: 100%; 485 | padding: 0 2px 0 3px; 486 | right: 0; 487 | top: 0; 488 | width: 12px; 489 | } 490 | 491 | .scrollbar-rail > .scroll-element .scroll-bar { 492 | background-color: #d0b9a0; 493 | 494 | -webkit-border-radius: 2px; 495 | -moz-border-radius: 2px; 496 | border-radius: 2px; 497 | 498 | box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5); 499 | } 500 | 501 | .scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-bar { 502 | box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6); 503 | } 504 | 505 | /* scrollbar height/width & offset from container borders */ 506 | 507 | .scrollbar-rail > .scroll-content.scroll-scrolly_visible { left: -17px; margin-left: 17px; } 508 | .scrollbar-rail > .scroll-content.scroll-scrollx_visible { margin-top: 17px; top: -17px; } 509 | 510 | .scrollbar-rail > .scroll-element.scroll-x .scroll-bar { height: 10px; min-width: 10px; top: 1px; } 511 | .scrollbar-rail > .scroll-element.scroll-y .scroll-bar { left: 1px; min-height: 10px; width: 10px; } 512 | 513 | .scrollbar-rail > .scroll-element.scroll-x .scroll-element_outer { height: 15px; left: 5px; } 514 | .scrollbar-rail > .scroll-element.scroll-x .scroll-element_size { height: 2px; left: -10px; top: 5px; } 515 | 516 | .scrollbar-rail > .scroll-element.scroll-y .scroll-element_outer { top: 5px; width: 15px; } 517 | .scrollbar-rail > .scroll-element.scroll-y .scroll-element_size { left: 5px; top: -10px; width: 2px; } 518 | 519 | /* update scrollbar offset if both scrolls are visible */ 520 | 521 | .scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -25px; } 522 | .scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -25px; } 523 | 524 | .scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -25px; } 525 | .scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -25px; } 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | /*************** SCROLLBAR DYNAMIC ***************/ 537 | 538 | .scrollbar-dynamic > .scroll-element, 539 | .scrollbar-dynamic > .scroll-element div 540 | { 541 | background: none; 542 | border: none; 543 | margin: 0; 544 | padding: 0; 545 | position: absolute; 546 | z-index: 10; 547 | } 548 | 549 | .scrollbar-dynamic > .scroll-element div { 550 | display: block; 551 | height: 100%; 552 | left: 0; 553 | top: 0; 554 | width: 100%; 555 | } 556 | 557 | .scrollbar-dynamic > .scroll-element.scroll-x { 558 | bottom: 2px; 559 | height: 7px; 560 | left: 0; 561 | min-width: 100%; 562 | width: 100%; 563 | } 564 | 565 | .scrollbar-dynamic > .scroll-element.scroll-y { 566 | height: 100%; 567 | min-height: 100%; 568 | right: 2px; 569 | top: 0; 570 | width: 7px; 571 | } 572 | 573 | .scrollbar-dynamic > .scroll-element .scroll-element_outer { 574 | opacity: 0.3; 575 | 576 | -webkit-border-radius: 12px; 577 | -moz-border-radius: 12px; 578 | border-radius: 12px; 579 | } 580 | .scrollbar-dynamic > .scroll-element .scroll-element_size { 581 | background-color: #cccccc; 582 | opacity: 0; 583 | 584 | -webkit-border-radius: 12px; 585 | -moz-border-radius: 12px; 586 | border-radius: 12px; 587 | 588 | -webkit-transition: opacity 0.2s; 589 | -moz-transition: opacity 0.2s; 590 | -o-transition: opacity 0.2s; 591 | -ms-transition: opacity 0.2s; 592 | transition: opacity 0.2s; 593 | } 594 | 595 | .scrollbar-dynamic > .scroll-element .scroll-bar { 596 | background-color: #6c6e71; 597 | 598 | -webkit-border-radius: 7px; 599 | -moz-border-radius: 7px; 600 | border-radius: 7px; 601 | } 602 | 603 | /* scrollbar height/width & offset from container borders */ 604 | 605 | .scrollbar-dynamic > .scroll-element.scroll-x .scroll-bar { 606 | bottom: 0; 607 | height: 7px; 608 | min-width: 24px; 609 | top: auto; 610 | } 611 | .scrollbar-dynamic > .scroll-element.scroll-y .scroll-bar { 612 | left: auto; 613 | min-height: 24px; 614 | right: 0; 615 | width: 7px; 616 | } 617 | 618 | .scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_outer { 619 | bottom: 0; 620 | top: auto; 621 | left: 2px; 622 | 623 | -webkit-transition: height 0.2s; 624 | -moz-transition: height 0.2s; 625 | -o-transition: height 0.2s; 626 | -ms-transition: height 0.2s; 627 | transition: height 0.2s; 628 | } 629 | 630 | .scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_outer { 631 | left: auto; 632 | right: 0; 633 | top: 2px; 634 | 635 | -webkit-transition: width 0.2s; 636 | -moz-transition: width 0.2s; 637 | -o-transition: width 0.2s; 638 | -ms-transition: width 0.2s; 639 | transition: width 0.2s; 640 | } 641 | 642 | .scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_size { left: -4px; } 643 | .scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_size { top: -4px; } 644 | 645 | 646 | /* update scrollbar offset if both scrolls are visible */ 647 | 648 | .scrollbar-dynamic > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -11px; } 649 | .scrollbar-dynamic > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -11px; } 650 | 651 | 652 | /* hover & drag */ 653 | 654 | .scrollbar-dynamic > .scroll-element:hover .scroll-element_outer, 655 | .scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer { 656 | overflow: hidden; 657 | 658 | -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; 659 | filter: alpha(opacity=70); 660 | opacity: 0.7; 661 | } 662 | .scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-element_size, 663 | .scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-element_size { 664 | opacity: 1; 665 | } 666 | .scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-bar, 667 | .scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-bar { 668 | height: 100%; 669 | width: 100%; 670 | 671 | -webkit-border-radius: 12px; 672 | -moz-border-radius: 12px; 673 | border-radius: 12px; 674 | } 675 | 676 | .scrollbar-dynamic > .scroll-element.scroll-x:hover .scroll-element_outer, 677 | .scrollbar-dynamic > .scroll-element.scroll-x.scroll-draggable .scroll-element_outer { 678 | height: 20px; 679 | min-height: 7px; 680 | } 681 | .scrollbar-dynamic > .scroll-element.scroll-y:hover .scroll-element_outer, 682 | .scrollbar-dynamic > .scroll-element.scroll-y.scroll-draggable .scroll-element_outer { 683 | min-width: 7px; 684 | width: 20px; 685 | } 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | /*************** SCROLLBAR GOOGLE CHROME ***************/ 697 | 698 | .scrollbar-chrome > .scroll-element, 699 | .scrollbar-chrome > .scroll-element div 700 | { 701 | border: none; 702 | margin: 0; 703 | overflow: hidden; 704 | padding: 0; 705 | position: absolute; 706 | z-index: 10; 707 | } 708 | 709 | .scrollbar-chrome > .scroll-element { 710 | background-color: #ffffff; 711 | } 712 | 713 | .scrollbar-chrome > .scroll-element div { 714 | display: block; 715 | height: 100%; 716 | left: 0; 717 | top: 0; 718 | width: 100%; 719 | } 720 | 721 | .scrollbar-chrome > .scroll-element .scroll-element_outer {} 722 | 723 | .scrollbar-chrome > .scroll-element .scroll-element_track { 724 | background: #f1f1f1; 725 | border: 1px solid #dbdbdb; 726 | } 727 | 728 | .scrollbar-chrome > .scroll-element.scroll-x { 729 | bottom: 0; 730 | height: 16px; 731 | left: 0; 732 | min-width: 100%; 733 | width: 100%; 734 | } 735 | 736 | .scrollbar-chrome > .scroll-element.scroll-y { 737 | height: 100%; 738 | min-height: 100%; 739 | right: 0; 740 | top: 0; 741 | width: 16px; 742 | } 743 | 744 | .scrollbar-chrome > .scroll-element .scroll-bar { 745 | background-color: #d9d9d9; 746 | border: 1px solid #bdbdbd; 747 | cursor: default; 748 | 749 | -webkit-border-radius: 2px; 750 | -moz-border-radius: 2px; 751 | border-radius: 2px; 752 | } 753 | 754 | .scrollbar-chrome > .scroll-element .scroll-bar:hover { 755 | background-color: #c2c2c2; 756 | border-color: #a9a9a9; 757 | } 758 | 759 | .scrollbar-chrome > .scroll-element.scroll-draggable .scroll-bar { 760 | background-color: #919191; 761 | border-color: #7e7e7e; 762 | } 763 | 764 | /* scrollbar height/width & offset from container borders */ 765 | 766 | .scrollbar-chrome > .scroll-content.scroll-scrolly_visible { left: -16px; margin-left: 16px; } 767 | .scrollbar-chrome > .scroll-content.scroll-scrollx_visible { top: -16px; margin-top: 16px; } 768 | 769 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-bar { height: 8px; min-width: 10px; top: 3px; } 770 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-bar { left: 3px; min-height: 10px; width: 8px; } 771 | 772 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-element_outer { border-left: 1px solid #dbdbdb; } 773 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-element_track { height: 14px; left: -3px; } 774 | .scrollbar-chrome > .scroll-element.scroll-x .scroll-element_size { height: 14px; left: -4px; } 775 | 776 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-element_outer { border-top: 1px solid #dbdbdb; } 777 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-element_track { top: -3px; width: 14px; } 778 | .scrollbar-chrome > .scroll-element.scroll-y .scroll-element_size { top: -4px; width: 14px; } 779 | 780 | /* update scrollbar offset if both scrolls are visible */ 781 | 782 | .scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -19px; } 783 | .scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -19px; } 784 | 785 | .scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -19px; } 786 | .scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -19px; } 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | -------------------------------------------------------------------------------- /sass/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.scrollbar", 3 | "version": "0.2.11", 4 | "devDependencies": { 5 | "grunt": "~0.4.1", 6 | "grunt-contrib-compass": "^1.0.4", 7 | "grunt-contrib-watch": "~0.6.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /scrollbar.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scrollbar", 3 | "title": "jQuery Scrollbar", 4 | "description": "Cross-browser CSS customizable scrollbar with advanced features: standard scroll behavior in all browsers/devices, responsive design support (no fixed height or width required), horizontal/vertical scrollbar or both, external scrollbars, automatically hide/show scrollbars (if content/container size is changed) and more...", 5 | "keywords": [ 6 | "scroll", 7 | "scrollbar" 8 | ], 9 | "version": "0.2.11", 10 | "author": { 11 | "name": "Yuriy Khabarov", 12 | "email": "13real008@gmail.com" 13 | }, 14 | "licenses": [ 15 | { 16 | "type": "MIT", 17 | "url": "https://github.com/gromo/jquery.scrollbar/blob/master/license-mit.txt" 18 | }, 19 | { 20 | "type": "GPLv2", 21 | "url": "https://github.com/gromo/jquery.scrollbar/blob/master/license-gpl.txt" 22 | } 23 | ], 24 | "homepage": "http://gromo.github.io/jquery.scrollbar/", 25 | "download": "http://gromo.github.io/jquery.scrollbar/jquery.scrollbar.zip", 26 | "demo": "http://gromo.github.io/jquery.scrollbar/demo/basic.html", 27 | "dependencies": { 28 | "jquery": ">=1.7" 29 | } 30 | } 31 | --------------------------------------------------------------------------------