| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528 |
- // Embedded icons from Open Iconic.
- // Released under MIT and copyright 2014 Waybury.
- // https://useiconic.com/open
- // Checkboxes and radios
- //
- // Base class takes care of all the key behavioral aspects.
- .custom-control {
- position: relative;
- z-index: 1;
- display: block;
- min-height: (@font-size-base * @line-height-base);
- padding-left: (@custom-control-gutter + @custom-control-indicator-size);
- color-adjust: exact; // Keep themed appearance for print
- }
- .custom-control-inline {
- display: inline-flex;
- margin-right: @custom-control-spacer-x;
- }
- .custom-control-input {
- position: absolute;
- left: 0;
- z-index: -1; // Put the input behind the label so it doesn't overlay text
- width: @custom-control-indicator-size;
- height: ((@font-size-base * @line-height-base + @custom-control-indicator-size) / 2);
- opacity: 0;
- &:checked ~ .custom-control-label::before {
- color: @custom-control-indicator-checked-color;
- border-color: @custom-control-indicator-checked-border-color;
- #gradient-bg(@custom-control-indicator-checked-bg);
- #box-shadow(@custom-control-indicator-checked-box-shadow);
- }
- &:focus ~ .custom-control-label::before {
- // the mixin is not used here to make sure there is feedback
- & when (@enable-shadows) {
- box-shadow: @input-box-shadow, @custom-control-indicator-focus-box-shadow;
- }
- & when not (@enable-shadows) {
- box-shadow: @custom-control-indicator-focus-box-shadow;
- }
- }
- &:focus:not(:checked) ~ .custom-control-label::before {
- border-color: @custom-control-indicator-focus-border-color;
- }
- &:not(:disabled):active ~ .custom-control-label::before {
- color: @custom-control-indicator-active-color;
- background-color: @custom-control-indicator-active-bg;
- border-color: @custom-control-indicator-active-border-color;
- #box-shadow(@custom-control-indicator-active-box-shadow);
- }
- // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
- &[disabled],
- &:disabled {
- ~ .custom-control-label {
- color: @custom-control-label-disabled-color;
- &::before {
- background-color: @custom-control-indicator-disabled-bg;
- }
- }
- }
- }
- // Custom control indicators
- //
- // Build the custom controls out of pseudo-elements.
- .custom-control-label {
- position: relative;
- margin-bottom: 0;
- // LESS PORT: Less doesn’t strip “empty” property values so we have to check for a value first.
- & when not (@custom-control-label-color = ~"") { color: @custom-control-label-color; }
- vertical-align: top;
- // LESS PORT: Less doesn’t strip “empty” property values so we have to check for a value first.
- & when not (@custom-control-cursor = ~"") { cursor: @custom-control-cursor; }
- // Background-color and (when enabled) gradient
- &::before {
- position: absolute;
- top: ((@font-size-base * @line-height-base - @custom-control-indicator-size) / 2);
- left: -(@custom-control-gutter + @custom-control-indicator-size);
- display: block;
- width: @custom-control-indicator-size;
- height: @custom-control-indicator-size;
- pointer-events: none;
- content: "";
- background-color: @custom-control-indicator-bg;
- border: @custom-control-indicator-border-color solid @custom-control-indicator-border-width;
- #box-shadow(@custom-control-indicator-box-shadow);
- }
- // Foreground (icon)
- &::after {
- position: absolute;
- top: ((@font-size-base * @line-height-base - @custom-control-indicator-size) / 2);
- left: -(@custom-control-gutter + @custom-control-indicator-size);
- display: block;
- width: @custom-control-indicator-size;
- height: @custom-control-indicator-size;
- content: "";
- background: no-repeat 50% ~"/" @custom-control-indicator-bg-size;
- }
- }
- // Checkboxes
- //
- // Tweak just a few things for checkboxes.
- .custom-checkbox {
- .custom-control-label::before {
- #border-radius(@custom-checkbox-indicator-border-radius);
- }
- .custom-control-input:checked ~ .custom-control-label {
- &::after {
- background-image: escape-svg(@custom-checkbox-indicator-icon-checked);
- }
- }
- .custom-control-input:indeterminate ~ .custom-control-label {
- &::before {
- border-color: @custom-checkbox-indicator-indeterminate-border-color;
- #gradient-bg(@custom-checkbox-indicator-indeterminate-bg);
- #box-shadow(@custom-checkbox-indicator-indeterminate-box-shadow);
- }
- &::after {
- background-image: escape-svg(@custom-checkbox-indicator-icon-indeterminate);
- }
- }
- .custom-control-input:disabled {
- &:checked ~ .custom-control-label::before {
- #gradient-bg(@custom-control-indicator-checked-disabled-bg);
- }
- &:indeterminate ~ .custom-control-label::before {
- #gradient-bg(@custom-control-indicator-checked-disabled-bg);
- }
- }
- }
- // Radios
- //
- // Tweak just a few things for radios.
- .custom-radio {
- .custom-control-label::before {
- border-radius: @custom-radio-indicator-border-radius;
- }
- .custom-control-input:checked ~ .custom-control-label {
- &::after {
- background-image: escape-svg(@custom-radio-indicator-icon-checked);
- }
- }
- .custom-control-input:disabled {
- &:checked ~ .custom-control-label::before {
- #gradient-bg(@custom-control-indicator-checked-disabled-bg);
- }
- }
- }
- // switches
- //
- // Tweak a few things for switches
- .custom-switch {
- padding-left: (@custom-switch-width + @custom-control-gutter);
- .custom-control-label {
- &::before {
- left: -(@custom-switch-width + @custom-control-gutter);
- width: @custom-switch-width;
- pointer-events: all;
- border-radius: @custom-switch-indicator-border-radius;
- }
- &::after {
- // LESS PORT: Using format strings here so we can put computed values in the `calc()`.
- top: add(((@font-size-base * @line-height-base - @custom-control-indicator-size) / 2), (@custom-control-indicator-border-width * 2));
- left: add(-(@custom-switch-width + @custom-control-gutter), (@custom-control-indicator-border-width * 2));
- width: @custom-switch-indicator-size;
- height: @custom-switch-indicator-size;
- background-color: @custom-control-indicator-border-color;
- border-radius: @custom-switch-indicator-border-radius;
- #transition(transform 0.15s ease-in-out, @custom-forms-transition);
- }
- }
- .custom-control-input:checked ~ .custom-control-label {
- &::after {
- background-color: @custom-control-indicator-bg;
- transform: translateX((@custom-switch-width - @custom-control-indicator-size));
- }
- }
- .custom-control-input:disabled {
- &:checked ~ .custom-control-label::before {
- #gradient-bg(@custom-control-indicator-checked-disabled-bg);
- }
- }
- }
- // Select
- //
- // Replaces the browser default select with a custom one, mostly pulled from
- // https://primer.github.io/.
- //
- .custom-select {
- display: inline-block;
- width: 100%;
- height: @custom-select-height;
- padding: @custom-select-padding-y (@custom-select-padding-x + @custom-select-indicator-padding) @custom-select-padding-y @custom-select-padding-x;
- // LESS PORT: Less doesn’t strip “empty” property values so we have to check for a value first.
- & when not (@custom-select-font-family = ~"") { font-family: @custom-select-font-family; }
- #font-size(@custom-select-font-size);
- font-weight: @custom-select-font-weight;
- line-height: @custom-select-line-height;
- color: @custom-select-color;
- vertical-align: middle;
- background: @custom-select-bg @custom-select-background;
- border: @custom-select-border-width solid @custom-select-border-color;
- #border-radius(@custom-select-border-radius, 0);
- #box-shadow(@custom-select-box-shadow);
- appearance: none;
- &:focus {
- border-color: @custom-select-focus-border-color;
- outline: 0;
- & when (@enable-shadows) {
- #box-shadow(@custom-select-box-shadow, @custom-select-focus-box-shadow);
- }
- & when not (@enable-shadows) {
- // Avoid using mixin so we can pass custom focus shadow properly
- box-shadow: @custom-select-focus-box-shadow;
- }
- &::-ms-value {
- // For visual consistency with other platforms/browsers,
- // suppress the default white text on blue background highlight given to
- // the selected option text when the (still closed) <select> receives focus
- // in IE and (under certain conditions) Edge.
- // See https://github.com/twbs/bootstrap/issues/19398.
- color: @input-color;
- background-color: @input-bg;
- }
- }
- &[multiple],
- &[size]:not([size="1"]) {
- height: auto;
- padding-right: @custom-select-padding-x;
- background-image: none;
- }
- &:disabled {
- color: @custom-select-disabled-color;
- background-color: @custom-select-disabled-bg;
- }
- // Hides the default caret in IE11
- &::-ms-expand {
- display: none;
- }
- // Remove outline from select box in FF
- &:-moz-focusring {
- color: transparent;
- text-shadow: 0 0 0 @custom-select-color;
- }
- }
- .custom-select-sm {
- height: @custom-select-height-sm;
- padding-top: @custom-select-padding-y-sm;
- padding-bottom: @custom-select-padding-y-sm;
- padding-left: @custom-select-padding-x-sm;
- #font-size(@custom-select-font-size-sm);
- }
- .custom-select-lg {
- height: @custom-select-height-lg;
- padding-top: @custom-select-padding-y-lg;
- padding-bottom: @custom-select-padding-y-lg;
- padding-left: @custom-select-padding-x-lg;
- #font-size(@custom-select-font-size-lg);
- }
- // File
- //
- // Custom file input.
- .custom-file {
- position: relative;
- display: inline-block;
- width: 100%;
- height: @custom-file-height;
- margin-bottom: 0;
- }
- .custom-file-input {
- position: relative;
- z-index: 2;
- width: 100%;
- height: @custom-file-height;
- margin: 0;
- opacity: 0;
- &:focus ~ .custom-file-label {
- border-color: @custom-file-focus-border-color;
- box-shadow: @custom-file-focus-box-shadow;
- }
- // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
- &[disabled] ~ .custom-file-label,
- &:disabled ~ .custom-file-label {
- background-color: @custom-file-disabled-bg;
- }
- each(@custom-file-text, #(@value, @lang) {
- &:lang(@{lang}) ~ .custom-file-label::after {
- content: @value;
- }
- });
- ~ .custom-file-label[data-browse]::after {
- content: attr(data-browse);
- }
- }
- .custom-file-label {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- z-index: 1;
- height: @custom-file-height;
- padding: @custom-file-padding-y @custom-file-padding-x;
- // LESS PORT: Less doesn’t strip “empty” property values so we have to check for a value first.
- & when not (@custom-file-font-family = ~"") { font-family: @custom-file-font-family; }
- font-weight: @custom-file-font-weight;
- line-height: @custom-file-line-height;
- color: @custom-file-color;
- background-color: @custom-file-bg;
- border: @custom-file-border-width solid @custom-file-border-color;
- #border-radius(@custom-file-border-radius);
- #box-shadow(@custom-file-box-shadow);
- &::after {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- z-index: 3;
- display: block;
- height: @custom-file-height-inner;
- padding: @custom-file-padding-y @custom-file-padding-x;
- line-height: @custom-file-line-height;
- color: @custom-file-button-color;
- content: "Browse";
- #gradient-bg(@custom-file-button-bg);
- border-left: inherit;
- #border-radius(0 @custom-file-border-radius @custom-file-border-radius 0);
- }
- }
- // Range
- //
- // Style range inputs the same across browsers. Vendor-specific rules for pseudo
- // elements cannot be mixed. As such, there are no shared styles for focus or
- // active states on prefixed selectors.
- .custom-range {
- width: 100%;
- height: add(@custom-range-thumb-height, (@custom-range-thumb-focus-box-shadow-width * 2));
- padding: 0; // Need to reset padding
- background-color: transparent;
- appearance: none;
- &:focus {
- outline: none;
- // Pseudo-elements must be split across multiple rulesets to have an effect.
- // No box-shadow() mixin for focus accessibility.
- &::-webkit-slider-thumb { box-shadow: @custom-range-thumb-focus-box-shadow; }
- &::-moz-range-thumb { box-shadow: @custom-range-thumb-focus-box-shadow; }
- &::-ms-thumb { box-shadow: @custom-range-thumb-focus-box-shadow; }
- }
- &::-moz-focus-outer {
- border: 0;
- }
- &::-webkit-slider-thumb {
- width: @custom-range-thumb-width;
- height: @custom-range-thumb-height;
- margin-top: ((@custom-range-track-height - @custom-range-thumb-height) / 2); // Webkit specific
- #gradient-bg(@custom-range-thumb-bg);
- border: @custom-range-thumb-border;
- #border-radius(@custom-range-thumb-border-radius);
- #box-shadow(@custom-range-thumb-box-shadow);
- #transition(@custom-forms-transition);
- appearance: none;
- &:active {
- #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;
- #border-radius(@custom-range-track-border-radius);
- #box-shadow(@custom-range-track-box-shadow);
- }
- &::-moz-range-thumb {
- width: @custom-range-thumb-width;
- height: @custom-range-thumb-height;
- #gradient-bg(@custom-range-thumb-bg);
- border: @custom-range-thumb-border;
- #border-radius(@custom-range-thumb-border-radius);
- #box-shadow(@custom-range-thumb-box-shadow);
- #transition(@custom-forms-transition);
- appearance: none;
- &:active {
- #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?
- #border-radius(@custom-range-track-border-radius);
- #box-shadow(@custom-range-track-box-shadow);
- }
- &::-ms-thumb {
- width: @custom-range-thumb-width;
- height: @custom-range-thumb-height;
- margin-top: 0; // Edge specific
- margin-right: @custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
- margin-left: @custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
- #gradient-bg(@custom-range-thumb-bg);
- border: @custom-range-thumb-border;
- #border-radius(@custom-range-thumb-border-radius);
- #box-shadow(@custom-range-thumb-box-shadow);
- #transition(@custom-forms-transition);
- appearance: none;
- &:active {
- #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 / 2);
- #box-shadow(@custom-range-track-box-shadow);
- }
- &::-ms-fill-lower {
- background-color: @custom-range-track-bg;
- #border-radius(@custom-range-track-border-radius);
- }
- &::-ms-fill-upper {
- margin-right: 15px; // arbitrary?
- background-color: @custom-range-track-bg;
- #border-radius(@custom-range-track-border-radius);
- }
- &:disabled {
- &::-webkit-slider-thumb {
- background-color: @custom-range-thumb-disabled-bg;
- }
- &::-webkit-slider-runnable-track {
- cursor: default;
- }
- &::-moz-range-thumb {
- background-color: @custom-range-thumb-disabled-bg;
- }
- &::-moz-range-track {
- cursor: default;
- }
- &::-ms-thumb {
- background-color: @custom-range-thumb-disabled-bg;
- }
- }
- }
- .custom-control-label::before,
- .custom-file-label,
- .custom-select {
- #transition(@custom-forms-transition);
- }
|