Happy new year all. Hats off to all CSS jockeys around the world this was a real struggle for me and not all done yet I would guess.
Here for your consumption:
[{"id":"bd6a122b.f50f6","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"e86761a9.beaeb","type":"ui_template","z":"bd6a122b.f50f6","group":"bb12aba1.d14278","name":"Range CSS","order":2,"width":4,"height":1,"format":"<!--\n Range Slider\n ============\n \n Outputs {v1: value, v2: value} on mouse up.\n \n Designed with 48px x 48px dashboard grid and seems to work\n with widget heights greater than one.\n This is a discrete range slider made from two single overlapping thumb md-sliders\n The focus dividing line is on each side of the track.\n \n Untested: 90 Deg. rotation.\n \n Fits in 48px high space. \n \n TODO: \n (1) General Pi touch screen problem - disable copy and select.\n (2) Unfilled track colour not exposed as dashboard theme variable.\n This means that rgba(111,111,111,1) is a tad too dark in both \n dark and light themes. An acceptable compromise until a variable \n is added to dashboard.\n (3) Thumb fails to scale on focus - transform:scale(1) !important;\n (4) Cannot get thumb to sit on top of grey part of slider that represents\n the unfilled length of track.\n (5) Have not figured out how to push v1 with v2 and\n push v2 with v1 unsing just CSS ?\n (6) An undesirable transform flicker when v2 is hovered.\n (7) Could probably use a label.\n Notes:\n md-invert\n\n-->\n<style>\n .nr-dashboard-template, .slider-v1{\n font-family:Liberation;\n padding: 0px;\n overflow:visible;\n }\n\n/* TODO` fails to stay scaled*/\n.slider-v1:focus .md-focus-ring:focus,\n.slider-v2:focus .md-focus-ring:focus {\n transform:scale(1) !important;\n}\n /* ok */\n .slider-v1:not(:focus) .md-focus-ring:hover,\n .slider-v2:not(:focus) .md-focus-ring:hover {\n transform:scale(0.8) !important;\n }\n .slider-v1 .md-focus-ring,\n .slider-v2 .md-focus-ring {\n top:14px;\n left:-10px;\n height:20px;\n width:20px;\n opacity:1;\n z-index:9998;\n background-color: var(--nr-dashboard-widgetColor) !important;\n }\n .slider-v1 .md-thumb, .slider-v2 .md-thumb,\n .slider-v1 .md-thumb:after, .slider-v2 .md-thumb:after {\n background-color: var(--nr-dashboard-widgetColor) !important;\n }\n.slider-v1 .md-sign,\n.slider-v2 .md-sign {\n height:16px !important;\n width:25px !important;\n background-color:var(--nr-dashboard-groupBackgroundColor);\n}\n/* v1 .md-sign */\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):focus .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):hover .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):active .md-sign {\n opacity:1;\n -webkit-transform: translate3d(1px, 10px, 0) scale(1) !important;\n transform: translate3d(1px, 10px, 0) scale(1) !important;\n background-color:var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):not(:hover) .md-sign,\n md-slider[md-discrete]:not(.slider-v2) .md-sign {\n/* opacity:1;*/\n -webkit-transform: translate3d(1px, 20px, 0) scale(1) !important;\n transform: translate3d(1px, 20px, 0) scale(1) !important;\n }\n/* v1 .md-sign:after */\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):focus .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):hover .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):active .md-sign:after {\n opacity:1;\n -webkit-transform: translate3d(-1px, -11px, 0) scale(1) !important;\n transform: translate3d(-1px, -11px, 0) scale(1) !important;\n border-top-color:var(--nr-dashboard-widgetColor);\n color:var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):not(:hover) .md-sign:after,\n md-slider[md-discrete]:not(.slider-v2) .md-sign:after {\n opacity:0;\n -webkit-transform: translate3d(-1px, -11px, 0) scale(1) !important;\n transform: translate3d(-1px, -11px, 0) scale(1) !important;\n }\n/* v2 .md-sign */\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):focus .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):hover .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):active .md-sign {\n opacity:1;\n -webkit-transform: translate3d(1px, 55px, 0) scale(1);\n transform: translate3d(1px, 55px, 0) scale(1);\n background-color:var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):not(:hover) .md-sign,\n md-slider[md-discrete]:not(.slider-v1) .md-sign {\n/* opacity:1;*/\n -webkit-transform: translate3d(1px, 46px, 0) scale(1);\n transform: translate3d(1px, 46px, 0) scale(1);\n }\n/* v2 .md-sign:after */\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):focus .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):hover .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):active .md-sign:after {\n opacity:1;\n -webkit-transform: translate3d(-1px, -26px, 0) scale(1);\n transform: translate3d(-1px, -26px, 0) scale(1);\n border-top-color:var(--nr-dashboard-widgetColor);\n border-bottom-color:var(--nr-dashboard-widgetColor);\n border-top-width:0px;\n border-bottom-width:14px;\n border-bottom-style:solid;\n color: var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):not(:hover) .md-sign:after,\n md-slider[md-discrete]:not(.slider-v1) .md-sign:after {\n opacity:0;\n -webkit-transform: translate3d(-1px, -26px, 0) scale(1);\n transform: translate3d(-1px, -26px, 0) scale(1);\n }\n /* Show sign when min value */\n .slider-v1:not(:hover) .md-sign,\n .slider-v2:not(:hover) .md-sign {\n background-color:var(--nr-dashboard-groupBackgroundColor) !important;\n opacity:1 !important;\n } \n .slider-v1 .md-thumb-text,\n .slider-v2 .md-thumb-text {\n opacity:1;\n color: var(--nr-dashboard-widgetTextColor) !important;\n }\n .slider-v1:hover .md-thumb-text,\n .slider-v2:hover .md-thumb-text {\n filter: contrast(1);\n }\n .slider-wrapper-v1{\n height: 50%;\n }\n .slider-wrapper-v2 {\n position: absolute !important;\n top:0px !important;\n height: 50%;\n }\n .slider-v2 .md-track-ticks {\n opacity:0 !important;\n }\n .slider-v1 .md-track-fill {\n z-index:9996 !important;\n background-color: var(--nr-dashboard-widgetColor) !important;\n }\n .slider-v2 .md-track-fill {\n z-index:9996 !important;\n }\n .slider-v1, .slider-v2 {\n margin: 0px;\n padding-left:10px;\n padding-right:10px;\n }\n .slider-v1 {\n top:-webkit-calc(100% - min(100%,48px));\n top:calc(100% - min(100%,48px));\n }\n .slider-v1 .md-slider-content {\n top:-webkit-calc(100% - 24px);\n top:calc(100% - 24px);\n }\n .slider-v2 .md-slider-content {\n top: -24px;\n }\n \n .slider-v2 .md-track {\n background-color:rgba(111,111,111,1) !important;\n }\n</style>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":130,"y":40,"wires":[[]]},{"id":"a67b28eb.f00ac8","type":"debug","z":"bd6a122b.f50f6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":110,"y":80,"wires":[]},{"id":"b888dbed.70e238","type":"ui_template","z":"bd6a122b.f50f6","group":"bb12aba1.d14278","name":"Range","order":9,"width":4,"height":"1","format":"<!--\n TODO: see CSS.\n \n Range Slider Requires: rangeSlider-CSS\n ============ =========================\n \n Outputs {v1: nn.n, v2: nn.n} on mouse up.\n \n Currently set to:\n min 15, max 30, step 0.1\n \n This is a discrete range slider made from two single overlapping thumb md-sliders\n The focus dividing line is on each side of the track.\n \n Untested: 90 Deg. rotation.\n \n Fits in 48px high space.\n-->\n\n<script>\n(function(scope) {\n scope.$watch(\"msg.payload\", function (v) {\n if (!v) scope.msg ={ payload: {v1:0, v2:0} };\n });\n})(scope);\n</script>\n\n<div class=\"slider-wrapper-v1;\" \n style=\"height:50%; width:100%;max-width:100%;\">\n <md-slider thumbLabel md-sign md-thumb-text \n style=\"max-width:100%; width:100%;\" \n md-discrete=\"\"\n md-disabled-thumb=\"false\"\n aria-label = \"msg.payload.v1\" \n ng-model=\"msg.payload.v1\" \n ng-change=\"send(msg)\" \n flex=\"20\" min=\"15\" max=\"30\" step=\"0.1\"\n class=\"slider-v1 ng-pristine ng-untouched ng-valid ng-isolate-scope ng-empty\">\n <div class=\"md-slider-wrapper1\">\n <div class=\"md-track-container\">\n <div class=\"md-track\"></div>\n <div class=\"md-track md-track-fill\" \n style=\"width: 55%;\">55</div>\n <div class=\"md-track-ticks\">\n <canvas style=\"position:absolute;\" width=\"100%\" height=\"5px\"></canvas></div>\n </div>\n <div class=\"md-thumb-container\" style=\"left: 55%;\">\n <div class=\"md-pointer\"></div>\n <div class=\"md-thumb\"></div>\n <div class=\"md-focus-thumb\"></div>\n <div class=\"md-focus-ring\"></div>\n <div class=\"md-sign\"><span class=\"md-thumb-text\"></span></div>\n <div class=\"md-disabled-thumb\"></div>\n </div>\n </div> \n </md-slider>\n</div>\n<div class=\"slider-wrapper-v2;\" \n style=\"height:50%; width:100%;max-width:100%;\">\n <md-slider thumbLabel md-sign md-thumb-text \n style=\"max-width:100%; width:100%;\"\n md-discrete=\"\"\n md-disabled-thumb=\"false\"\n aria-label = \"msg.payload.v2\" \n ng-model=\"msg.payload.v2\" \n ng-change=\"send(msg)\" \n flex=\"20\" min=\"15\" max=\"30\" step=\"0.1\"\n class=\"slider-v2 ng-pristine ng-untouched ng-valid ng-isolate-scope ng-empty\">\n <div class=\"md-slider-wrapper2\">\n <div class=\"md-track-container\">\n <div class=\"md-track\"></div>\n <div class=\"md-track md-track-fill\" \n style=\"width: 55%;\">55</div>\n <div class=\"md-track-ticks\">\n <canvas style=\"position:absolute;\" width=\"100%\" height=\"5px\"></canvas></div>\n </div>\n <div class=\"md-thumb-container\" style=\"left: 55%;\">\n <div class=\"md-thumb\"></div>\n <div class=\"md-focus-thumb\"></div>\n <div class=\"md-focus-ring\"></div>\n <div class=\"md-sign\"><span class=\"md-thumb-text\"></span></div>\n <div class=\"md-disabled-thumb\"></div>\n </div>\n </div> \n </md-slider>\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":110,"y":120,"wires":[["a67b28eb.f00ac8"]]},{"id":"1da7c407.8ac8dc","type":"inject","z":"bd6a122b.f50f6","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"v2\":19.2,\"v1\":23.5}","payloadType":"json","x":150,"y":160,"wires":[["b888dbed.70e238"]]},{"id":"bb12aba1.d14278","type":"ui_group","name":"Dashboard 2.26.1 - ui_template range slider","tab":"485a5637.1779c8","order":2,"disp":true,"width":"4","collapse":false},{"id":"485a5637.1779c8","type":"ui_tab","name":"Pad Port 1888","icon":"dashboard","order":2,"disabled":false,"hidden":false}]
Hover
Light theme
Unfortunately there is still a small snagging list and any help would be welcome.
TODO:
(1) DONE https://discourse.nodered.org/t/pi-7-touch-problem/38840 - General Pi touch screen problem - disable copy and select.
(2) Unfilled track colour not exposed as dashboard theme variable.
This means that rgba(111,111,111,1) is a tad too dark in both
dark and light themes. An acceptable compromise for now.
(3) Thumb fails to scale on focus - transform:scale(1) !important;
(4) Cannot get thumb to sit on top of grey part of slider that represents
the unfilled length of track.
(5) Have not figured out how to push v1 with v2 and
push v2 with v1 using just CSS ?
(6) An undesirable transform flicker when v2 is hovered.
(7) Could probably use a label.
Enjoy.
Thanks to @hotNipi (1) is fixed. Here is the CSS
[{"id":"2fada998.fa3f96","type":"ui_template","z":"b7f02da3.192c","group":"bb12aba1.d14278","name":"Range CSS","order":2,"width":4,"height":1,"format":"<!--\n Range Slider\n ============\n \n Outputs {v1: value, v2: value} on mouse up.\n \n Designed with 48px x 48px dashboard grid and seems to work\n with widget heights greater than one.\n This is a discrete range slider made from two single overlapping thumb md-sliders\n The focus dividing line is on each side of the track.\n \n Untested: 90 Deg. rotation.\n \n Fits in 48px high space. \n \n TODO: \n (1) DONE https://discourse.nodered.org/t/pi-7-touch-problem/38840 - General Pi touch screen problem - disable copy and select.\n (2) Unfilled track colour not exposed as dashboard theme variable.\n This means that rgba(111,111,111,1) is a tad too dark in both \n dark and light themes. An acceptable compromise for now.\n (3) Thumb fails to scale on focus - transform:scale(1) !important;\n (4) Cannot get thumb to sit on top of grey part of slider that represents\n the unfilled length of track.\n (5) Have not figured out how to push v1 with v2 and\n push v2 with v1 unsing just CSS ?\n (6) An undesirable transform flicker when v2 is hovered.\n (7) Could probably use a label.\n Notes:\n md-invert\n\n-->\n<style>\n .nr-dashboard-template, .slider-v1{\n font-family:Liberation;\n padding: 0px;\n overflow:visible;\n -webkit-user-select: none; /* Safari */\n -ms-user-select: none; /* IE 10 and IE 11 */\n user-select: none; /* Standard syntax */\n }\n\n/* TODO` fails to stay scaled*/\n.slider-v1:focus .md-focus-ring:focus,\n.slider-v2:focus .md-focus-ring:focus {\n transform:scale(1) !important;\n}\n /* ok */\n .slider-v1:not(:focus) .md-focus-ring:hover,\n .slider-v2:not(:focus) .md-focus-ring:hover {\n transform:scale(0.8) !important;\n }\n .slider-v1 .md-focus-ring,\n .slider-v2 .md-focus-ring {\n top:14px;\n left:-10px;\n height:20px;\n width:20px;\n opacity:1;\n z-index:9998;\n background-color: var(--nr-dashboard-widgetColor) !important;\n }\n .slider-v1 .md-thumb, .slider-v2 .md-thumb,\n .slider-v1 .md-thumb:after, .slider-v2 .md-thumb:after {\n background-color: var(--nr-dashboard-widgetColor) !important;\n }\n.slider-v1 .md-sign,\n.slider-v2 .md-sign {\n height:16px !important;\n width:25px !important;\n background-color:var(--nr-dashboard-groupBackgroundColor);\n}\n/* v1 .md-sign */\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):focus .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):hover .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):active .md-sign {\n opacity:1;\n -webkit-transform: translate3d(1px, 10px, 0) scale(1) !important;\n transform: translate3d(1px, 10px, 0) scale(1) !important;\n background-color:var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):not(:hover) .md-sign,\n md-slider[md-discrete]:not(.slider-v2) .md-sign {\n/* opacity:1;*/\n -webkit-transform: translate3d(1px, 20px, 0) scale(1) !important;\n transform: translate3d(1px, 20px, 0) scale(1) !important;\n }\n/* v1 .md-sign:after */\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):focus .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):hover .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):active .md-sign:after {\n opacity:1;\n -webkit-transform: translate3d(-1px, -11px, 0) scale(1) !important;\n transform: translate3d(-1px, -11px, 0) scale(1) !important;\n border-top-color:var(--nr-dashboard-widgetColor);\n color:var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v2):not(:hover) .md-sign:after,\n md-slider[md-discrete]:not(.slider-v2) .md-sign:after {\n opacity:0;\n -webkit-transform: translate3d(-1px, -11px, 0) scale(1) !important;\n transform: translate3d(-1px, -11px, 0) scale(1) !important;\n }\n/* v2 .md-sign */\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):focus .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):hover .md-sign,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):active .md-sign {\n opacity:1;\n -webkit-transform: translate3d(1px, 55px, 0) scale(1);\n transform: translate3d(1px, 55px, 0) scale(1);\n background-color:var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):not(:hover) .md-sign,\n md-slider[md-discrete]:not(.slider-v1) .md-sign {\n/* opacity:1;*/\n -webkit-transform: translate3d(1px, 46px, 0) scale(1);\n transform: translate3d(1px, 46px, 0) scale(1);\n }\n/* v2 .md-sign:after */\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):focus .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):hover .md-sign:after,\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):active .md-sign:after {\n opacity:1;\n -webkit-transform: translate3d(-1px, -26px, 0) scale(1);\n transform: translate3d(-1px, -26px, 0) scale(1);\n border-top-color:var(--nr-dashboard-widgetColor);\n border-bottom-color:var(--nr-dashboard-widgetColor);\n border-top-width:0px;\n border-bottom-width:14px;\n border-bottom-style:solid;\n color: var(--nr-dashboard-widgetColor);\n }\n md-slider[md-discrete]:not([disabled]):not(.slider-v1):not(:hover) .md-sign:after,\n md-slider[md-discrete]:not(.slider-v1) .md-sign:after {\n opacity:0;\n -webkit-transform: translate3d(-1px, -26px, 0) scale(1);\n transform: translate3d(-1px, -26px, 0) scale(1);\n }\n /* Show sign when min value */\n .slider-v1:not(:hover) .md-sign,\n .slider-v2:not(:hover) .md-sign {\n background-color:var(--nr-dashboard-groupBackgroundColor) !important;\n opacity:1 !important;\n } \n .slider-v1 .md-thumb-text,\n .slider-v2 .md-thumb-text {\n opacity:1;\n color: var(--nr-dashboard-widgetTextColor) !important;\n }\n .slider-v1:hover .md-thumb-text,\n .slider-v2:hover .md-thumb-text {\n filter: contrast(1);\n }\n .slider-wrapper-v1{\n height: 50%;\n }\n .slider-wrapper-v2 {\n position: absolute !important;\n top:0px !important;\n height: 50%;\n }\n .slider-v2 .md-track-ticks {\n opacity:0 !important;\n }\n .slider-v1 .md-track-fill {\n z-index:9996 !important;\n background-color: var(--nr-dashboard-widgetColor) !important;\n }\n .slider-v2 .md-track-fill {\n z-index:9996 !important;\n }\n .slider-v1, .slider-v2 {\n margin: 0px;\n padding-left:10px;\n padding-right:10px;\n }\n .slider-v1 {\n top:-webkit-calc(100% - min(100%,48px));\n top:calc(100% - min(100%,48px));\n }\n .slider-v1 .md-slider-content {\n top:-webkit-calc(100% - 24px);\n top:calc(100% - 24px);\n }\n .slider-v2 .md-slider-content {\n top: -24px;\n }\n \n .slider-v2 .md-track {\n background-color:rgba(111,111,111,1) !important;\n }\n</style>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":150,"y":60,"wires":[[]]},{"id":"bb12aba1.d14278","type":"ui_group","name":"ui_template range slider","tab":"485a5637.1779c8","order":2,"disp":true,"width":"4","collapse":false},{"id":"485a5637.1779c8","type":"ui_tab","name":"Pad Port 1999","icon":"dashboard","order":2,"disabled":false,"hidden":false}]