From 1e004ff6b726af21eec90f743fac15beaffda1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Nuno=20Mota?= Date: Thu, 7 May 2020 21:10:43 +0100 Subject: [PATCH] Add slider (#78) * Add section in docs * Hide range input on all browsers Displays indicator as radio outline on Windows 10 Firefox 75 * Add svg icons * Add thumb styling on range input * Add track to range input * Add indicator css for has-recatangular-indicator * Update styling and labels for range input * Update example for simple range input * Remove repeated code * Remove unused icon and add vertical input style * Refactor styling and adapt description to fit * Add style for all vertical lengths and update docs * Correct 2x to 2px --- docs/index.html.ejs | 48 +++++++++ icon/indicator-horizontal.svg | 6 ++ icon/indicator-rectangle-horizontal.svg | 6 ++ style.css | 136 ++++++++++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 icon/indicator-horizontal.svg create mode 100644 icon/indicator-rectangle-horizontal.svg diff --git a/docs/index.html.ejs b/docs/index.html.ejs index 3a0b357..b9b7428 100644 --- a/docs/index.html.ejs +++ b/docs/index.html.ejs @@ -30,6 +30,7 @@
  • OptionButton
  • GroupBox
  • TextBox
  • +
  • Slider
  • Dropdown
  • Window @@ -390,6 +391,53 @@ +
    +

    Slider

    +
    +
    + A slider, sometimes called a trackbar control, consists of a bar that + defines the extent or range of the adjustment and an indicator that + shows the current value for the control... + +
    — Microsoft Windows User Experience p. 146
    +
    + +

    + Sliders can rendered by specifying a range type on an + input element. +

    + + <%- example(` +
    + + + + +
    + `) %> + +

    + You can make use of the has-box-indicator class replace the + default indicator with a box indicator, furthermore the slider can be wrapped + with a div using is-vertical to display the input vertically. +

    + +

    + Note: To change the length of a vertical slider, the input width + and div height. +

    + + <%- example(` +
    + +
    + +
    +
    + `) %> +
    +
    +
    diff --git a/icon/indicator-horizontal.svg b/icon/indicator-horizontal.svg new file mode 100644 index 0000000..f6db8b0 --- /dev/null +++ b/icon/indicator-horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/icon/indicator-rectangle-horizontal.svg b/icon/indicator-rectangle-horizontal.svg new file mode 100644 index 0000000..7d0d9b1 --- /dev/null +++ b/icon/indicator-rectangle-horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/style.css b/style.css index 12e124d..26ac2c6 100644 --- a/style.css +++ b/style.css @@ -22,6 +22,8 @@ --radio-width: 12px; --checkbox-width: 13px; --radio-label-spacing: 6px; + --range-track-height: 4px; + --range-spacing: 10px; /* Some detailed computations for radio buttons and checkboxes */ --radio-total-width-precalc: var(--radio-width) + var(--radio-label-spacing); @@ -429,6 +431,140 @@ textarea:focus { outline: none; } +input[type=range] { + -webkit-appearance: none; + width: 100%; + background: transparent; +} + +input[type=range]:focus { + outline: none; +} + +input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 21px; + width: 11px; + background: svg-load("./icon/indicator-horizontal.svg"); + transform: translateY(-8px); +} + +input[type=range].has-box-indicator::-webkit-slider-thumb { + background: svg-load("./icon/indicator-rectangle-horizontal.svg"); + transform: translateY(-10px); +} + +input[type=range]::-moz-range-thumb { + height: 21px; + width: 11px; + border: 0; + border-radius: 0; + background: svg-load("./icon/indicator-horizontal.svg"); + transform: translateY(2px); +} + +input[type=range].has-box-indicator::-moz-range-thumb { + background: svg-load("./icon/indicator-rectangle-horizontal.svg"); + transform: translateY(0px); +} + +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 2px; + box-sizing: border-box; + background: black; + border-right: 1px solid grey; + border-bottom: 1px solid grey; + box-shadow: + 1px 0 0 white, + 1px 1px 0 white, + 0 1px 0 white, + -1px 0 0 darkgrey, + -1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + -1px 1px 0 white, + 1px -1px darkgrey; +} + +input[type=range]::-moz-range-track { + width: 100%; + height: 2px; + box-sizing: border-box; + background: black; + border-right: 1px solid grey; + border-bottom: 1px solid grey; + box-shadow: + 1px 0 0 white, + 1px 1px 0 white, + 0 1px 0 white, + -1px 0 0 darkgrey, + -1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + -1px 1px 0 white, + 1px -1px darkgrey; +} + +.is-vertical { + display: inline-block; + width: 4px; + height: 150px; + transform: translateY(50%) ; +} + +.is-vertical > input[type=range] { + width: 150px; + height: 4px; + margin: 0 calc(var(--grouped-element-spacing) + var(--range-spacing)) 0 var(--range-spacing); + transform-origin: left; + transform: rotate(270deg) translateX(calc(-50% + var(--element-spacing))) ; +} + +.is-vertical > input[type=range]::-webkit-slider-runnable-track { + border-left: 1px solid grey; + border-right: 0; + border-bottom: 1px solid grey; + box-shadow: + -1px 0 0 white, + -1px 1px 0 white, + 0 1px 0 white, + 1px 0 0 darkgrey, + 1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + 1px 1px 0 white, + -1px -1px darkgrey; +} + +.is-vertical > input[type=range]::-moz-range-track { + border-left: 1px solid grey; + border-right: 0; + border-bottom: 1px solid grey; + box-shadow: + -1px 0 0 white, + -1px 1px 0 white, + 0 1px 0 white, + 1px 0 0 darkgrey, + 1px -1px 0 darkgrey, + 0 -1px 0 darkgrey, + 1px 1px 0 white, + -1px -1px darkgrey; +} + +.is-vertical > input[type=range]::-webkit-slider-thumb { + transform: translateY(-8px) scaleX(-1); +} + +.is-vertical > input[type=range].has-box-indicator::-webkit-slider-thumb { + transform: translateY(-10px) scaleX(-1); +} + +.is-vertical > input[type=range]::-moz-range-thumb { + transform: translateY(2px) scaleX(-1); +} + +.is-vertical > input[type=range].has-box-indicator::-moz-range-thumb { + transform: translateY(0px) scaleX(-1); +} + select:focus { color: var(--button-highlight); background-color: var(--dialog-blue);