diff --git a/scss/_custom-forms.scss b/scss/_custom-forms.scss deleted file mode 100644 index ce49f3060aff..000000000000 --- a/scss/_custom-forms.scss +++ /dev/null @@ -1,514 +0,0 @@ -// 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; - display: block; - min-height: $font-size-base * $line-height-base; - padding-left: $custom-control-gutter + $custom-control-indicator-size; -} - -.custom-control-inline { - display: inline-flex; - margin-right: $custom-control-spacer-x; -} - -.custom-control-input { - position: absolute; - z-index: -1; // Put the input behind the label so it doesn't overlay text - opacity: 0; - - &:checked ~ .custom-control-label::before { - color: $custom-control-indicator-checked-color; - border-color: $custom-control-indicator-checked-border-color; - @include gradient-bg($custom-control-indicator-checked-bg); - @include 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 - @if $enable-shadows { - box-shadow: $input-box-shadow, $input-focus-box-shadow; - } @else { - 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; - @include box-shadow($custom-control-indicator-active-box-shadow); - } - - // Use disabled attribute instead of :disabled pseudo-class - // Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231 - &[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; - color: $custom-control-label-color; - vertical-align: top; - - // 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; - @include 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 { - @include border-radius($custom-checkbox-indicator-border-radius); - } - - .custom-control-input:checked ~ .custom-control-label { - &::after { - background-image: $custom-checkbox-indicator-icon-checked; - } - } - - .custom-control-input:indeterminate ~ .custom-control-label { - &::before { - border-color: $custom-checkbox-indicator-indeterminate-border-color; - @include gradient-bg($custom-checkbox-indicator-indeterminate-bg); - @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow); - } - &::after { - background-image: $custom-checkbox-indicator-icon-indeterminate; - } - } - - .custom-control-input:disabled { - &:checked ~ .custom-control-label::before { - background-color: $custom-control-indicator-checked-disabled-bg; - } - &:indeterminate ~ .custom-control-label::before { - background-color: $custom-control-indicator-checked-disabled-bg; - } - } -} - -// Radios -// -// Tweak just a few things for radios. - -.custom-radio { - .custom-control-label::before { - // stylelint-disable-next-line property-blacklist - border-radius: $custom-radio-indicator-border-radius; - } - - .custom-control-input:checked ~ .custom-control-label { - &::after { - background-image: $custom-radio-indicator-icon-checked; - } - } - - .custom-control-input:disabled { - &:checked ~ .custom-control-label::before { - background-color: $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; - // stylelint-disable-next-line property-blacklist - border-radius: $custom-switch-indicator-border-radius; - } - - &::after { - top: calc(#{(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2)} + #{$custom-control-indicator-border-width * 2}); - left: calc(#{-($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; - // stylelint-disable-next-line property-blacklist - border-radius: $custom-switch-indicator-border-radius; - @include transition(transform .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 { - background-color: $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; - font-family: $custom-select-font-family; - @include 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-background; - background-color: $custom-select-bg; - border: $custom-select-border-width solid $custom-select-border-color; - @include border-radius($custom-select-border-radius, 0); - @include box-shadow($custom-select-box-shadow); - appearance: none; - - &:focus { - border-color: $custom-select-focus-border-color; - outline: 0; - @if $enable-shadows { - box-shadow: $custom-select-box-shadow, $custom-select-focus-box-shadow; - } @else { - 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) s in some browsers, due to the limited stylability of ``s in IE10+. - &::-ms-expand { - background-color: transparent; - border: 0; - } - - // Customize the `:focus` state to imitate native WebKit styles. - @include form-control-focus($ignore-warning: true); - - // Placeholder - &::placeholder { - color: $input-placeholder-color; - // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526. - opacity: 1; - } - - // Disabled and read-only inputs - // - // HTML5 says that controls under a fieldset > legend:first-child won't be - // disabled if the fieldset is disabled. Due to implementation difficulty, we - // don't honor that edge case; we style them as disabled anyway. - &:disabled, - &[readonly] { - background-color: $input-disabled-bg; - // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655. - opacity: 1; - } -} - -select.form-control { - &:focus::-ms-value { - // Suppress the nested default white text on blue background highlight given to - // the selected option text when the (still closed) s in some browsers, due to the limited stylability of ``s in IE10+. + &::-ms-expand { + background-color: transparent; + border: 0; + } + + // Customize the `:focus` state to imitate native WebKit styles. + &:focus { + color: $input-focus-color; + background-color: $input-focus-bg; + border-color: $input-focus-border-color; + outline: 0; + // Avoid using mixin so we can pass custom focus shadow properly + @if $enable-shadows { + box-shadow: $input-box-shadow, $input-focus-box-shadow; + } @else { + box-shadow: $input-focus-box-shadow; + } + } + + // Placeholder + &::placeholder { + color: $input-placeholder-color; + // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526. + opacity: 1; + } + + // Disabled and read-only inputs + // + // HTML5 says that controls under a fieldset > legend:first-child won't be + // disabled if the fieldset is disabled. Due to implementation difficulty, we + // don't honor that edge case; we style them as disabled anyway. + &:disabled, + &[readonly] { + background-color: $input-disabled-bg; + // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655. + opacity: 1; + } +} + +// Readonly controls as plain text +// +// Apply class to a readonly input to make it appear like regular plain +// text (without any border, background color, focus indicator) + +.form-control-plaintext { + display: block; + width: 100%; + padding: $input-padding-y 0; + margin-bottom: 0; // match inputs if this class comes on inputs with default margins + line-height: $input-line-height; + color: $input-plaintext-color; + background-color: transparent; + border: solid transparent; + border-width: $input-border-width 0; + + &.form-control-sm, + &.form-control-lg { + padding-right: 0; + padding-left: 0; + } +} + +// Form control sizing +// +// Build on `.form-control` with modifier classes to decrease or increase the +// height and font-size of form controls. +// +// Repeated in `_input_group.scss` to avoid Sass extend issues. + +.form-control-sm { + height: $input-height-sm; + padding: $input-padding-y-sm $input-padding-x-sm; + @include font-size($input-font-size-sm); + line-height: $input-line-height-sm; + @include border-radius($input-border-radius-sm); +} + +.form-control-lg { + height: $input-height-lg; + padding: $input-padding-y-lg $input-padding-x-lg; + @include font-size($input-font-size-lg); + line-height: $input-line-height-lg; + @include border-radius($input-border-radius-lg); +} + +textarea.form-control { + height: auto; +} diff --git a/scss/forms/_form-file.scss b/scss/forms/_form-file.scss new file mode 100644 index 000000000000..bbc38a9f81e8 --- /dev/null +++ b/scss/forms/_form-file.scss @@ -0,0 +1,72 @@ +.form-file { + position: relative; + display: inline-block; + width: 100%; + height: $form-file-height; + margin-bottom: 0; +} + +.form-file-input { + position: relative; + z-index: 2; + width: 100%; + height: $form-file-height; + margin: 0; + opacity: 0; + + &:focus ~ .form-file-label { + border-color: $form-file-focus-border-color; + box-shadow: $form-file-focus-box-shadow; + } + + // Use disabled attribute instead of :disabled pseudo-class + // Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231 + &[disabled] ~ .form-file-label { + background-color: $form-file-disabled-bg; + } +} + +.form-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + display: flex; + height: $form-file-height; + border-color: $form-file-border-color; + @include border-radius($form-file-border-radius); + @include box-shadow($form-file-box-shadow); +} + +.form-file-text { + display: block; + flex-grow: 1; + padding: $form-file-padding-y $form-file-padding-x; + overflow: hidden; + font-family: $form-file-font-family; + font-weight: $form-file-font-weight; + line-height: $form-file-line-height; + color: $form-file-color; + text-overflow: ellipsis; + white-space: nowrap; + background-color: $form-file-bg; + border-color: inherit; + border-style: solid; + border-width: $form-file-border-width; + @include border-left-radius(inherit); +} + +.form-file-button { + display: block; + flex-shrink: 0; + padding: $form-file-padding-y $form-file-padding-x; + margin-left: -$form-file-border-width; + line-height: $form-file-line-height; + color: $form-file-button-color; + @include gradient-bg($form-file-button-bg); + border-color: inherit; + border-style: solid; + border-width: $form-file-border-width; + @include border-right-radius(inherit); +} diff --git a/scss/forms/_form-range.scss b/scss/forms/_form-range.scss new file mode 100644 index 000000000000..b54d4d6aafbd --- /dev/null +++ b/scss/forms/_form-range.scss @@ -0,0 +1,142 @@ +// 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. + +.form-range { + width: 100%; + height: calc(#{$form-range-thumb-height} + #{$form-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: $form-range-thumb-focus-box-shadow; } + &::-moz-range-thumb { box-shadow: $form-range-thumb-focus-box-shadow; } + &::-ms-thumb { box-shadow: $form-range-thumb-focus-box-shadow; } + } + + &::-moz-focus-outer { + border: 0; + } + + &::-webkit-slider-thumb { + width: $form-range-thumb-width; + height: $form-range-thumb-height; + margin-top: ($form-range-track-height - $form-range-thumb-height) / 2; // Webkit specific + @include gradient-bg($form-range-thumb-bg); + border: $form-range-thumb-border; + @include border-radius($form-range-thumb-border-radius); + @include box-shadow($form-range-thumb-box-shadow); + @include transition($custom-forms-transition); + appearance: none; + + &:active { + @include gradient-bg($form-range-thumb-active-bg); + } + } + + &::-webkit-slider-runnable-track { + width: $form-range-track-width; + height: $form-range-track-height; + color: transparent; // Why? + cursor: $form-range-track-cursor; + background-color: $form-range-track-bg; + border-color: transparent; + @include border-radius($form-range-track-border-radius); + @include box-shadow($form-range-track-box-shadow); + } + + &::-moz-range-thumb { + width: $form-range-thumb-width; + height: $form-range-thumb-height; + @include gradient-bg($form-range-thumb-bg); + border: $form-range-thumb-border; + @include border-radius($form-range-thumb-border-radius); + @include box-shadow($form-range-thumb-box-shadow); + @include transition($custom-forms-transition); + appearance: none; + + &:active { + @include gradient-bg($form-range-thumb-active-bg); + } + } + + &::-moz-range-track { + width: $form-range-track-width; + height: $form-range-track-height; + color: transparent; + cursor: $form-range-track-cursor; + background-color: $form-range-track-bg; + border-color: transparent; // Firefox specific? + @include border-radius($form-range-track-border-radius); + @include box-shadow($form-range-track-box-shadow); + } + + &::-ms-thumb { + width: $form-range-thumb-width; + height: $form-range-thumb-height; + margin-top: 0; // Edge specific + margin-right: $form-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden. + margin-left: $form-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden. + @include gradient-bg($form-range-thumb-bg); + border: $form-range-thumb-border; + @include border-radius($form-range-thumb-border-radius); + @include box-shadow($form-range-thumb-box-shadow); + @include transition($custom-forms-transition); + appearance: none; + + &:active { + @include gradient-bg($form-range-thumb-active-bg); + } + } + + &::-ms-track { + width: $form-range-track-width; + height: $form-range-track-height; + color: transparent; + cursor: $form-range-track-cursor; + background-color: transparent; + border-color: transparent; + border-width: $form-range-thumb-height / 2; + @include box-shadow($form-range-track-box-shadow); + } + + &::-ms-fill-lower { + background-color: $form-range-track-bg; + @include border-radius($form-range-track-border-radius); + } + + &::-ms-fill-upper { + margin-right: 15px; // arbitrary? + background-color: $form-range-track-bg; + @include border-radius($form-range-track-border-radius); + } + + &:disabled { + &::-webkit-slider-thumb { + background-color: $form-range-thumb-disabled-bg; + } + + &::-webkit-slider-runnable-track { + cursor: default; + } + + &::-moz-range-thumb { + background-color: $form-range-thumb-disabled-bg; + } + + &::-moz-range-track { + cursor: default; + } + + &::-ms-thumb { + background-color: $form-range-thumb-disabled-bg; + } + } +} diff --git a/scss/forms/_form-select.scss b/scss/forms/_form-select.scss new file mode 100644 index 000000000000..e0b69c04f7b2 --- /dev/null +++ b/scss/forms/_form-select.scss @@ -0,0 +1,76 @@ +// Select +// +// Replaces the browser default select with a custom one, mostly pulled from +// https://primer.github.io/. + +.form-select { + display: inline-block; + width: 100%; + height: $form-select-height; + padding: $form-select-padding-y ($form-select-padding-x + $form-select-indicator-padding) $form-select-padding-y $form-select-padding-x; + font-family: $form-select-font-family; + @include font-size($form-select-font-size); + font-weight: $form-select-font-weight; + line-height: $form-select-line-height; + color: $form-select-color; + vertical-align: middle; + background: $form-select-background; + background-color: $form-select-bg; + border: $form-select-border-width solid $form-select-border-color; + @include border-radius($form-select-border-radius, 0); + @include box-shadow($form-select-box-shadow); + appearance: none; + + &:focus { + border-color: $form-select-focus-border-color; + outline: 0; + @if $enable-shadows { + box-shadow: $form-select-box-shadow, $form-select-focus-box-shadow; + } @else { + box-shadow: $form-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) - We'll never share your email with anyone else. - -
- - -
-
- - -
- - -{{< /example >}} - -## Form controls - -Textual form controls—like ``s, ` - - -{{< /example >}} - -For file inputs, swap the `.form-control` for `.form-control-file`. - -{{< example >}} -
-
- - -
-
-{{< /example >}} - -### Sizing - -Set heights using classes like `.form-control-lg` and `.form-control-sm`. - -{{< example >}} - - - -{{< /example >}} - -{{< example >}} - - - -{{< /example >}} - -### Readonly - -Add the `readonly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor. - -{{< example >}} - -{{< /example >}} - -### Readonly plain text - -If you want to have `` elements in your form styled as plain text, use the `.form-control-plaintext` class to remove the default form field styling and preserve the correct margin and padding. - -{{< example >}} -
-
- -
- -
-
-
- -
- -
-
-
-{{< /example >}} - -{{< example >}} -
-
- - -
-
- - -
- -
-{{< /example >}} - -## Range Inputs - -Set horizontally scrollable range inputs using `.form-control-range`. - -{{< example >}} -
-
- - -
-
-{{< /example >}} - -## Checkboxes and radios - -Default checkboxes and radios are improved upon with the help of `.form-check`, **a single class for both input types that improves the layout and behavior of their HTML elements**. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many. - -Disabled checkboxes and radios are supported. The `disabled` attribute will apply a lighter color to help indicate the input's state. - -Checkboxes and radios use are built to support HTML-based form validation and provide concise, accessible labels. As such, our ``s and `