diff --git a/README.md b/README.md
index 7394df0..20cc7ef 100644
--- a/README.md
+++ b/README.md
@@ -316,6 +316,36 @@ When set to false, when clicking on a rail, the click event will be allowed to p
When set to true, you can scroll the container by selecting text and move the cursor.
**Default: false**
+### theme
+A string. It's a class name added to the container element. The class name is prepended with `ps-theme-`. So default theme class name is `ps-theme-default`. In order to create custom themes with scss use `ps-container($theme)` mixin, where `$theme` is a scss map.
+**Default: 'default'**
+
+**Example 1:**
+
+Add `theme` parameter:
+```javascript
+Ps.initialize(container, {
+ theme: 'my-theme-name'
+});
+```
+Create a class name prefixed with `.ps-theme-`. Include `ps-container()` mixin. It's recommended to use `map-merge()` to extend `$ps-theme-default` map with your custom styles.
+```css#
+.ps-theme-my-theme-name {
+ @include ps-container(map-merge($ps-theme-default, (
+ border-radius: 0,
+ scrollbar-x-rail-height: 20px,
+ scrollbar-x-height: 20px,
+ scrollbar-y-rail-width: 20px,
+ scrollbar-y-width: 20px,)
+ ));
+}
+```
+
+**Example 2:**
+
+Alternatively, if you don't want to create your own themes, but only modify the default one, you could simply overwrite `$ps-*` variables with your own values. In this case `theme` parameter is not required when calling `.initialize()` method. Remember do define your own variables before the `theme.scss` file is imported.
+
+
## Events
perfect-scrollbar dispatches custom events.
diff --git a/examples/custom-theme.html b/examples/custom-theme.html
new file mode 100644
index 0000000..c9d4965
--- /dev/null
+++ b/examples/custom-theme.html
@@ -0,0 +1,27 @@
+
+
+
+
+ perfect-scrollbar example
+
+
+
+
+
+
+
+
+
diff --git a/src/css/main.scss b/src/css/main.scss
index e370139..ae1f655 100644
--- a/src/css/main.scss
+++ b/src/css/main.scss
@@ -1,134 +1,3 @@
-// Colors
-$ps-rail-hover: #eee;
-$ps-bar-default: #aaa;
-$ps-bar-hover: #999;
-
-// Helper mixins
-@mixin border-radius($r) {
- -webkit-border-radius: $r;
- -moz-border-radius: $r;
- -ms-border-radius: $r;
- border-radius: $r;
-}
-
-@mixin transition($t...) {
- -webkit-transition: $t;
- -moz-transition: $t;
- -o-transition: $t;
- transition: $t;
-}
-
-// Scrollbar mixins
-@mixin scrollbar-rail-default {
- display: none;
- position: absolute; /* please don't change 'position' */
- @include border-radius(4px);
- opacity: 0;
- @include transition(background-color .2s linear, opacity .2s linear);
-}
-
-@mixin scrollbar-rail-hover {
- background-color: $ps-rail-hover;
- opacity: 0.9;
-}
-
-@mixin scrollbar-default {
- position: absolute; /* please don't change 'position' */
- background-color: $ps-bar-default;
- @include border-radius(4px);
- @include transition(background-color .2s linear);
-}
-
-@mixin scrollbar-hover {
- background-color: $ps-bar-hover;
-}
-
-@mixin in-scrolling {
- &.ps-in-scrolling {
- pointer-events: none;
- &.ps-x>.ps-scrollbar-x-rail{
- @include scrollbar-rail-hover;
- >.ps-scrollbar-x {
- @include scrollbar-hover;
- }
- }
- &.ps-y>.ps-scrollbar-y-rail {
- @include scrollbar-rail-hover;
- >.ps-scrollbar-y {
- @include scrollbar-hover;
- }
- }
- }
-}
-
-.ps-container {
- -ms-touch-action: none;
- touch-action: none;
- overflow: hidden !important;
- -ms-overflow-style: none;
-
- // Edge
- @supports (-ms-overflow-style: none) {
- overflow: auto !important;
- }
- // IE10+
- @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
- overflow: auto !important;
- }
-
- &.ps-active-x > .ps-scrollbar-x-rail,
- &.ps-active-y > .ps-scrollbar-y-rail {
- display: block;
- }
-
- @include in-scrolling;
-
- >.ps-scrollbar-x-rail {
- @include scrollbar-rail-default;
- bottom: 3px; /* there must be 'bottom' for ps-scrollbar-x-rail */
- height: 8px;
-
- >.ps-scrollbar-x {
- @include scrollbar-default;
- bottom: 0; /* there must be 'bottom' for ps-scrollbar-x */
- height: 8px;
- }
- }
-
- >.ps-scrollbar-y-rail {
- @include scrollbar-rail-default;
- right: 3px; /* there must be 'right' for ps-scrollbar-y-rail */
- width: 8px;
-
- >.ps-scrollbar-y {
- @include scrollbar-default;
- right: 0; /* there must be 'right' for ps-scrollbar-y */
- width: 8px;
- }
- }
-
- &:hover, &.ps-focus {
- @include in-scrolling;
-
- >.ps-scrollbar-x-rail,
- >.ps-scrollbar-y-rail {
- opacity: 0.6;
- }
-
- >.ps-scrollbar-x-rail:hover {
- @include scrollbar-rail-hover;
-
- >.ps-scrollbar-x {
- @include scrollbar-hover;
- }
- }
-
- >.ps-scrollbar-y-rail:hover {
- @include scrollbar-rail-hover;
-
- >.ps-scrollbar-y {
- @include scrollbar-hover;
- }
- }
- }
-}
+@import 'variables';
+@import 'mixins';
+@import 'themes';
diff --git a/src/css/mixins.scss b/src/css/mixins.scss
new file mode 100644
index 0000000..f2abecf
--- /dev/null
+++ b/src/css/mixins.scss
@@ -0,0 +1,120 @@
+// Helper mixins
+@mixin border-radius($r) {
+ -webkit-border-radius: $r;
+ -moz-border-radius: $r;
+ -ms-border-radius: $r;
+ border-radius: $r;
+}
+
+@mixin transition($t...) {
+ -webkit-transition: $t;
+ -moz-transition: $t;
+ -o-transition: $t;
+ transition: $t;
+}
+
+// Scrollbar mixins
+@mixin scrollbar-rail-default($theme) {
+ display: none;
+ position: absolute; /* please don't change 'position' */
+ @include border-radius(map_get($theme, border-radius));
+ opacity: map_get($theme, rail-default-opacity);
+ @include transition(background-color .2s linear, opacity .2s linear);
+}
+
+@mixin scrollbar-rail-hover($theme) {
+ background-color: map_get($theme, rail-hover-bg);
+ opacity: map_get($theme, rail-hover-opacity);
+}
+
+@mixin scrollbar-default($theme) {
+ position: absolute; /* please don't change 'position' */
+ background-color: map_get($theme, bar-container-hover-bg);
+ @include border-radius(map_get($theme, border-radius));
+ @include transition(background-color .2s linear);
+}
+
+@mixin scrollbar-hover($theme) {
+ background-color: map_get($theme, bar-hover-bg);
+}
+
+@mixin in-scrolling($theme) {
+ &.ps-in-scrolling {
+ pointer-events: none;
+ &.ps-x > .ps-scrollbar-x-rail {
+ @include scrollbar-rail-hover($theme);
+ > .ps-scrollbar-x {
+ @include scrollbar-hover($theme);
+ }
+ }
+ &.ps-y > .ps-scrollbar-y-rail {
+ @include scrollbar-rail-hover($theme);
+ > .ps-scrollbar-y {
+ @include scrollbar-hover($theme);
+ }
+ }
+ }
+}
+
+// Layout and theme mixin
+@mixin ps-container($theme) {
+ -ms-touch-action: none;
+ overflow: hidden !important;
+
+ &.ps-active-x > .ps-scrollbar-x-rail,
+ &.ps-active-y > .ps-scrollbar-y-rail {
+ display: block;
+ background-color: map_get($theme, bar-bg);
+ }
+
+ @include in-scrolling($theme);
+
+ > .ps-scrollbar-x-rail {
+ @include scrollbar-rail-default($theme);
+ bottom: map_get($theme, scrollbar-x-rail-bottom); /* there must be 'bottom' for ps-scrollbar-x-rail */
+ height: map_get($theme, scrollbar-x-rail-height);
+
+ > .ps-scrollbar-x {
+ @include scrollbar-default($theme);
+ bottom: map_get($theme, scrollbar-x-bottom); /* there must be 'bottom' for ps-scrollbar-x */
+ height: map_get($theme, scrollbar-x-height);
+ }
+ }
+
+ > .ps-scrollbar-y-rail {
+ @include scrollbar-rail-default($theme);
+ right: map_get($theme, scrollbar-y-rail-right); /* there must be 'right' for ps-scrollbar-y-rail */
+ width: map_get($theme, scrollbar-y-rail-width);
+
+ > .ps-scrollbar-y {
+ @include scrollbar-default($theme);
+ right: map_get($theme, scrollbar-y-right); /* there must be 'right' for ps-scrollbar-y */
+ width: map_get($theme, scrollbar-y-width);
+ }
+ }
+
+ &:hover {
+ @include in-scrolling($theme);
+
+ > .ps-scrollbar-x-rail,
+ > .ps-scrollbar-y-rail {
+ opacity: map_get($theme, rail-container-hover-opacity);
+ }
+
+ > .ps-scrollbar-x-rail:hover {
+ @include scrollbar-rail-hover($theme);
+
+ > .ps-scrollbar-x {
+ @include scrollbar-hover($theme);
+ }
+ }
+
+ > .ps-scrollbar-y-rail:hover {
+ @include scrollbar-rail-hover($theme);
+
+ > .ps-scrollbar-y {
+ @include scrollbar-hover($theme);
+ }
+ }
+ }
+}
diff --git a/src/css/themes.scss b/src/css/themes.scss
new file mode 100644
index 0000000..af6defe
--- /dev/null
+++ b/src/css/themes.scss
@@ -0,0 +1,23 @@
+$ps-theme-default: (
+ border-radius: $ps-border-radius,
+ rail-default-opacity: $ps-rail-default-opacity,
+ rail-container-hover-opacity: $ps-rail-container-hover-opacity,
+ rail-hover-opacity: $ps-rail-hover-opacity,
+ bar-bg: $ps-bar-bg,
+ bar-container-hover-bg: $ps-bar-container-hover-bg,
+ bar-hover-bg: $ps-bar-hover-bg,
+ rail-hover-bg: $ps-rail-hover-bg,
+ scrollbar-x-rail-bottom: $ps-scrollbar-x-rail-bottom,
+ scrollbar-x-rail-height: $ps-scrollbar-x-rail-height,
+ scrollbar-x-bottom: $ps-scrollbar-x-bottom,
+ scrollbar-x-height: $ps-scrollbar-x-height,
+ scrollbar-y-rail-right: $ps-scrollbar-y-rail-right,
+ scrollbar-y-rail-width: $ps-scrollbar-y-rail-width,
+ scrollbar-y-right: $ps-scrollbar-y-right,
+ scrollbar-y-width: $ps-scrollbar-y-width,
+);
+
+// Default theme
+.ps-container {
+ @include ps-container($ps-theme-default);
+}
diff --git a/src/css/variables.scss b/src/css/variables.scss
new file mode 100644
index 0000000..d67c156
--- /dev/null
+++ b/src/css/variables.scss
@@ -0,0 +1,22 @@
+// Colors
+$ps-border-radius: 4px !default;
+
+$ps-rail-default-opacity: 0 !default;
+$ps-rail-container-hover-opacity: 0.6 !default;
+$ps-rail-hover-opacity: 0.9 !default;
+
+$ps-bar-bg: transparent !default;
+$ps-bar-container-hover-bg: #aaa !default;
+$ps-bar-hover-bg: #999 !default;
+$ps-rail-hover-bg: #eee !default;
+
+// Sizes
+$ps-scrollbar-x-rail-bottom: 3px !default;
+$ps-scrollbar-x-rail-height: 8px !default;
+$ps-scrollbar-x-bottom: 0 !default;
+$ps-scrollbar-x-height: 8px !default;
+
+$ps-scrollbar-y-rail-right: 3px !default;
+$ps-scrollbar-y-rail-width: 8px !default;
+$ps-scrollbar-y-right: 0 !default;
+$ps-scrollbar-y-width: 8px !default;
diff --git a/src/js/plugin/default-setting.js b/src/js/plugin/default-setting.js
index 9497447..521c73e 100644
--- a/src/js/plugin/default-setting.js
+++ b/src/js/plugin/default-setting.js
@@ -13,5 +13,6 @@ module.exports = {
useKeyboard: true,
useSelectionScroll: false,
wheelPropagation: false,
- wheelSpeed: 1
+ wheelSpeed: 1,
+ theme: 'default'
};
diff --git a/src/js/plugin/initialize.js b/src/js/plugin/initialize.js
index 156ef1a..a983434 100644
--- a/src/js/plugin/initialize.js
+++ b/src/js/plugin/initialize.js
@@ -23,6 +23,7 @@ module.exports = function (element, userSettings) {
var i = instances.add(element);
i.settings = h.extend(i.settings, userSettings);
+ cls.add(element, 'ps-theme-' + i.settings.theme);
clickRailHandler(element);
dragScrollbarHandler(element);