From 470b4472c63f444851c2bc5b7e6cf838103a621a Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Mon, 19 Feb 2018 14:40:59 -0800 Subject: [PATCH] Custom range input (#25600) * added the styling * added the documentation * update for one rule per line * fix hound error: trailing whitespace * trimmed off vendor prefixes * Add note about track and thumb * Psuedo-elements must be split across multiple rulesets to have an affect * Fix firefox inner focus * Seems that FF is the only one affected by this * Add support for gradients * Add labels, clarify min/max changes * add step example * add custom range vars --- docs/4.0/components/forms.md | 23 +++++++ scss/_custom-forms.scss | 123 +++++++++++++++++++++++++++++++++++ scss/_variables.scss | 16 +++++ 3 files changed, 162 insertions(+) diff --git a/docs/4.0/components/forms.md b/docs/4.0/components/forms.md index 07063854d5..8bf61de35d 100644 --- a/docs/4.0/components/forms.md +++ b/docs/4.0/components/forms.md @@ -1172,6 +1172,29 @@ As is the `size` attribute: {% endexample %} +### Range + +Create custom `` controls with `.custom-range`. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only IE and Firefox support "filling" their track from the left or right of the thumb as a means to visually indicate progress, we do not currently support it. + +{% example html %} + + +{% endexample %} + +Range inputs have implicit values for `min` and `max`—`0` and `100`, respectively. You may specify new values for those using the `min` and `max` attributes. + +{% example html %} + + +{% endexample %} + +By default, range inputs "snap" to integer values. To change this, you can specify a `step` value. In the example below, we double the number of steps by using `step="0.5"`. + +{% example html %} + + +{% endexample %} + ### File browser The file input is the most gnarly of the bunch and requires additional JavaScript if you'd like to hook them up with functional *Choose file...* and selected file name text. diff --git a/scss/_custom-forms.scss b/scss/_custom-forms.scss index 2d83f7ea68..27de8769a4 100644 --- a/scss/_custom-forms.scss +++ b/scss/_custom-forms.scss @@ -295,3 +295,126 @@ @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0); } } + +// Range +// +// Style range inputs the same across browsers. Vendor-specific rules for psuedo +// elements cannot be mixed. As such, there are no shared styles for focus or +// active states on prefixed selectors. + +.custom-range { + width: 100%; + padding-left: 0; // Firefox specific + background-color: transparent; + appearance: none; + + &:focus { + outline: none; + } + + &::-moz-focus-outer { + border: 0; + } + + &::-webkit-slider-thumb { + width: $custom-range-thumb-width; + height: $custom-range-thumb-height; + margin-top: -($custom-range-thumb-width * .25); // Webkit specific? + @include gradient-bg($custom-range-thumb-bg); + border: $custom-range-thumb-border; + @include border-radius($custom-range-thumb-border-radius); + @include box-shadow($custom-range-thumb-box-shadow); + appearance: none; + + &:focus { + outline: none; + box-shadow: $custom-range-thumb-focus-box-shadow; // No mixin for focus accessibility + } + + &:active { + @include gradient-bg($custom-range-thumb-active-bg); + } + } + + &::-webkit-slider-runnable-track { + width: $custom-range-track-width; + height: $custom-range-track-height; + color: transparent; // Why? + cursor: $custom-range-track-cursor; + background-color: $custom-range-track-bg; + border-color: transparent; + @include border-radius($custom-range-track-border-radius); + @include box-shadow($custom-range-track-box-shadow); + } + + &::-moz-range-thumb { + width: $custom-range-thumb-width; + height: $custom-range-thumb-height; + @include gradient-bg($custom-range-thumb-bg); + border: $custom-range-thumb-border; + @include border-radius($custom-range-thumb-border-radius); + @include box-shadow($custom-range-thumb-box-shadow); + appearance: none; + + &:focus { + outline: none; + box-shadow: $custom-range-thumb-focus-box-shadow; // No mixin for focus accessibility + } + + &:active { + @include gradient-bg($custom-range-thumb-active-bg); + } + } + + &::-moz-range-track { + width: $custom-range-track-width; + height: $custom-range-track-height; + color: transparent; + cursor: $custom-range-track-cursor; + background-color: $custom-range-track-bg; + border-color: transparent; // Firefox specific? + @include border-radius($custom-range-track-border-radius); + @include box-shadow($custom-range-track-box-shadow); + } + + &::-ms-thumb { + width: $custom-range-thumb-width; + height: $custom-range-thumb-height; + @include gradient-bg($custom-range-thumb-bg); + border: $custom-range-thumb-border; + @include border-radius($custom-range-thumb-border-radius); + @include box-shadow($custom-range-thumb-box-shadow); + appearance: none; + + &:focus { + outline: none; + box-shadow: $custom-range-thumb-focus-box-shadow; // No mixin for focus accessibility + } + + &:active { + @include gradient-bg($custom-range-thumb-active-bg); + } + } + + &::-ms-track { + width: $custom-range-track-width; + height: $custom-range-track-height; + color: transparent; + cursor: $custom-range-track-cursor; + background-color: transparent; + border-color: transparent; + border-width: ($custom-range-thumb-height * .5); + @include box-shadow($custom-range-track-box-shadow); + } + + &::-ms-fill-lower { + background-color: $custom-range-track-bg; + @include border-radius($custom-range-track-border-radius); + } + + &::-ms-fill-upper { + margin-right: 15px; // arbitrary? + background-color: $custom-range-track-bg; + @include border-radius($custom-range-track-border-radius); + } +} diff --git a/scss/_variables.scss b/scss/_variables.scss index 53cb29c2af..0a34e6c674 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -504,6 +504,22 @@ $custom-select-height-sm: $input-height-sm !default; $custom-select-font-size-lg: 125% !default; $custom-select-height-lg: $input-height-lg !default; +$custom-range-track-width: 100% !default; +$custom-range-track-height: .5rem !default; +$custom-range-track-cursor: pointer !default; +$custom-range-track-bg: $gray-300 !default; +$custom-range-track-border-radius: 1rem !default; +$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default; + +$custom-range-thumb-width: 1rem !default; +$custom-range-thumb-height: $custom-range-thumb-width !default; +$custom-range-thumb-bg: $component-active-bg !default; +$custom-range-thumb-border: 0 !default; +$custom-range-thumb-border-radius: 1rem !default; +$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default; +$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-btn-focus-box-shadow !default; +$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default; + $custom-file-height: $input-height !default; $custom-file-focus-border-color: $input-focus-border-color !default; $custom-file-focus-box-shadow: $input-btn-focus-box-shadow !default;