v5: Forms update (#28450)

* Initial spike of consolidated form checks

* Stub out forms rearrangement

- Prepping to drop non-custom file and range inputs
- Prepping to merge custom and native checks and radios (with switches)
- Prepping to merge custom select with form select
- Moving docs arround so forms has it's own area given volume of CSS

* Move input group Sass file to forms subdir

* Start to split and move the docs around

* Simpler imports

* Copyediting

* delete overview file

* Remove commented out code

* remove the custom-forms import

* rewrite flex-check as form-check, replace all custom properties

* Remove old forms doc

* stub out new subpage link section

* update migration guide

* Update nav, forms overview in page nav, and descriptions

* fix check bg position

* fix margin-top calculation

* rename .custom-select to .form-select

* Update validation styles for new checks

* add some vertical margin, fix inline checks

* fix docs examples

* better way to do this contents stuff, redo the toc while i'm at it

* page restyle for docs while here

* un-callout that, edit text

* redo padding on toc

* fix toc

* start to cleanup checks docs

* Rewrite Markdown tables into HTML

* Redesign tables, redo their docs

* Replace Open Iconic icons with custom Bootstrap icons

* Redesign the docs navbar, add a subheader, redo the sidebar

* Redesign docs homepage a bit

* Simplify table style overrides for docs tables

* Simplify docs typography for page titles and reading line length

* Stub out icons page

* Part of sidebar update, remove migration from nav.yml

* Move toc CSS to separate partial

* Change appearance of overview page

* fix sidebar arrow direction

* Add footer to docs layout

* Update descriptions

* Drop the .form-group class for margin utilities

* Remove lingering form-group-margin-bottom var

* improve footer spacing

* add headings to range page

* uncomment form range css

* Rename .custom-range to .form-range

* Drop unused docs var

* Uncomment the comment

* Remove unused variable

* Fix radio image sizing

* Reboot update: reset horizontal ul and ol padding

* de-dupe IDs

* tweak toc styles

* nvm, fix dropdown versions stuff

* remove sidebar nav toggle for now

* broken html

* fix more broken html, move css

* scss linting

* comment out broken helper docs

* scope styles

* scope styles

* Fixes #25540 and fixes #26407 for v5 only

* Update sidebar once more

* Match new sidenav order

* fix syntax error

* Rename custom-file to form-file, update paths, update migration docs for previous changes in #28696

* rename back

* fix size and alignment

* rename that back too
This commit is contained in:
Mark Otto 2019-07-12 16:52:33 -05:00 committed by GitHub
parent 50f97710eb
commit aaf03bdc9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 3162 additions and 2918 deletions

View File

@ -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) <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;
}
}
.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;
@include 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;
@include 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 attribute instead of :disabled pseudo-class
// Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231
&[disabled] ~ .custom-file-label {
background-color: $custom-file-disabled-bg;
}
}
.custom-file-label {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 1;
display: flex;
height: $custom-file-height;
border-color: $custom-file-border-color;
@include border-radius($custom-file-border-radius);
@include box-shadow($custom-file-box-shadow);
}
.custom-file-text {
display: block;
flex-grow: 1;
padding: $custom-file-padding-y $custom-file-padding-x;
overflow: hidden;
font-family: $custom-file-font-family;
font-weight: $custom-file-font-weight;
line-height: $custom-file-line-height;
color: $custom-file-color;
text-overflow: ellipsis;
white-space: nowrap;
background-color: $custom-file-bg;
border-color: inherit;
border-style: solid;
border-width: $custom-file-border-width;
@include border-left-radius(inherit);
}
.custom-file-button {
display: block;
flex-shrink: 0;
padding: $custom-file-padding-y $custom-file-padding-x;
margin-left: -$custom-file-border-width;
line-height: $custom-file-line-height;
color: $custom-file-button-color;
@include gradient-bg($custom-file-button-bg);
border-color: inherit;
border-style: solid;
border-width: $custom-file-border-width;
@include border-right-radius(inherit);
}
// 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: calc(#{$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
@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);
@include transition($custom-forms-transition);
appearance: none;
&: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);
@include transition($custom-forms-transition);
appearance: none;
&: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;
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.
@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);
@include transition($custom-forms-transition);
appearance: none;
&: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 / 2;
@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);
}
&: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-file-text,
.custom-file-button,
.custom-select {
@include transition($custom-forms-transition);
}

View File

@ -1,334 +1,9 @@
// stylelint-disable selector-no-qualifying-type
//
// Textual form controls
//
.form-control {
display: block;
width: 100%;
height: $input-height;
padding: $input-padding-y $input-padding-x;
font-family: $input-font-family;
@include font-size($input-font-size);
font-weight: $input-font-weight;
line-height: $input-line-height;
color: $input-color;
background-color: $input-bg;
background-clip: padding-box;
border: $input-border-width solid $input-border-color;
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
@include border-radius($input-border-radius, 0);
@include box-shadow($input-box-shadow);
@include transition($input-transition);
// Unstyle the caret on `<select>`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) <select> receives focus
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
// match the appearance of the native widget.
// See https://github.com/twbs/bootstrap/issues/19398.
color: $input-color;
background-color: $input-bg;
}
}
// Make file inputs better match text inputs by forcing them to new lines.
.form-control-file,
.form-control-range {
display: block;
width: 100%;
}
//
// Labels
//
// For use with horizontal and inline forms, when you need the label (or legend)
// text to align with the form controls.
.col-form-label {
padding-top: calc(#{$input-padding-y} + #{$input-border-width});
padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});
margin-bottom: 0; // Override the `<label>/<legend>` default
@include font-size(inherit); // Override the `<legend>` default
line-height: $input-line-height;
}
.col-form-label-lg {
padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});
padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
}
.col-form-label-sm {
padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});
padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
}
// 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
@include font-size($input-font-size);
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);
}
// stylelint-disable-next-line no-duplicate-selectors
select.form-control {
&[size],
&[multiple] {
height: auto;
}
}
textarea.form-control {
height: auto;
}
// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.
.form-group {
margin-bottom: $form-group-margin-bottom;
}
.form-text {
display: block;
margin-top: $form-text-margin-top;
}
// Form grid
//
// Special replacement for our grid system's `.row` for tighter form layouts.
@if $enable-grid-classes {
.form-row {
display: flex;
flex-wrap: wrap;
margin-right: -$form-grid-gutter-width / 2;
margin-left: -$form-grid-gutter-width / 2;
> .col,
> [class*="col-"] {
padding-right: $form-grid-gutter-width / 2;
padding-left: $form-grid-gutter-width / 2;
}
}
}
// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
.form-check {
position: relative;
display: block;
padding-left: $form-check-input-gutter;
}
.form-check-input {
position: absolute;
margin-top: $form-check-input-margin-y;
margin-left: -$form-check-input-gutter;
// Use disabled attribute instead of :disabled pseudo-class
// Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231
&[disabled] ~ .form-check-label {
color: $text-muted;
}
}
.form-check-label {
margin-bottom: 0; // Override default `<label>` bottom margin
}
.form-check-inline {
display: inline-flex;
align-items: center;
padding-left: 0; // Override base .form-check
margin-right: $form-check-inline-margin-x;
// Undo .form-check-input defaults and add some `margin-right`.
.form-check-input {
position: static;
margin-top: 0;
margin-right: $form-check-inline-input-margin-x;
margin-left: 0;
}
}
// Form validation
//
// Provide feedback to users when form field values are valid or invalid. Works
// primarily for client-side validation via scoped `:invalid` and `:valid`
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
// server-side validation.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
// Because we use flex, the initial sizing of checkboxes is collapsed and
// doesn't occupy the full-width (which is what we want for xs grid tier),
// so we force that here.
.form-check {
width: 100%;
}
// Kick in the inline
@include media-breakpoint-up(sm) {
label {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0;
}
// Inline-block all the things for "inline"
.form-group {
display: flex;
flex: 0 0 auto;
flex-flow: row wrap;
align-items: center;
margin-bottom: 0;
}
// Allow folks to *not* use `.form-group`
.form-control {
display: inline-block;
width: auto; // Prevent labels from stacking above inputs in `.form-group`
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-plaintext {
display: inline-block;
}
.input-group,
.custom-select {
width: auto;
}
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match.
.form-check {
display: flex;
align-items: center;
justify-content: center;
width: auto;
padding-left: 0;
}
.form-check-input {
position: relative;
flex-shrink: 0;
margin-top: 0;
margin-right: $form-check-input-margin-x;
margin-left: 0;
}
.custom-control {
align-items: center;
justify-content: center;
}
.custom-control-label {
margin-bottom: 0;
}
}
}
@import "forms/labels";
@import "forms/form-control";
@import "forms/form-select";
@import "forms/form-check";
@import "forms/form-file";
@import "forms/form-range";
@import "forms/layout";
@import "forms/input-group";
@import "forms/validation";

View File

@ -157,6 +157,12 @@ address {
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
padding-left: 2rem;
}
ol,
ul,
dl {

View File

@ -12,12 +12,16 @@
td {
padding: $table-cell-padding;
vertical-align: top;
border-top: $table-border-width solid $table-border-color;
border-bottom: $table-border-width solid $table-border-color;
}
td {
border-bottom: $table-border-width solid $table-border-color;
}
thead th {
vertical-align: bottom;
border-bottom: (2 * $table-border-width) solid $table-border-color;
border-bottom-color: $table-head-border-color;
}
tbody + tbody {

View File

@ -351,8 +351,8 @@ $hr-margin-y: $spacer !default;
//
// Customizes the `.table` component with basic values, each used across all table variations.
$table-cell-padding: .75rem !default;
$table-cell-padding-sm: .3rem !default;
$table-cell-padding: .5rem !default;
$table-cell-padding-sm: .25rem !default;
$table-color: $body-color !default;
$table-bg: null !default;
@ -366,6 +366,7 @@ $table-border-color: $border-color !default;
$table-head-bg: $gray-200 !default;
$table-head-color: $gray-700 !default;
$table-head-border-color: $gray-700 !default;
$table-dark-color: $white !default;
$table-dark-bg: $gray-800 !default;
@ -506,17 +507,61 @@ $input-height-lg: calc(#{$input-line-height-lg * 1em} + #{
$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
$form-check-input-width: 1.25em !default;
$form-check-min-height: $font-size-base * $line-height-base !default;
$form-check-padding-left: $form-check-input-width + .5em !default;
$form-check-margin-bottom: .125rem !default;
$form-check-input-active-filter: brightness(90%) !default;
$form-check-input-bg: $body-bg !default;
$form-check-input-border: 1px solid rgba(0, 0, 0, .25) !default;
$form-check-input-border-radius: .25em !default;
$form-check-radio-border-radius: 50% !default;
$form-check-input-focus-border: $input-focus-border-color !default;
$form-check-input-focus-box-shadow: $input-btn-focus-box-shadow !default;
$form-check-input-checked-color: $component-active-color !default;
$form-check-input-checked-bg-color: $component-active-bg !default;
$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default;
$form-check-input-checked-bg-repeat: no-repeat !default;
$form-check-input-checked-bg-position: center center !default;
$form-check-input-checked-bg-size: 1em !default;
$form-check-input-checked-bg-image: str-replace(url('data:image/svg+xml;utf8,<svg viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="#{$form-check-input-checked-color}" stroke-width="3" d="M4 8.5L6.5 11l6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>'), "#", "%23") !default;
$form-check-radio-checked-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-check-input-checked-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-check-input-indeterminate-color: $component-active-color !default;
$form-check-input-indeterminate-bg-color: $component-active-bg !default;
$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default;
$form-check-input-indeterminate-bg-repeat: no-repeat !default;
$form-check-input-indeterminate-bg-position: center center !default;
$form-check-input-indeterminate-bg-size: 1em !default;
$form-check-input-indeterminate-bg-image: str-replace(url('data:image/svg+xml;utf8,<svg viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M5 8h6" stroke="#{$form-check-input-indeterminate-color}" stroke-width="3" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>'), "#", "%23") !default;
$form-switch-color: rgba(0, 0, 0, .25) !default;
$form-switch-width: 2em !default;
$form-switch-height: $form-check-input-width !default;
$form-switch-padding-left: $form-switch-width + .5em !default;
$form-switch-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-switch-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-switch-border-radius: $form-switch-width !default;
$form-switch-transition: .2s ease-in-out !default;
$form-switch-transition-property: background-position, background-color !default;
$form-switch-focus-color: hsla(211, 100%, 75%, 1) !default;
$form-switch-focus-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-switch-focus-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-switch-checked-color: $component-active-color !default;
$form-switch-checked-bg-image: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$form-switch-checked-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-switch-checked-bg-position: right center !default;
$form-text-margin-top: .25rem !default;
$form-check-input-gutter: 1.25rem !default;
$form-check-input-margin-y: .3rem !default;
$form-check-inline-margin-right: 1rem !default;
$form-check-input-margin-x: .25rem !default;
$form-check-inline-margin-x: .75rem !default;
$form-check-inline-input-margin-x: .3125rem !default;
$form-grid-gutter-width: 10px !default;
$form-group-margin-bottom: 1rem !default;
$input-group-addon-color: $input-color !default;
$input-group-addon-bg: $gray-200 !default;
@ -524,128 +569,83 @@ $input-group-addon-border-color: $input-border-color !default;
$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
$custom-control-gutter: .5rem !default;
$custom-control-spacer-x: 1rem !default;
$form-select-padding-y: $input-padding-y !default;
$form-select-padding-x: $input-padding-x !default;
$form-select-font-family: $input-font-family !default;
$form-select-font-size: $input-font-size !default;
$form-select-height: $input-height !default;
$form-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
$form-select-font-weight: $input-font-weight !default;
$form-select-line-height: $input-line-height !default;
$form-select-color: $input-color !default;
$form-select-disabled-color: $gray-600 !default;
$form-select-bg: $input-bg !default;
$form-select-disabled-bg: $gray-200 !default;
$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions
$form-select-indicator-color: $gray-800 !default;
$form-select-indicator: str-replace(url('data:image/svg+xml;utf8,<svg viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="#{$form-select-indicator-color}" stroke-width="2px" d="M2 5l6 6 6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>'), "#", "%23") !default;
$custom-control-indicator-size: 1rem !default;
$custom-control-indicator-bg: $input-bg !default;
$form-select-background: $form-select-indicator no-repeat right $form-select-padding-x center / $form-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
$custom-control-indicator-bg-size: 50% 50% !default;
$custom-control-indicator-box-shadow: $input-box-shadow !default;
$custom-control-indicator-border-color: $gray-500 !default;
$custom-control-indicator-border-width: $input-border-width !default;
$form-select-feedback-icon-padding-right: calc((1em + #{2 * $form-select-padding-y}) * 3 / 4 + #{$form-select-padding-x + $form-select-indicator-padding}) !default;
$form-select-feedback-icon-position: center right ($form-select-padding-x + $form-select-indicator-padding) !default;
$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;
$custom-control-label-color: null !default;
$form-select-border-width: $input-border-width !default;
$form-select-border-color: $input-border-color !default;
$form-select-border-radius: $border-radius !default;
$form-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;
$custom-control-indicator-disabled-bg: $input-disabled-bg !default;
$custom-control-label-disabled-color: $gray-600 !default;
$form-select-focus-border-color: $input-focus-border-color !default;
$form-select-focus-width: $input-focus-width !default;
$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default;
$custom-control-indicator-checked-color: $component-active-color !default;
$custom-control-indicator-checked-bg: $component-active-bg !default;
$custom-control-indicator-checked-disabled-bg: rgba(theme-color("primary"), .5) !default;
$custom-control-indicator-checked-box-shadow: none !default;
$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;
$form-select-padding-y-sm: $input-padding-y-sm !default;
$form-select-padding-x-sm: $input-padding-x-sm !default;
$form-select-font-size-sm: $input-font-size-sm !default;
$form-select-height-sm: $input-height-sm !default;
$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;
$custom-control-indicator-focus-border-color: $input-focus-border-color !default;
$form-select-padding-y-lg: $input-padding-y-lg !default;
$form-select-padding-x-lg: $input-padding-x-lg !default;
$form-select-font-size-lg: $input-font-size-lg !default;
$form-select-height-lg: $input-height-lg !default;
$custom-control-indicator-active-color: $component-active-color !default;
$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;
$custom-control-indicator-active-box-shadow: none !default;
$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;
$form-range-track-width: 100% !default;
$form-range-track-height: .5rem !default;
$form-range-track-cursor: pointer !default;
$form-range-track-bg: $gray-300 !default;
$form-range-track-border-radius: 1rem !default;
$form-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;
$custom-checkbox-indicator-border-radius: $border-radius !default;
$custom-checkbox-indicator-icon-checked: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e"), "#", "%23") !default;
$form-range-thumb-width: 1rem !default;
$form-range-thumb-height: $form-range-thumb-width !default;
$form-range-thumb-bg: $component-active-bg !default;
$form-range-thumb-border: 0 !default;
$form-range-thumb-border-radius: 1rem !default;
$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;
$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;
$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge
$form-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;
$form-range-thumb-disabled-bg: $gray-500 !default;
$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;
$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;
$custom-checkbox-indicator-icon-indeterminate: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3e%3c/svg%3e"), "#", "%23") !default;
$custom-checkbox-indicator-indeterminate-box-shadow: none !default;
$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;
$form-file-height: $input-height !default;
$form-file-focus-border-color: $input-focus-border-color !default;
$form-file-focus-box-shadow: $input-focus-box-shadow !default;
$form-file-disabled-bg: $input-disabled-bg !default;
$custom-radio-indicator-border-radius: 50% !default;
$custom-radio-indicator-icon-checked: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3e%3c/svg%3e"), "#", "%23") !default;
$custom-switch-width: $custom-control-indicator-size * 1.75 !default;
$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;
$custom-switch-indicator-size: calc(#{$custom-control-indicator-size} - #{$custom-control-indicator-border-width * 4}) !default;
$custom-select-padding-y: $input-padding-y !default;
$custom-select-padding-x: $input-padding-x !default;
$custom-select-font-family: $input-font-family !default;
$custom-select-font-size: $input-font-size !default;
$custom-select-height: $input-height !default;
$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
$custom-select-font-weight: $input-font-weight !default;
$custom-select-line-height: $input-line-height !default;
$custom-select-color: $input-color !default;
$custom-select-disabled-color: $gray-600 !default;
$custom-select-bg: $input-bg !default;
$custom-select-disabled-bg: $gray-200 !default;
$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions
$custom-select-indicator-color: $gray-800 !default;
$custom-select-indicator: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e"), "#", "%23") !default;
$custom-select-background: $custom-select-indicator no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
$custom-select-feedback-icon-padding-right: calc((1em + #{2 * $custom-select-padding-y}) * 3 / 4 + #{$custom-select-padding-x + $custom-select-indicator-padding}) !default;
$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;
$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;
$custom-select-border-width: $input-border-width !default;
$custom-select-border-color: $input-border-color !default;
$custom-select-border-radius: $border-radius !default;
$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;
$custom-select-focus-border-color: $input-focus-border-color !default;
$custom-select-focus-width: $input-focus-width !default;
$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;
$custom-select-padding-y-sm: $input-padding-y-sm !default;
$custom-select-padding-x-sm: $input-padding-x-sm !default;
$custom-select-font-size-sm: $input-font-size-sm !default;
$custom-select-height-sm: $input-height-sm !default;
$custom-select-padding-y-lg: $input-padding-y-lg !default;
$custom-select-padding-x-lg: $input-padding-x-lg !default;
$custom-select-font-size-lg: $input-font-size-lg !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-focus-box-shadow !default;
$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge
$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;
$custom-range-thumb-disabled-bg: $gray-500 !default;
$custom-file-height: $input-height !default;
$custom-file-focus-border-color: $input-focus-border-color !default;
$custom-file-focus-box-shadow: $input-focus-box-shadow !default;
$custom-file-disabled-bg: $input-disabled-bg !default;
$custom-file-padding-y: $input-padding-y !default;
$custom-file-padding-x: $input-padding-x !default;
$custom-file-line-height: $input-line-height !default;
$custom-file-font-family: $input-font-family !default;
$custom-file-font-weight: $input-font-weight !default;
$custom-file-color: $input-color !default;
$custom-file-bg: $input-bg !default;
$custom-file-border-width: $input-border-width !default;
$custom-file-border-color: $input-border-color !default;
$custom-file-border-radius: $input-border-radius !default;
$custom-file-box-shadow: $input-box-shadow !default;
$custom-file-button-color: $custom-file-color !default;
$custom-file-button-bg: $input-group-addon-bg !default;
$form-file-padding-y: $input-padding-y !default;
$form-file-padding-x: $input-padding-x !default;
$form-file-line-height: $input-line-height !default;
$form-file-font-family: $input-font-family !default;
$form-file-font-weight: $input-font-weight !default;
$form-file-color: $input-color !default;
$form-file-bg: $input-bg !default;
$form-file-border-width: $input-border-width !default;
$form-file-border-color: $input-border-color !default;
$form-file-border-radius: $input-border-radius !default;
$form-file-box-shadow: $input-box-shadow !default;
$form-file-button-color: $form-file-color !default;
$form-file-button-bg: $input-group-addon-bg !default;
// Form validation

2
scss/bootstrap.scss vendored
View File

@ -27,8 +27,6 @@
@import "transitions";
@import "dropdown";
@import "button-group";
@import "input-group";
@import "custom-forms";
@import "nav";
@import "navbar";
@import "card";

116
scss/forms/_form-check.scss Normal file
View File

@ -0,0 +1,116 @@
//
// Check/radio
//
.form-check {
display: block;
min-height: $form-check-min-height;
padding-left: $form-check-padding-left;
margin-bottom: $form-check-margin-bottom;
}
.form-check-input {
float: left;
width: $form-check-input-width;
height: $form-check-input-width;
// Todo: Change static value to base line-height?
margin-top: calc((1.5em - #{$form-check-input-width}) / 2); // line-height minus check height
margin-left: $form-check-padding-left * -1;
background-color: $form-check-input-bg;
border: $form-check-input-border;
appearance: none;
&[type="checkbox"] {
@include border-radius($form-check-input-border-radius);
}
&[type="radio"] {
@include border-radius($form-check-radio-border-radius);
}
&:active {
filter: $form-check-input-active-filter;
}
&:focus {
border-color: $form-check-input-focus-border;
outline: 0;
box-shadow: $form-check-input-focus-box-shadow;
}
&:checked {
background-color: $form-check-input-checked-bg-color;
background-repeat: $form-check-input-checked-bg-repeat;
background-position: $form-check-input-checked-bg-position;
background-size: $form-check-input-checked-bg-size;
border-color: $form-check-input-checked-border-color;
&[type="checkbox"] {
background-image: $form-check-input-checked-bg-image;
}
&[type="radio"] {
background-image: $form-check-radio-checked-bg-image;
}
}
&[type="checkbox"]:indeterminate {
background-color: $form-check-input-indeterminate-bg-color;
background-image: $form-check-input-indeterminate-bg-image;
background-repeat: $form-check-input-indeterminate-bg-repeat;
background-position: $form-check-input-indeterminate-bg-position;
background-size: $form-check-input-indeterminate-bg-size;
border-color: $form-check-input-indeterminate-border-color;
}
// Use disabled attribute instead of :disabled pseudo-class
// Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231
&[disabled] {
pointer-events: none;
filter: none;
opacity: .5;
~ .form-check-label {
opacity: .5;
}
}
}
.form-check-label {
margin-bottom: 0;
}
//
// Switch
//
.form-switch {
padding-left: $form-switch-padding-left;
.form-check-input {
width: $form-switch-width;
margin-left: $form-switch-padding-left * -1;
background-image: $form-switch-bg-image;
background-repeat: no-repeat;
background-position: left center;
background-size: calc(#{$form-switch-height} - 2px); // Get a 1px separation
@include border-radius($form-switch-border-radius);
// Todo: Figure out how to tackle these, with or without mixin?
// transition: $form-switch-transition;
// transition-property: $form-switch-transition-property;
&:focus {
background-image: $form-switch-focus-bg-image;
}
&:checked {
background-image: $form-switch-checked-bg-image;
background-position: $form-switch-checked-bg-position;
}
}
}
.form-check-inline {
display: inline-block;
margin-right: $form-check-inline-margin-right;
}

View File

@ -0,0 +1,115 @@
// stylelint-disable selector-no-qualifying-type
//
// Textual form controls
//
.form-control {
display: block;
width: 100%;
height: $input-height;
padding: $input-padding-y $input-padding-x;
font-family: $input-font-family;
@include font-size($input-font-size);
font-weight: $input-font-weight;
line-height: $input-line-height;
color: $input-color;
background-color: $input-bg;
background-clip: padding-box;
border: $input-border-width solid $input-border-color;
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
@include border-radius($input-border-radius, 0);
@include box-shadow($input-box-shadow);
@include transition($input-transition);
// Unstyle the caret on `<select>`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;
}

View File

@ -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);
}

142
scss/forms/_form-range.scss Normal file
View File

@ -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;
}
}
}

View File

@ -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) <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: $form-select-padding-x;
background-image: none;
}
&:disabled {
color: $form-select-disabled-color;
background-color: $form-select-disabled-bg;
}
// Hides the default caret in IE11
&::-ms-expand {
display: none;
}
}
.form-select-sm {
height: $form-select-height-sm;
padding-top: $form-select-padding-y-sm;
padding-bottom: $form-select-padding-y-sm;
padding-left: $form-select-padding-x-sm;
@include font-size($form-select-font-size-sm);
}
.form-select-lg {
height: $form-select-height-lg;
padding-top: $form-select-padding-y-lg;
padding-bottom: $form-select-padding-y-lg;
padding-left: $form-select-padding-x-lg;
@include font-size($form-select-font-size-lg);
}

View File

@ -12,45 +12,45 @@
width: 100%;
> .form-control,
> .custom-select,
> .custom-file {
> .form-select,
> .form-file {
position: relative; // For focus state's z-index
flex: 1 1 0%;
margin-bottom: 0;
+ .form-control,
+ .custom-select,
+ .custom-file {
+ .form-select,
+ .form-file {
margin-left: -$input-border-width;
}
}
// Bring the "active" form control to the top of surrounding elements
> .form-control:focus,
> .custom-select:focus,
> .custom-file .custom-file-input:focus ~ .custom-file-label {
> .form-select:focus,
> .form-file .form-file-input:focus ~ .form-file-label {
z-index: 3;
}
// Bring the custom file input above the label
> .custom-file .custom-file-input:focus {
> .form-file .form-file-input:focus {
z-index: 4;
}
> .form-control,
> .custom-select {
> .form-select {
&:not(:last-child) { @include border-right-radius(0); }
&:not(:first-child) { @include border-left-radius(0); }
}
// Custom file inputs have more complex markup, thus requiring different
// border-radius overrides.
> .custom-file {
> .form-file {
display: flex;
align-items: center;
&:not(:last-child) .custom-file-label { @include border-right-radius(0); }
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
&:not(:last-child) .form-file-label { @include border-right-radius(0); }
&:not(:first-child) .form-file-label { @include border-left-radius(0); }
}
}
@ -123,12 +123,12 @@
// manipulation.
.input-group-lg > .form-control:not(textarea),
.input-group-lg > .custom-select {
.input-group-lg > .form-select {
height: $input-height-lg;
}
.input-group-lg > .form-control,
.input-group-lg > .custom-select,
.input-group-lg > .form-select,
.input-group-lg > .input-group-prepend > .input-group-text,
.input-group-lg > .input-group-append > .input-group-text,
.input-group-lg > .input-group-prepend > .btn,
@ -140,12 +140,12 @@
}
.input-group-sm > .form-control:not(textarea),
.input-group-sm > .custom-select {
.input-group-sm > .form-select {
height: $input-height-sm;
}
.input-group-sm > .form-control,
.input-group-sm > .custom-select,
.input-group-sm > .form-select,
.input-group-sm > .input-group-prepend > .input-group-text,
.input-group-sm > .input-group-append > .input-group-text,
.input-group-sm > .input-group-prepend > .btn,
@ -156,9 +156,9 @@
@include border-radius($input-border-radius-sm);
}
.input-group-lg > .custom-select,
.input-group-sm > .custom-select {
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
.input-group-lg > .form-select,
.input-group-sm > .form-select {
padding-right: $form-select-padding-x + $form-select-indicator-padding;
}

27
scss/forms/_labels.scss Normal file
View File

@ -0,0 +1,27 @@
//
// Labels
//
// For use with horizontal and inline forms, when you need the label (or legend)
// text to align with the form controls.
.col-form-label {
padding-top: calc(#{$input-padding-y} + #{$input-border-width});
padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});
margin-bottom: 0; // Override the `<label>/<legend>` default
@include font-size(inherit); // Override the `<legend>` default
line-height: $input-line-height;
}
.col-form-label-lg {
padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});
padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
}
.col-form-label-sm {
padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});
padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
}

101
scss/forms/_layout.scss Normal file
View File

@ -0,0 +1,101 @@
// Form grid
//
// Special replacement for our grid system's `.row` for tighter form layouts.
@if $enable-grid-classes {
.form-row {
display: flex;
flex-wrap: wrap;
margin-right: -$form-grid-gutter-width / 2;
margin-left: -$form-grid-gutter-width / 2;
> .col,
> [class*="col-"] {
padding-right: $form-grid-gutter-width / 2;
padding-left: $form-grid-gutter-width / 2;
}
}
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
// Because we use flex, the initial sizing of checkboxes is collapsed and
// doesn't occupy the full-width (which is what we want for xs grid tier),
// so we force that here.
.form-check {
width: 100%;
}
// Kick in the inline
@include media-breakpoint-up(sm) {
label {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0;
}
// Inline-block all the things for "inline"
.form-group {
display: flex;
flex: 0 0 auto;
flex-flow: row wrap;
align-items: center;
margin-bottom: 0;
}
// Allow folks to *not* use `.form-group`
.form-control {
display: inline-block;
width: auto; // Prevent labels from stacking above inputs in `.form-group`
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-plaintext {
display: inline-block;
}
.input-group,
.form-select {
width: auto;
}
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match.
.form-check {
display: flex;
align-items: center;
justify-content: center;
width: auto;
padding-left: 0;
}
.form-check-input {
position: relative;
flex-shrink: 0;
margin-top: 0;
margin-right: $form-check-input-margin-x;
margin-left: 0;
}
.custom-control {
align-items: center;
justify-content: center;
}
.custom-control-label {
margin-bottom: 0;
}
}
}

View File

@ -0,0 +1,10 @@
// Form validation
//
// Provide feedback to users when form field values are valid or invalid. Works
// primarily for client-side validation via scoped `:invalid` and `:valid`
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
// server-side validation.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}

View File

@ -97,13 +97,13 @@
}
}
.custom-select {
.form-select {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
padding-right: $custom-select-feedback-icon-padding-right;
background: $custom-select-background, $icon $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;
padding-right: $form-select-feedback-icon-padding-right;
background: $form-select-background, $icon $form-select-bg no-repeat $form-select-feedback-icon-position / $form-select-feedback-icon-size;
}
&:focus {
@ -130,6 +130,16 @@
.form-check-input {
@include form-validation-state-selector($state) {
border-color: $color;
&:checked {
@include gradient-bg(lighten($color, 10%));
}
&:focus {
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
~ .form-check-label {
color: $color;
}
@ -140,45 +150,16 @@
}
}
}
.custom-control-input {
@include form-validation-state-selector($state) {
~ .custom-control-label {
color: $color;
&::before {
border-color: $color;
}
}
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
}
&:checked {
~ .custom-control-label::before {
border-color: lighten($color, 10%);
@include gradient-bg(lighten($color, 10%));
}
}
&:focus {
~ .custom-control-label::before {
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
&:not(:checked) ~ .custom-control-label::before {
border-color: $color;
}
}
.form-check-inline .form-check-input {
~ .#{$state}-feedback {
margin-left: .5em;
}
}
// custom file
.custom-file-input {
.form-file-input {
@include form-validation-state-selector($state) {
~ .custom-file-label {
~ .form-file-label {
border-color: $color;
}
@ -188,7 +169,7 @@
}
&:focus {
~ .custom-file-label {
~ .form-file-label {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}

View File

@ -107,11 +107,40 @@ var bsAlert = new bootstrap.Alert(myAlert)
This makes an alert listen for click events on descendant elements which have the `data-dismiss="alert"` attribute. (Not necessary when using the data-api's auto-initialization.)
| Method | Description |
| --- | --- |
| `close` | Closes an alert by removing it from the DOM. If the `.fade` and `.show` classes are present on the element, the alert will fade out before it is removed. |
| `dispose` | Destroys an element's alert. |
| `_getInstance` | *Static* method which allows you to get the alert instance associated to a DOM element, you can use it like this: `bootstrap.Alert._getInstance(alert)` |
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>close</code>
</td>
<td>
Closes an alert by removing it from the DOM. If the <code>.fade</code> and <code>.show</code> classes are present on the element, the alert will fade out before it is removed.
</td>
</tr>
<tr>
<td>
<code>dispose</code>
</td>
<td>
Destroys an element's alert.
</td>
</tr>
<tr>
<td>
<code>_getInstance</code>
</td>
<td>
Static method which allows you to get the alert instance associated to a DOM element, you can use it like this: <code>bootstrap.Alert._getInstance(alert)</code>
</td>
</tr>
</tbody>
</table>
{{< highlight js >}}
var alertNode = document.querySelector('.alert')
@ -123,10 +152,28 @@ alert.close()
Bootstrap's alert plugin exposes a few events for hooking into alert functionality.
| Event | Description |
| --- | --- |
| `close.bs.alert` | This event fires immediately when the <code>close</code> instance method is called. |
| `closed.bs.alert` | This event is fired when the alert has been closed (will wait for CSS transitions to complete). |
<table>
<thead>
<tr>
<th>Event</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>close.bs.alert</code></td>
<td>
Fires immediately when the <code>close</code> instance method is called.
</td>
</tr>
<tr>
<td><code>closed.bs.alert</code></td>
<td>
Fired when the alert has been closed and CSS transitions have completed.
</td>
</tr>
</tbody>
</table>
{{< highlight js >}}
var myAlert = document.getElementById('myAlert')

View File

@ -159,10 +159,32 @@ var button = document.getElementById('myButton')
var bsButton = new bootstrap.Button(button)
{{< /highlight >}}
| Method | Description |
| --------- | ------------------------------------------------------------------------------- |
| `toggle` | Toggles push state. Gives the button the appearance that it has been activated. |
| `dispose` | Destroys an element's button. |
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>toggle</code>
</td>
<td>
Toggles push state. Gives the button the appearance that it has been activated.
</td>
</tr>
<tr>
<td>
<code>dispose</code>
</td>
<td>
Destroys an element's button.
</td>
</tr>
</tbody>
</table>
For example, to toggle all buttons

View File

@ -230,7 +230,7 @@ var carousel = new bootstrap.Carousel(myCarousel)
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-interval=""`.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -296,17 +296,44 @@ var carousel = new bootstrap.Carousel(myCarousel, {
})
{{< /highlight >}}
| Method | Description |
| --- | --- |
| `cycle` | Cycles through the carousel items from left to right. |
| `pause` | Stops the carousel from cycling through items. |
| `prev` | Cycles to the previous item. **Returns to the caller before the previous item has been shown** (i.e. before the `slid.bs.carousel` event occurs). |
| `next` | Cycles to the next item. **Returns to the caller before the next item has been shown** (i.e. before the `slid.bs.carousel` event occurs). |
| `nextWhenVisible` | Only go to the next slide when the page, carousel and the carousel parent is visible. |
| `to` | Cycles the carousel to a particular frame (0 based, similar to an array). **Returns to the caller before the target item has been shown** (i.e. before the `slid.bs.carousel` event occurs). |
| `dispose` | Destroys an element's carousel. |
| `_getInstance` | *Static* method which allows you to get the carousel instance associated with a DOM element |
<table class="table">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>cycle</code></td>
<td>Cycles through the carousel items from left to right.</td>
</tr>
<tr>
<td><code>pause</code></td>
<td>Stops the carousel from cycling through items.</td>
</tr>
<tr>
<td><code>prev</code></td>
<td>Cycles to the previous item. <strong>Returns to the caller before the previous item has been shown</strong> (e.g., before the <code>slid.bs.carousel</code> event occurs).</td>
</tr>
<tr>
<td><code>next</code></td>
<td>Cycles to the next item. <strong>Returns to the caller before the next item has been shown</strong> (e.g., before the <code>slid.bs.carousel</code> event occurs).</td>
</tr>
<tr>
<td><code>nextWhenVisible</code></td>
<td>Cycles the carousel to a particular frame (0 based, similar to an array). <strong>Returns to the caller before the target item has been shown</strong> (e.g., before the <code>slid.bs.carousel</code> event occurs).</td>
</tr>
<tr>
<td><code>dispose</code></td>
<td>Destroys an element's carousel.</td>
</tr>
<tr>
<td><code>_getInstance</code></td>
<td>Static method which allows you to get the carousel instance associated with a DOM element.</td>
</tr>
</tbody>
</table>
### Events
@ -319,21 +346,21 @@ Bootstrap's carousel class exposes two events for hooking into carousel function
All carousel events are fired at the carousel itself (i.e. at the `<div class="carousel">`).
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>slide.bs.carousel</td>
<td>This event fires immediately when the <code>slide</code> instance method is invoked.</td>
<td><code>slide.bs.carousel</code></td>
<td>Fires immediately when the <code>slide</code> instance method is invoked.</td>
</tr>
<tr>
<td>slid.bs.carousel</td>
<td>This event is fired when the carousel has completed its slide transition.</td>
<td><code>slid.bs.carousel</code></td>
<td>Fired when the carousel has completed its slide transition.</td>
</tr>
</tbody>
</table>

View File

@ -160,7 +160,7 @@ var collapseList = collapseElementList.map(function (collapseEl) {
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-parent=""`.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -202,22 +202,45 @@ var bsCollapse = new bootstrap.Collapse(myCollapse, {
})
{{< /highlight >}}
| Method | Description |
| --- | --- |
| `toggle` | Toggles a collapsible element to shown or hidden. **Returns to the caller before the collapsible element has actually been shown or hidden** (i.e. before the `shown.bs.collapse` or `hidden.bs.collapse` event occurs). |
| `show` | Shows a collapsible element. **Returns to the caller before the collapsible element has actually been shown** (i.e. before the `shown.bs.collapse` event occurs).|
| `hide` | Hides a collapsible element. **Returns to the caller before the collapsible element has actually been hidden** (i.e. before the `hidden.bs.collapse` event occurs).|
| `dispose` | Destroys an element's collapse. |
| `_getInstance` | *Static* method which allows you to get the collapse instance associated with a DOM element |
<table class="table">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>toggle</code></td>
<td>Toggles a collapsible element to shown or hidden. <strong>Returns to the caller before the collapsible element has actually been shown or hidden</strong> (i.e. before the <code>shown.bs.collapse</code> or <code>hidden.bs.collapse</code> event occurs).</td>
</tr>
<tr>
<td><code>show</code></td>
<td>Shows a collapsible element. <strong>Returns to the caller before the collapsible element has actually been shown</strong> (e.g., before the <code>shown.bs.collapse</code> event occurs). </td>
</tr>
<tr>
<td><code>hide</code></td>
<td>Hides a collapsible element. <strong>Returns to the caller before the collapsible element has actually been hidden</strong> (e.g., before the <code>hidden.bs.collapse</code> event occurs).</td>
</tr>
<tr>
<td><code>dispose</code></td>
<td>Destroys an element's collapse.</td>
</tr>
<tr>
<td><code>_getInstance</code></td>
<td>Static method which allows you to get the collapse instance associated with a DOM element.</td>
</tr>
</tbody>
</table>
### Events
Bootstrap's collapse class exposes a few events for hooking into collapse functionality.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -811,7 +811,7 @@ Regardless of whether you call your dropdown via JavaScript or instead use the d
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-offset=""`.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -862,26 +862,100 @@ Note when `boundary` is set to any value other than `'scrollParent'`, the style
### Methods
| Method | Description |
| --- | --- |
| `toggle` | Toggles the dropdown menu of a given navbar or tabbed navigation. |
| `show` | Shows the dropdown menu of a given navbar or tabbed navigation. |
| `hide` | Hides the dropdown menu of a given navbar or tabbed navigation. |
| `update` | Updates the position of an element's dropdown. |
| `dispose` | Destroys an element's dropdown. |
| `_getInstance` | *Static* method which allows you to get the dropdown instance associated with a DOM element |
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>toggle</code></td>
<td>
Toggles the dropdown menu of a given navbar or tabbed navigation.
</td>
</tr>
<tr>
<td><code>show</code></td>
<td>
Shows the dropdown menu of a given navbar or tabbed navigation.
</td>
</tr>
<tr>
<td><code>hide</code></td>
<td>
Hides the dropdown menu of a given navbar or tabbed navigation.
</td>
</tr>
<tr>
<td><code>update</code></td>
<td>
Updates the position of an element's dropdown.
</td>
</tr>
<tr>
<td><code>dispose</code></td>
<td>
Destroys an element's dropdown.
</td>
</tr>
<tr>
<td><code>_getInstance</code></td>
<td>
Static method which allows you to get the dropdown instance associated with a DOM element.
</td>
</tr>
</tbody>
</table>
### Events
All dropdown events are fired at the `.dropdown-menu`'s parent element and have a `relatedTarget` property, whose value is the toggling anchor element.
`hide.bs.dropdown` and `hidden.bs.dropdown` events have a `clickEvent` property (only when the original event type is `click`) that contains an Event Object for the click event.
`hide.bs.dropdown` and `hidden.bs.dropdown` events have a `clickEvent` property (only when the original Event type is `click`) that contains an Event Object for the click event.
| Event | Description |
| --- | --- |
| `show.bs.dropdown` | This event fires immediately when the show instance method is called. |
| `shown.bs.dropdown` | This event is fired when the dropdown has been made visible to the user (will wait for CSS transitions, to complete). |
| `hide.bs.dropdown` | This event is fired immediately when the hide instance method has been called. |
| `hidden.bs.dropdown`| This event is fired when the dropdown has finished being hidden from the user (will wait for CSS transitions, to complete). |
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>show.bs.dropdown</code>
</td>
<td>
Fires immediately when the show instance method is called.
</td>
</tr>
<tr>
<td>
<code>shown.bs.dropdown</code>
</td>
<td>
Fired when the dropdown has been made visible to the user and CSS transitions have completed.
</td>
</tr>
<tr>
<td>
<code>hide.bs.dropdown</code>
</td>
<td>
Fires immediately when the hide instance method has been called.
</td>
</tr>
<tr>
<td>
<code>hidden.bs.dropdown</code>
</td>
<td>
Fired when the dropdown has finished being hidden from the user and CSS transitions have completed.
</td>
</tr>
</tbody>
</table>
{{< highlight js >}}
var myDropdown = document.getElementById('myDropdown')

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
---
layout: docs
title: Icons
description: Custom icons for Bootstrap components.
group: components
toc: true
---
<div class="booticons-list">
<svg class="booticon booticon-chevron-left" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M11 2L5 8l6 6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-chevron-right" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M5 14l6-6-6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-chevron-up" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M2 11l6-6 6 6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-chevron-down" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M2 5l6 6 6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-chevron-condensed-left" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M9 2L6 8l3 6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-chevron-condensed-right" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M7 14l3-6-3-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-check" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M4 8.5L6.5 11l6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-x" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 8l-3 3 3-3 3 3-3-3zm0 0l3-3-3 3-3-3 3 3z" stroke="currentColor" stroke-width="2" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-dash" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M5 8h6" stroke="currentColor" stroke-width="2" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<svg class="booticon booticon-circle" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zm0-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8z" fill="currentColor" fill-rule="nonzero"/></svg>
<svg class="booticon booticon-dot" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 8v.082" stroke="currentColor" stroke-width="2" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>

View File

@ -356,7 +356,7 @@ When showing a new tab, the events fire in the following order:
If no tab was already active, the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event type</th>

View File

@ -590,7 +590,7 @@ Embedding YouTube videos in modals requires additional JavaScript not in Bootstr
Modals have three optional sizes, available via modifier classes to be placed on a `.modal-dialog`. These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th>Size</th>
@ -737,7 +737,7 @@ Create a modal with a single line of JavaScript:
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-backdrop=""`.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -833,10 +833,10 @@ var modal = bootstrap.Modal._getInstance(myModalEl) // Returns a Bootstrap modal
Bootstrap's modal class exposes a few events for hooking into modal functionality. All modal events are fired at the modal itself (i.e. at the `<div class="modal">`).
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -615,10 +615,10 @@ When showing a new tab, the events fire in the following order:
If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -153,7 +153,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
Note that for security reasons the `sanitize`, `sanitizeFn` and `whiteList` options cannot be supplied using data attributes.
{{< /callout >}}
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -356,10 +356,10 @@ var popover = bootstrap.Popover._getInstance(exampleTriggerEl) // Returns a Boot
### Events
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -287,7 +287,7 @@ Destroys an element's scrollspy.
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-offset=""`.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -320,10 +320,10 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
### Events
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -233,7 +233,7 @@ var toastList = toastElList.map(function (toastEl) {
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-animation=""`.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -293,10 +293,10 @@ Hides an element's toast. Your toast will remain on the DOM but won't show anymo
### Events
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -148,7 +148,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
Note that for security reasons the `sanitize`, `sanitizeFn` and `whiteList` options cannot be supplied using data attributes.
{{< /callout >}}
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 100px;">Name</th>
@ -343,10 +343,10 @@ Updates the position of an element's tooltip.
### Events
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th style="width: 150px;">Event type</th>
<th>Description</th>
</tr>
</thead>

View File

@ -102,7 +102,7 @@ All heading elements—e.g., `<h1>`—and `<p>` are reset to have their `margin-
## Lists
All lists—`<ul>`, `<ol>`, and `<dl>`—have their `margin-top` removed and a `margin-bottom: 1rem`. Nested lists have no `margin-bottom`.
All lists—`<ul>`, `<ol>`, and `<dl>`—have their `margin-top` removed and a `margin-bottom: 1rem`. Nested lists have no `margin-bottom`. We've also reset the horizontal `padding` on `<ul>` and `<ol>` elements.
<div class="bd-example">
{{< markdown >}}

View File

@ -6,11 +6,11 @@ group: content
toc: true
---
## Examples
## Overview
Due to the widespread use of tables across third-party widgets like calendars and date pickers, we've designed our tables to be **opt-in**. Just add the base class `.table` to any `<table>`, then extend with custom styles or our various included modifier classes.
Due to the widespread use of `<table>` elements across third-party widgets like calendars and date pickers, Bootstrap's tables are **opt-in**. Add the base class `.table` to any `<table>`, then extend with our optional modifier classes or custom styles. **All table styles are inherited in Bootstrap**, meaning any nested tables will be styled in the same manner as the parent.
Using the most basic table markup, here's how `.table`-based tables look in Bootstrap. **All table styles are inherited in Bootstrap 4**, meaning any nested tables will be styled in the same manner as the parent.
Using the most basic table markup, here's how `.table`-based tables look in Bootstrap.
{{< example >}}
<table class="table">
@ -45,6 +45,10 @@ Using the most basic table markup, here's how `.table`-based tables look in Boot
</table>
{{< /example >}}
## Options
### Inverted
You can also invert the colors—with light text on dark backgrounds—with `.table-dark`.
{{< example >}}
@ -80,75 +84,7 @@ You can also invert the colors—with light text on dark backgrounds—with `.ta
</table>
{{< /example >}}
## Table head options
Similar to tables and dark tables, use the modifier classes `.thead-light` or `.thead-dark` to make `<thead>`s appear light or dark gray.
{{< example >}}
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
{{< /example >}}
## Striped rows
### Striped rows
Use `.table-striped` to add zebra-striping to any table row within the `<tbody>`.
@ -218,7 +154,7 @@ Use `.table-striped` to add zebra-striping to any table row within the `<tbody>`
</table>
{{< /example >}}
## Bordered table
### Bordered
Add `.table-bordered` for borders on all sides of the table and cells.
@ -286,7 +222,7 @@ Add `.table-bordered` for borders on all sides of the table and cells.
</table>
{{< /example >}}
## Borderless table
### No borders
Add `.table-borderless` for a table without borders.
@ -356,7 +292,7 @@ Add `.table-borderless` for a table without borders.
</table>
{{< /example >}}
## Hoverable rows
### Hoverable rows
Add `.table-hover` to enable a hover state on table rows within a `<tbody>`.
@ -424,9 +360,9 @@ Add `.table-hover` to enable a hover state on table rows within a `<tbody>`.
</table>
{{< /example >}}
## Small table
### Small tables
Add `.table-sm` to make tables more compact by cutting cell padding in half.
Add `.table-sm` to make any `.table` more compact by cutting all cell `padding` in half.
{{< example >}}
<table class="table table-sm">
@ -460,39 +396,7 @@ Add `.table-sm` to make tables more compact by cutting cell padding in half.
</table>
{{< /example >}}
{{< example >}}
<table class="table table-sm table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
{{< /example >}}
## Contextual classes
### Variants
Use contextual classes to color table rows or individual cells.
@ -633,13 +537,77 @@ Regular table background variants are not available with the dark table, however
{{< partial "callout-warning-color-assistive-technologies.md" >}}
{{< /callout >}}
Create responsive tables by wrapping any `.table` with `.table-responsive{-sm|-md|-lg|-xl}`, making the table scroll horizontally at each `max-width` breakpoint of up to (but not including) 576px, 768px, 992px, and 1120px, respectively.
## Anatomy
{{< callout info >}}
{{< partial "callout-info-mediaqueries-breakpoints.md" >}}
{{< /callout >}}
### Table head
## Captions
Similar to tables and dark tables, use the modifier classes `.thead-light` or `.thead-dark` to make `<thead>`s appear light or dark gray.
{{< example >}}
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
{{< /example >}}
### Captions
A `<caption>` functions like a heading for a table. It helps users with screen readers to find a table and understand what it's about and decide if they want to read it.

View File

@ -0,0 +1,217 @@
---
layout: docs
title: Checks
description: Create consistent cross-browser and cross-device checkboxes and radios with our completely rewritten checks component.
group: forms
toc: true
---
## Approach
Browser default checkboxes and radios are replaced with the help of `.form-check`, a series of classes for both input types that improves the layout and behavior of their HTML elements, that provide greater customization and cross browser consistency. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many.
Structurally, our `<input>`s and `<label>`s are sibling elements as opposed to an `<input>` within a `<label>`. This is slightly more verbose as you must specify `id` and `for` attributes to relate the `<input>` and `<label>`. We use the sibling selector (`~`) for all our `<input>` states, like `[checked]` or `[disabled]`. When combined with the `.form-check-label` class, we can easily style the text for each item based on the `<input>`'s state.
Our checks use custom Bootstrap icons to indicate checked or indeterminate states.
<script>
document.addEventListener("DOMContentLoaded", function() {
var checkbox = document.getElementById("flexCheckIndeterminate");
checkbox.indeterminate = true;
});
</script>
## Checks
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
<label class="form-check-label" for="flexCheckDefault">
Default checkbox
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckChecked" checked>
<label class="form-check-label" for="flexCheckChecked">
Checked checkbox
</label>
</div>
{{< /example >}}
### Indeterminate
Checkboxes can utilize the `:indeterminate` pseudo class when manually set via JavaScript (there is no available HTML attribute for specifying it).
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
<label class="form-check-label" for="flexCheckIndeterminate">
Indeterminate checkbox
</label>
</div>
{{< /example >}}
### Disabled
Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state.
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckDisabled" disabled>
<label class="form-check-label" for="flexCheckDisabled">
Disabled checkbox
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckCheckedDisabled" checked disabled>
<label class="form-check-label" for="flexCheckCheckedDisabled">
Disabled checked checkbox
</label>
</div>
{{< /example >}}
## Radios
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault1">
<label class="form-check-label" for="flexRadioDefault1">
Default radio
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault2" checked>
<label class="form-check-label" for="flexRadioDefault2">
Default checked radio
</label>
</div>
{{< /example >}}
### Disabled
Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state.
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="radio" name="flexRadioDisabled" id="flexRadioDisabled" disabled>
<label class="form-check-label" for="flexRadioDisabled">
Disabled radio
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="flexRadioDisabled" id="flexRadioCheckedDisabled" checked disabled>
<label class="form-check-label" for="flexRadioCheckedDisabled">
Disabled checked radio
</label>
</div>
{{< /example >}}
## Switches
A switch has the markup of a custom checkbox but uses the `.form-switch` class to render a toggle switch. Switches also support the `disabled` attribute.
{{< example >}}
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="flexSwitchCheckDefault">
<label class="form-check-label" for="flexSwitchCheckDefault">Default switch checkbox input</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="flexSwitchCheckChecked" checked>
<label class="form-check-label" for="flexSwitchCheckChecked">Checked switch checkbox input</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="flexSwitchCheckDisabled" disabled>
<label class="form-check-label" for="flexSwitchCheckDisabled">Disabled switch checkbox input</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="flexSwitchCheckCheckedDisabled" checked disabled>
<label class="form-check-label" for="flexSwitchCheckCheckedDisabled">Disabled checked switch checkbox input</label>
</div>
{{< /example >}}
## Default (stacked)
By default, any number of checkboxes and radios that are immediate sibling will be vertically stacked and appropriately spaced with `.form-check`.
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
<label class="form-check-label" for="defaultCheck1">
Default checkbox
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck2" disabled>
<label class="form-check-label" for="defaultCheck2">
Disabled checkbox
</label>
</div>
{{< /example >}}
{{< example >}}
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios1" value="option1" checked>
<label class="form-check-label" for="exampleRadios1">
Default radio
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios2" value="option2">
<label class="form-check-label" for="exampleRadios2">
Second default radio
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled>
<label class="form-check-label" for="exampleRadios3">
Disabled radio
</label>
</div>
{{< /example >}}
## Inline
Group checkboxes or radios on the same horizontal row by adding `.form-check-inline` to any `.form-check`.
{{< example >}}
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
<label class="form-check-label" for="inlineCheckbox1">1</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2">
<label class="form-check-label" for="inlineCheckbox2">2</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3" disabled>
<label class="form-check-label" for="inlineCheckbox3">3 (disabled)</label>
</div>
{{< /example >}}
{{< example >}}
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1">
<label class="form-check-label" for="inlineRadio1">1</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2">
<label class="form-check-label" for="inlineRadio2">2</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3" disabled>
<label class="form-check-label" for="inlineRadio3">3 (disabled)</label>
</div>
{{< /example >}}
## Without labels
Add `.position-static` to inputs within `.form-check` that don't have any label text. Remember to still provide some form of label for assistive technologies (for instance, using `aria-label`).
{{< example >}}
<div class="form-check">
<input class="form-check-input position-static" type="checkbox" id="blankCheckbox" value="option1" aria-label="...">
</div>
<div class="form-check">
<input class="form-check-input position-static" type="radio" name="blankRadio" id="blankRadio1" value="option1" aria-label="...">
</div>
{{< /example >}}

View File

@ -0,0 +1,37 @@
---
layout: docs
title: File browser
description: Use our custom file inputs for consistent cross-browser styling, built-in customization, and lightweight JavaScript.
group: forms
toc: false
---
{{< callout info >}}
The recommended plugin to animate custom file input: [bs-custom-file-input](https://www.npmjs.com/package/bs-custom-file-input), that's what we are using currently here in our docs.
{{< /callout >}}
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.
{{< example >}}
<div class="form-file">
<input type="file" class="form-file-input" id="customFile">
<label class="form-file-label" for="customFile">
<span class="form-file-text">Choose file...</span>
<span class="form-file-button">Browse</span>
</label>
</div>
{{< /example >}}
Longer placeholder text is truncated and an ellipsis is added when there's not enough space.
{{< example >}}
<div class="form-file">
<input type="file" class="form-file-input" id="customFileLong">
<label class="form-file-label" for="customFileLong">
<span class="form-file-text">Lorem ipsum posuere consectetur est at lobortis nulla vitae elit libero a pharetra augue fusce dapibus tellus ac cursus commodo tortor mauris condimentum nibh ut fermentum massa justo sit amet risus cras mattis consectetur purus sit amet fermentum</span>
<span class="form-file-button">Browse</span>
</label>
</div>
{{< /example >}}
We hide the default file `<input>` via `opacity` and instead style the `<label>`. The button is generated and positioned with `::after`. Lastly, we declare a `width` and `height` on the `<input>` for proper spacing for surrounding content.

View File

@ -0,0 +1,75 @@
---
layout: docs
title: Form controls
description: Give textual form controls like `<input>`s and `<textarea>`s an upgrade with custom styles, sizing, focus states, and more.
group: forms
toc: true
---
## Example
{{< example >}}
<form>
<div class="mb-3">
<label for="exampleFormControlInput1">Email address</label>
<input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1">Example textarea</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
</form>
{{< /example >}}
## Sizing
Set heights using classes like `.form-control-lg` and `.form-control-sm`.
{{< example >}}
<input class="form-control form-control-lg" type="text" placeholder=".form-control-lg">
<input class="form-control" type="text" placeholder="Default input">
<input class="form-control form-control-sm" type="text" placeholder=".form-control-sm">
{{< /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 >}}
<input class="form-control" type="text" placeholder="Readonly input here..." readonly>
{{< /example >}}
## Readonly plain text
If you want to have `<input readonly>` 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 >}}
<form>
<div class="mb-3 row">
<label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="text" readonly class="form-control-plaintext" id="staticEmail" value="email@example.com">
</div>
</div>
<div class="mb-3 row">
<label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword">
</div>
</div>
</form>
{{< /example >}}
{{< example >}}
<form class="form-inline">
<div class="mb-3 mb-2">
<label for="staticEmail2" class="sr-only">Email</label>
<input type="text" readonly class="form-control-plaintext" id="staticEmail2" value="email@example.com">
</div>
<div class="mb-3 mx-sm-3 mb-2">
<label for="inputPassword2" class="sr-only">Password</label>
<input type="password" class="form-control" id="inputPassword2" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary mb-2">Confirm identity</button>
</form>
{{< /example >}}

View File

@ -2,7 +2,7 @@
layout: docs
title: Input group
description: Easily extend form controls by adding text, buttons, or button groups on either side of textual inputs, custom selects, and custom file inputs.
group: components
group: forms
toc: true
---
@ -268,7 +268,7 @@ Input groups include support for custom selects and custom file inputs. Browser
<div class="input-group-prepend">
<label class="input-group-text" for="inputGroupSelect01">Options</label>
</div>
<select class="custom-select" id="inputGroupSelect01">
<select class="form-select" id="inputGroupSelect01">
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
@ -277,7 +277,7 @@ Input groups include support for custom selects and custom file inputs. Browser
</div>
<div class="input-group mb-3">
<select class="custom-select" id="inputGroupSelect02">
<select class="form-select" id="inputGroupSelect02">
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
@ -292,7 +292,7 @@ Input groups include support for custom selects and custom file inputs. Browser
<div class="input-group-prepend">
<button class="btn btn-outline-secondary" type="button">Button</button>
</div>
<select class="custom-select" id="inputGroupSelect03" aria-label="Example select with button addon">
<select class="form-select" id="inputGroupSelect03" aria-label="Example select with button addon">
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
@ -301,7 +301,7 @@ Input groups include support for custom selects and custom file inputs. Browser
</div>
<div class="input-group">
<select class="custom-select" id="inputGroupSelect04" aria-label="Example select with button addon">
<select class="form-select" id="inputGroupSelect04" aria-label="Example select with button addon">
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
@ -320,21 +320,21 @@ Input groups include support for custom selects and custom file inputs. Browser
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupFileAddon01">Upload</span>
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
<label class="custom-file-label" for="inputGroupFile01">
<span class="custom-file-text">Choose file...</span>
<span class="custom-file-button">Browse</span>
<div class="form-file">
<input type="file" class="form-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
<label class="form-file-label" for="inputGroupFile01">
<span class="form-file-text">Choose file...</span>
<span class="form-file-button">Browse</span>
</label>
</div>
</div>
<div class="input-group mb-3">
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputGroupFile02">
<label class="custom-file-label" for="inputGroupFile02" aria-describedby="inputGroupFileAddon02">
<span class="custom-file-text">Choose file...</span>
<span class="custom-file-button">Browse</span>
<div class="form-file">
<input type="file" class="form-file-input" id="inputGroupFile02">
<label class="form-file-label" for="inputGroupFile02" aria-describedby="inputGroupFileAddon02">
<span class="form-file-text">Choose file...</span>
<span class="form-file-button">Browse</span>
</label>
</div>
<div class="input-group-append">
@ -346,21 +346,21 @@ Input groups include support for custom selects and custom file inputs. Browser
<div class="input-group-prepend">
<button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon03">Button</button>
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputGroupFile03" aria-describedby="inputGroupFileAddon03">
<label class="custom-file-label" for="inputGroupFile03">
<span class="custom-file-text">Choose file...</span>
<span class="custom-file-button">Browse</span>
<div class="form-file">
<input type="file" class="form-file-input" id="inputGroupFile03" aria-describedby="inputGroupFileAddon03">
<label class="form-file-label" for="inputGroupFile03">
<span class="form-file-text">Choose file...</span>
<span class="form-file-button">Browse</span>
</label>
</div>
</div>
<div class="input-group">
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04">
<label class="custom-file-label" for="inputGroupFile04">
<span class="custom-file-text">Choose file...</span>
<span class="custom-file-button">Browse</span>
<div class="form-file">
<input type="file" class="form-file-input" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04">
<label class="form-file-label" for="inputGroupFile04">
<span class="form-file-text">Choose file...</span>
<span class="form-file-button">Browse</span>
</label>
</div>
<div class="input-group-append">

View File

@ -0,0 +1,388 @@
---
layout: docs
title: Layout
description: Give your forms some structure—from inline to horizontal to custom grid implementations—with our form layout options.
group: forms
toc: true
---
## Forms
Every group of form fields should reside in a `<form>` element. Bootstrap provides no default styling for the `<form>` element, but there are some powerful browser features that are provided by default.
- New to browser forms? Consider reviewing [the MDN form docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) for an overview and complete list of available attributes.
- `<button>`s within a `<form>` default to `type="submit"`, so strive to be specific and always include a `type`.
- You can disable every form element within a form with the `disabled` attribute on the `<form>`.
Since Bootstrap applies `display: block` and `width: 100%` to almost all our form controls, forms will by default stack vertically. Additional classes can be used to vary this layout on a per-form basis.
## Utilities
[Margin utilities]({{< docsref "/utilities/spacing" >}}) are the easiest way to add some structure to forms. They provide basic grouping of labels, controls, optional help text, and form validation messaging. We recommend sticking to `margin-bottom` utilities, and using a single direction throughout the form for consistency.
Feel free to build your forms however you like, with `<fieldset>`s, `<div>`s, or nearly any other element.
{{< example >}}
<form>
<div class="mb-3">
<label for="formGroupExampleInput">Example label</label>
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input placeholder">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2">Another label</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input placeholder">
</div>
</form>
{{< /example >}}
## Form grid
More complex forms can be built using our grid classes. Use these for form layouts that require multiple columns, varied widths, and additional alignment options. **Requires the `$enable-grid-classes` Sass variable to be enabled** (on by default).
{{< example >}}
<form>
<div class="row">
<div class="col">
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Last name">
</div>
</div>
</form>
{{< /example >}}
## Form row
You may also swap `.row` for `.form-row`, a variation of our standard grid row that overrides the default column gutters for tighter and more compact layouts. **Also requires the `$enable-grid-classes` Sass variable to be enabled** (on by default).
{{< example >}}
<form>
<div class="form-row">
<div class="col">
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Last name">
</div>
</div>
</form>
{{< /example >}}
More complex layouts can also be created with the grid system.
{{< example >}}
<form>
<div class="form-row">
<div class="mb-3 col-md-6">
<label for="inputEmail4">Email</label>
<input type="email" class="form-control" id="inputEmail4">
</div>
<div class="mb-3 col-md-6">
<label for="inputPassword4">Password</label>
<input type="password" class="form-control" id="inputPassword4">
</div>
</div>
<div class="mb-3">
<label for="inputAddress">Address</label>
<input type="text" class="form-control" id="inputAddress" placeholder="1234 Main St">
</div>
<div class="mb-3">
<label for="inputAddress2">Address 2</label>
<input type="text" class="form-control" id="inputAddress2" placeholder="Apartment, studio, or floor">
</div>
<div class="form-row">
<div class="mb-3 col-md-6">
<label for="inputCity">City</label>
<input type="text" class="form-control" id="inputCity">
</div>
<div class="mb-3 col-md-4">
<label for="inputState">State</label>
<select id="inputState" class="form-select">
<option selected>Choose...</option>
<option>...</option>
</select>
</div>
<div class="mb-3 col-md-2">
<label for="inputZip">Zip</label>
<input type="text" class="form-control" id="inputZip">
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck">
Check me out
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
</form>
{{< /example >}}
## Horizontal form
Create horizontal forms with the grid by adding the `.row` class to form groups and using the `.col-*-*` classes to specify the width of your labels and controls. Be sure to add `.col-form-label` to your `<label>`s as well so they're vertically centered with their associated form controls.
At times, you maybe need to use margin or padding utilities to create that perfect alignment you need. For example, we've removed the `padding-top` on our stacked radio inputs label to better align the text baseline.
{{< example >}}
<form>
<div class="mb-3 row">
<label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3">
</div>
</div>
<div class="mb-3 row">
<label for="inputPassword3" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3">
</div>
</div>
<fieldset class="mb-3">
<div class="row">
<legend class="col-form-label col-sm-2 pt-0">Radios</legend>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
<label class="form-check-label" for="gridRadios1">
First radio
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
<label class="form-check-label" for="gridRadios2">
Second radio
</label>
</div>
<div class="form-check disabled">
<input class="form-check-input" type="radio" name="gridRadios" id="gridRadios3" value="option3" disabled>
<label class="form-check-label" for="gridRadios3">
Third disabled radio
</label>
</div>
</div>
</div>
</fieldset>
<div class="mb-3 row">
<div class="col-sm-2">Checkbox</div>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck1">
<label class="form-check-label" for="gridCheck1">
Example checkbox
</label>
</div>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</div>
</form>
{{< /example >}}
### Horizontal form label sizing
Be sure to use `.col-form-label-sm` or `.col-form-label-lg` to your `<label>`s or `<legend>`s to correctly follow the size of `.form-control-lg` and `.form-control-sm`.
{{< example >}}
<form>
<div class="mb-3 row">
<label for="colFormLabelSm" class="col-sm-2 col-form-label col-form-label-sm">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control form-control-sm" id="colFormLabelSm" placeholder="col-form-label-sm">
</div>
</div>
<div class="mb-3 row">
<label for="colFormLabel" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="colFormLabel" placeholder="col-form-label">
</div>
</div>
<div class="mb-3 row">
<label for="colFormLabelLg" class="col-sm-2 col-form-label col-form-label-lg">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control form-control-lg" id="colFormLabelLg" placeholder="col-form-label-lg">
</div>
</div>
</form>
{{< /example >}}
## Column sizing
As shown in the previous examples, our grid system allows you to place any number of `.col`s within a `.row` or `.form-row`. They'll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining `.col`s equally split the rest, with specific column classes like `.col-7`.
{{< example >}}
<form>
<div class="form-row">
<div class="col-7">
<input type="text" class="form-control" placeholder="City">
</div>
<div class="col">
<input type="text" class="form-control" placeholder="State">
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Zip">
</div>
</div>
</form>
{{< /example >}}
## Auto-sizing
The example below uses a flexbox utility to vertically center the contents and changes `.col` to `.col-auto` so that your columns only take up as much space as needed. Put another way, the column sizes itself based on the contents.
{{< example >}}
<form>
<div class="form-row align-items-center">
<div class="col-auto">
<label class="sr-only" for="inlineFormInput">Name</label>
<input type="text" class="form-control mb-2" id="inlineFormInput" placeholder="Jane Doe">
</div>
<div class="col-auto">
<label class="sr-only" for="inlineFormInputGroup">Username</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
</div>
</div>
<div class="col-auto">
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="autoSizingCheck">
<label class="form-check-label" for="autoSizingCheck">
Remember me
</label>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary mb-2">Submit</button>
</div>
</div>
</form>
{{< /example >}}
You can then remix that once again with size-specific column classes.
{{< example >}}
<form>
<div class="form-row align-items-center">
<div class="col-sm-3 my-1">
<label class="sr-only" for="inlineFormInputName">Name</label>
<input type="text" class="form-control" id="inlineFormInputName" placeholder="Jane Doe">
</div>
<div class="col-sm-3 my-1">
<label class="sr-only" for="inlineFormInputGroupUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="Username">
</div>
</div>
<div class="col-auto my-1">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="autoSizingCheck2">
<label class="form-check-label" for="autoSizingCheck2">
Remember me
</label>
</div>
</div>
<div class="col-auto my-1">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
{{< /example >}}
And of course [custom form controls](#custom-forms) are supported.
{{< example >}}
<form>
<div class="form-row align-items-center">
<div class="col-auto my-1">
<label class="mr-sm-2 sr-only" for="inlineFormSelect">Preference</label>
<select class="form-select mr-sm-2" id="inlineFormSelect">
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
<div class="col-auto my-1">
<div class="form-check mr-sm-2">
<input type="checkbox" class="form-check-input" id="formCheckAutosizing">
<label class="form-check-label" for="formCheckAutosizing">Remember my preference</label>
</div>
</div>
<div class="col-auto my-1">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
{{< /example >}}
## Inline forms
Use the `.form-inline` class to display a series of labels, form controls, and buttons on a single horizontal row. Form controls within inline forms vary slightly from their default states.
- Controls are `display: flex`, collapsing any HTML white space and allowing you to provide alignment control with [spacing]({{< docsref "/utilities/spacing" >}}) and [flexbox]({{< docsref "/utilities/flex" >}}) utilities.
- Controls and input groups receive `width: auto` to override the Bootstrap default `width: 100%`.
- Controls **only appear inline in viewports that are at least 576px wide** to account for narrow viewports on mobile devices.
You may need to manually address the width and alignment of individual form controls with [spacing utilities]({{< docsref "/utilities/spacing" >}}) (as shown below). Lastly, be sure to always include a `<label>` with each form control, even if you need to hide it from non-screenreader visitors with `.sr-only`.
{{< example >}}
<form class="form-inline">
<label class="sr-only" for="inlineFormInputName2">Name</label>
<input type="text" class="form-control mb-2 mr-sm-2" id="inlineFormInputName2" placeholder="Jane Doe">
<label class="sr-only" for="inlineFormInputGroupUsername2">Username</label>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername2" placeholder="Username">
</div>
<div class="form-check mb-2 mr-sm-2">
<input class="form-check-input" type="checkbox" id="inlineFormCheck">
<label class="form-check-label" for="inlineFormCheck">
Remember me
</label>
</div>
<button type="submit" class="btn btn-primary mb-2">Submit</button>
</form>
{{< /example >}}
Custom form controls and selects are also supported.
{{< example >}}
<form class="form-inline">
<label class="my-1 mr-2" for="inlineFormSelectPref">Preference</label>
<select class="form-select my-1 mr-sm-2" id="inlineFormSelectPref">
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div class="form-check my-1 mr-sm-2">
<input type="checkbox" class="form-check-input" id="formCheckInline">
<label class="form-check-label" for="formCheckInline">Remember my preference</label>
</div>
<button type="submit" class="btn btn-primary my-1">Submit</button>
</form>
{{< /example >}}
{{< callout warning >}}
### Alternatives to hidden labels
Assistive technologies such as screen readers will have trouble with your forms if you don't include a label for every input. For these inline forms, you can hide the labels using the `.sr-only` class. There are further alternative methods of providing a label for assistive technologies, such as the `aria-label`, `aria-labelledby` or `title` attribute. If none of these are present, assistive technologies may resort to using the `placeholder` attribute, if present, but note that use of `placeholder` as a replacement for other labelling methods is not advised.
{{< /callout >}}

View File

@ -0,0 +1,123 @@
---
layout: docs
title: Forms
description: Examples and usage guidelines for form control styles, layout options, and custom components for creating a wide variety of forms.
group: forms
toc: true
sections:
- title: Form control
description: Style textual inputs and textareas with support for multiple states.
- title: Select
description: Improve browser default select elements with a custom initial appearance.
- title: Checks
description: Use our custom radio buttons and checkboxes in forms for selecting input options.
- title: File
description: Replace browser default file inputs with our custom version with optional JavaScript.
- title: Range
description: Replace browser default range inputs with our custom version.
- title: Input group
description: Attach labels and buttons to your inputs for increased semantic value.
- title: Layout
description: Create inline, horizontal, or complex grid-based layouts with your forms.
- title: Validation
description: Validate your forms with custom or native validation behaviors and styles.
---
## Overview
Bootstrap's form controls expand on [our Rebooted form styles]({{< docsref "/content/reboot#forms" >}}) with classes. Use these classes to opt into their customized displays for a more consistent rendering across browsers and devices.
Be sure to use an appropriate `type` attribute on all inputs (e.g., `email` for email address or `number` for numerical information) to take advantage of newer input controls like email verification, number selection, and more.
Here's a quick example to demonstrate Bootstrap's form styles. Keep reading for documentation on required classes, form layout, and more.
{{< example >}}
<form>
<div class="mb-3">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="mb-3">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1">
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">Check me out</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{{< /example >}}
## Help text
Block-level help text in forms can be created using `.form-text` (previously known as `.help-block` in v3). Inline help text can be flexibly implemented using any inline HTML element and utility classes like `.text-muted`.
{{< callout warning >}}
##### Associating help text with form controls
Help text should be explicitly associated with the form control it relates to using the `aria-describedby` attribute. This will ensure that assistive technologies—such as screen readers—will announce this help text when the user focuses or enters the control.
{{< /callout >}}
Help text below inputs can be styled with `.form-text`. This class includes `display: block` and adds some top margin for easy spacing from the inputs above.
{{< example >}}
<label for="inputPassword5">Password</label>
<input type="password" id="inputPassword5" class="form-control" aria-describedby="passwordHelpBlock">
<small id="passwordHelpBlock" class="form-text text-muted">
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
</small>
{{< /example >}}
Inline text can use any typical inline HTML element (be it a `<small>`, `<span>`, or something else) with nothing more than a utility class.
{{< example >}}
<form class="form-inline">
<div class="mb-3">
<label for="inputPassword6">Password</label>
<input type="password" id="inputPassword6" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
<small id="passwordHelpInline" class="text-muted">
Must be 8-20 characters long.
</small>
</div>
</form>
{{< /example >}}
## Disabled forms
Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter.
{{< highlight html >}}
<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
{{< /highlight >}}
Add the `disabled` attribute to a `<fieldset>` to disable all the controls within.
By default, browsers will treat all native form controls (`<input>`, `<select>`, and `<button>` elements) inside a `<fieldset disabled>` as disabled, preventing both keyboard and mouse interactions on them. However, if your form also includes `<a ... class="btn btn-*">` elements, these will only be given a style of `pointer-events: none`.
{{< example >}}
<form>
<fieldset disabled>
<div class="mb-3">
<label for="disabledTextInput">Disabled input</label>
<input type="text" id="disabledTextInput" class="form-control" placeholder="Disabled input">
</div>
<div class="mb-3">
<label for="disabledSelect">Disabled select menu</label>
<select id="disabledSelect" class="form-select">
<option>Disabled select</option>
</select>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="disabledFieldsetCheck" disabled>
<label class="form-check-label" for="disabledFieldsetCheck">
Can't check this
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</fieldset>
</form>
{{< /example >}}

View File

@ -0,0 +1,34 @@
---
layout: docs
title: Range
description: Use our custom range inputs for consistent cross-browser styling and built-in customization.
group: forms
toc: true
---
## Overview
Create custom `<input type="range">` controls with `.form-range`. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only Firefox supports "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 >}}
<label for="customRange1">Example range</label>
<input type="range" class="form-range" id="customRange1">
{{< /example >}}
## Min and max
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 >}}
<label for="customRange2">Example range</label>
<input type="range" class="form-range" min="0" max="5" id="customRange2">
{{< /example >}}
## Steps
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 >}}
<label for="customRange3">Example range</label>
<input type="range" class="form-range" min="0" max="5" step="0.5" id="customRange3">
{{< /example >}}

View File

@ -0,0 +1,62 @@
---
layout: docs
title: Select
description: Customize the native `<select>`s with custom CSS that changes the element's initial appearance.
group: forms
toc: true
---
## Default
Custom `<select>` menus need only a custom class, `.form-select` to trigger the custom styles. Custom styles are limited to the `<select>`'s initial appearance and cannot modify the `<option>`s due to browser limitations.
{{< example >}}
<select class="form-select">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
{{< /example >}}
## Sizing
You may also choose from small and large custom selects to match our similarly sized text inputs.
{{< example >}}
<select class="form-select form-select-lg mb-3">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select class="form-select form-select-sm">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
{{< /example >}}
The `multiple` attribute is also supported:
{{< example >}}
<select class="form-select" multiple>
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
{{< /example >}}
As is the `size` attribute:
{{< example >}}
<select class="form-select" size="3">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
{{< /example >}}

View File

@ -0,0 +1,404 @@
---
layout: docs
title: Validation
description: Provide valuable, actionable feedback to your users with HTML5 form validation, via browser default behaviors or custom styles and JavaScript.
group: forms
toc: true
---
{{< callout warning >}}
We currently recommend using custom validation styles, as native browser default validation messages are not consistently exposed to assistive technologies in all browsers (most notably, Chrome on desktop and mobile).
{{< /callout >}}
## How it works
Here's how form validation works with Bootstrap:
- HTML form validation is applied via CSS's two pseudo-classes, `:invalid` and `:valid`. It applies to `<input>`, `<select>`, and `<textarea>` elements.
- Bootstrap scopes the `:invalid` and `:valid` styles to parent `.was-validated` class, usually applied to the `<form>`. Otherwise, any required field without a value shows up as invalid on page load. This way, you may choose when to activate them (typically after form submission is attempted).
- To reset the appearance of the form (for instance, in the case of dynamic form submissions using AJAX), remove the `.was-validated` class from the `<form>` again after submission.
- As a fallback, `.is-invalid` and `.is-valid` classes may be used instead of the pseudo-classes for [server-side validation](#server-side). They do not require a `.was-validated` parent class.
- Due to constraints in how CSS works, we cannot (at present) apply styles to a `<label>` that comes before a form control in the DOM without the help of custom JavaScript.
- All modern browsers support the [constraint validation API](https://www.w3.org/TR/html5/sec-forms.html#the-constraint-validation-api), a series of JavaScript methods for validating form controls.
- Feedback messages may utilize the [browser defaults](#browser-defaults) (different for each browser, and unstylable via CSS) or our custom feedback styles with additional HTML and CSS.
- You may provide custom validity messages with `setCustomValidity` in JavaScript.
With that in mind, consider the following demos for our custom form validation styles, optional server-side classes, and browser defaults.
## Custom styles
For custom Bootstrap form validation messages, you'll need to add the `novalidate` boolean attribute to your `<form>`. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback. Background icons for `<select>`s are only available with `.form-select`, and not `.form-control`.
{{< example >}}
<form class="needs-validation" novalidate>
<div class="form-row">
<div class="col-md-4 mb-3">
<label for="validationCustom01">First name</label>
<input type="text" class="form-control" id="validationCustom01" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4 mb-3">
<label for="validationCustom02">Last name</label>
<input type="text" class="form-control" id="validationCustom02" value="Otto" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4 mb-3">
<label for="validationCustomUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend">@</span>
</div>
<input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
<label for="validationCustom03">City</label>
<input type="text" class="form-control" id="validationCustom03" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="validationCustom04">State</label>
<select class="form-select" id="validationCustom04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-feedback">
Please select a valid state.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="validationCustom05">Zip</label>
<input type="text" class="form-control" id="validationCustom05" required>
<div class="invalid-feedback">
Please provide a valid zip.
</div>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
<label class="form-check-label" for="invalidCheck">
Agree to terms and conditions
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
{{< /example >}}
## Browser defaults
Not interested in custom validation feedback messages or writing JavaScript to change form behaviors? All good, you can use the browser defaults. Try submitting the form below. Depending on your browser and OS, you'll see a slightly different style of feedback.
While these feedback styles cannot be styled with CSS, you can still customize the feedback text through JavaScript.
{{< example >}}
<form>
<div class="form-row">
<div class="col-md-4 mb-3">
<label for="validationDefault01">First name</label>
<input type="text" class="form-control" id="validationDefault01" value="Mark" required>
</div>
<div class="col-md-4 mb-3">
<label for="validationDefault02">Last name</label>
<input type="text" class="form-control" id="validationDefault02" value="Otto" required>
</div>
<div class="col-md-4 mb-3">
<label for="validationDefaultUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend2">@</span>
</div>
<input type="text" class="form-control" id="validationDefaultUsername" aria-describedby="inputGroupPrepend2" required>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
<label for="validationDefault03">City</label>
<input type="text" class="form-control" id="validationDefault03" required>
</div>
<div class="col-md-3 mb-3">
<label for="validationDefault04">State</label>
<select class="form-select" id="validationDefault04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
</div>
<div class="col-md-3 mb-3">
<label for="validationDefault05">Zip</label>
<input type="text" class="form-control" id="validationDefault05" required>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck2" required>
<label class="form-check-label" for="invalidCheck2">
Agree to terms and conditions
</label>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
{{< /example >}}
## Server side
We recommend using client-side validation, but in case you require server-side validation, you can indicate invalid and valid form fields with `.is-invalid` and `.is-valid`. Note that `.invalid-feedback` is also supported with these classes.
{{< example >}}
<form>
<div class="form-row">
<div class="col-md-4 mb-3">
<label for="validationServer01">First name</label>
<input type="text" class="form-control is-valid" id="validationServer01" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4 mb-3">
<label for="validationServer02">Last name</label>
<input type="text" class="form-control is-valid" id="validationServer02" value="Otto" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4 mb-3">
<label for="validationServerUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend3">@</span>
</div>
<input type="text" class="form-control is-invalid" id="validationServerUsername" aria-describedby="inputGroupPrepend3" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
<label for="validationServer03">City</label>
<input type="text" class="form-control is-invalid" id="validationServer03" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="validationServer04">State</label>
<select class="form-select is-invalid" id="validationServer04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-feedback">
Please select a valid state.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="validationServer05">Zip</label>
<input type="text" class="form-control is-invalid" id="validationServer05" required>
<div class="invalid-feedback">
Please provide a valid zip.
</div>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input is-invalid" type="checkbox" value="" id="invalidCheck3" required>
<label class="form-check-label" for="invalidCheck3">
Agree to terms and conditions
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
{{< /example >}}
## Supported elements
Validation styles are available for the following form controls and components:
- `<input>`s and `<textarea>`s with `.form-control` (including up to one `.form-control` in input groups)
- `<select>`s with `.form-control` or `.form-select`
- `.form-check`s
- `.custom-checkbox`s and `.custom-radio`s
- `.form-file`
{{< example >}}
<form class="was-validated">
<div class="mb-3">
<label for="validationTextarea">Textarea</label>
<textarea class="form-control is-invalid" id="validationTextarea" placeholder="Required example textarea" required></textarea>
<div class="invalid-feedback">
Please enter a message in the textarea.
</div>
</div>
<div class="custom-control custom-checkbox mb-3">
<input type="checkbox" class="custom-control-input" id="customControlValidation1" required>
<label class="custom-control-label" for="customControlValidation1">Check this custom checkbox</label>
<div class="invalid-feedback">Example invalid feedback text</div>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="customControlValidation2" name="radio-stacked" required>
<label class="custom-control-label" for="customControlValidation2">Toggle this custom radio</label>
</div>
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" id="customControlValidation3" name="radio-stacked" required>
<label class="custom-control-label" for="customControlValidation3">Or toggle this other custom radio</label>
<div class="invalid-feedback">More example invalid feedback text</div>
</div>
<div class="mb-3">
<select class="form-select" required>
<option value="">Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div class="invalid-feedback">Example invalid custom select feedback</div>
</div>
<div class="form-file">
<input type="file" class="form-file-input" id="validatedCustomFile" required>
<label class="form-file-label" for="validatedCustomFile">Choose file...</label>
<div class="invalid-feedback">Example invalid custom file feedback</div>
</div>
</form>
{{< /example >}}
## Tooltips
If your form layout allows it, you can swap the `.{valid|invalid}-feedback` classes for `.{valid|invalid}-tooltip` classes to display validation feedback in a styled tooltip. Be sure to have a parent with `position: relative` on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup.
{{< example >}}
<form class="needs-validation" novalidate>
<div class="form-row">
<div class="col-md-4 mb-3">
<label for="validationTooltip01">First name</label>
<input type="text" class="form-control" id="validationTooltip01" value="Mark" required>
<div class="valid-tooltip">
Looks good!
</div>
</div>
<div class="col-md-4 mb-3">
<label for="validationTooltip02">Last name</label>
<input type="text" class="form-control" id="validationTooltip02" value="Otto" required>
<div class="valid-tooltip">
Looks good!
</div>
</div>
<div class="col-md-4 mb-3">
<label for="validationTooltipUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="validationTooltipUsernamePrepend">@</span>
</div>
<input type="text" class="form-control" id="validationTooltipUsername" aria-describedby="validationTooltipUsernamePrepend" required>
<div class="invalid-tooltip">
Please choose a unique and valid username.
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
<label for="validationTooltip03">City</label>
<input type="text" class="form-control" id="validationTooltip03" required>
<div class="invalid-tooltip">
Please provide a valid city.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="validationTooltip04">State</label>
<select class="form-select" id="validationTooltip04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-tooltip">
Please select a valid state.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="validationTooltip05">Zip</label>
<input type="text" class="form-control" id="validationTooltip05" required>
<div class="invalid-tooltip">
Please provide a valid zip.
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
{{< /example >}}
## Customizing
Validation states can be customized via Sass with the `$form-validation-states` map. Located in our `_variables.scss` file, this Sass map is looped over to generate the default `valid`/`invalid` validation states. Included is a nested map for customizing each state's color and icon. While no other states are supported by browsers, those using custom styles can easily add more complex form feedback.
Please note that we do not recommend customizing these values without also modifying the `form-validation-state` mixin.
{{< highlight scss >}}
// Sass map from `_variables.scss`
// Override this and recompile your Sass to generate different states
$form-validation-states: map-merge(
(
"valid": (
"color": $form-feedback-valid-color,
"icon": $form-feedback-icon-valid
),
"invalid": (
"color": $form-feedback-invalid-color,
"icon": $form-feedback-icon-invalid
)
),
$form-validation-states
);
// Loop from `_forms.scss`
// Any modifications to the above Sass map will be reflected in your compiled
// CSS via this loop.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}
{{< /highlight >}}

View File

@ -24,10 +24,10 @@ We use [Autoprefixer](https://github.com/postcss/autoprefixer) to handle intende
Generally speaking, Bootstrap supports the latest versions of each major platform's default browsers. Note that proxy browsers (such as Opera Mini, Opera Mobile's Turbo mode, UC Browser Mini, Amazon Silk) are not supported.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<td></td>
<th></th>
<th>Chrome</th>
<th>Firefox</th>
<th>Safari</th>
@ -38,27 +38,27 @@ Generally speaking, Bootstrap supports the latest versions of each major platfor
<tbody>
<tr>
<th scope="row">Android</th>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td class="text-muted">N/A</td>
<td class="text-success">Android v5.0+ supported</td>
<td class="text-success">Supported</td>
<td>Supported</td>
<td>Supported</td>
<td class="text-muted">&mdash;</td>
<td>v5.0+</td>
<td>Supported</td>
</tr>
<tr>
<th scope="row">iOS</th>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td class="text-muted">N/A</td>
<td class="text-success">Supported</td>
<td>Supported</td>
<td>Supported</td>
<td>Supported</td>
<td class="text-muted">&mdash;</td>
<td>Supported</td>
</tr>
<tr>
<th scope="row">Windows 10 Mobile</th>
<td class="text-muted">N/A</td>
<td class="text-muted">N/A</td>
<td class="text-muted">N/A</td>
<td class="text-muted">N/A</td>
<td class="text-success">Supported</td>
<th scope="row" class="text-nowrap">Windows 10 Mobile</th>
<td class="text-muted">&mdash;</td>
<td class="text-muted">&mdash;</td>
<td class="text-muted">&mdash;</td>
<td class="text-muted">&mdash;</td>
<td>Supported</td>
</tr>
</tbody>
</table>
@ -67,10 +67,10 @@ Generally speaking, Bootstrap supports the latest versions of each major platfor
Similarly, the latest versions of most desktop browsers are supported.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<td></td>
<th></th>
<th>Chrome</th>
<th>Firefox</th>
<th>Internet Explorer</th>
@ -82,21 +82,21 @@ Similarly, the latest versions of most desktop browsers are supported.
<tbody>
<tr>
<th scope="row">Mac</th>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td class="text-muted">N/A</td>
<td class="text-muted">N/A</td>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td>Supported</td>
<td>Supported</td>
<td class="text-muted">&mdash;</td>
<td class="text-muted">&mdash;</td>
<td>Supported</td>
<td>Supported</td>
</tr>
<tr>
<th scope="row">Windows</th>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td class="text-success">Supported, IE11</td>
<td class="text-success">Supported</td>
<td class="text-success">Supported</td>
<td class="text-danger">Not supported</td>
<td>Supported</td>
<td>Supported</td>
<td>IE11 only</td>
<td>Supported</td>
<td>Supported</td>
<td class="text-muted">&mdash;</td>
</tr>
</tbody>
</table>

View File

@ -19,15 +19,50 @@ When completed, you'll be able to run the various commands provided from the com
## Using npm scripts
Our [package.json]({{< param repo >}}/blob/v{{< param current_version >}}/package.json) includes the following commands and tasks:
Our [package.json]({{< param repo >}}/blob/v{{< param current_version >}}/package.json) includes numerous tasks for developing the project. Run `npm run` to see all the npm scripts in your terminal. **Primary tasks include:**
| Task | Description |
| --- | --- |
| `npm run dist` | `npm run dist` creates the `/dist/` directory with compiled files. **Uses [Sass](https://sass-lang.com/), [Autoprefixer][autoprefixer], and [terser](https://github.com/terser-js/terser).** |
| `npm test` | Same as `npm run dist` plus it runs tests locally |
| `npm run docs` | Builds and lints CSS and JavaScript for docs. You can then run the documentation locally via `npm run docs-serve`. |
Run `npm run` to see all the npm scripts.
<table class="table">
<thead>
<tr>
<th>Task</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>npm start</code>
</td>
<td>
Compiles CSS and JavaScript, builds the documentation, and starts a local server.
</td>
</tr>
<tr>
<td>
<code>npm run dist</code>
</td>
<td>
Creates the <code>dist/</code> directory with compiled files. Requires <a href="https://sass-lang.com">Sass</a>, <a href="https://github.com/postcss/autoprefixer">Autoprefixer</a>, and <a href="https://github.com/terser-js/terser">terser</a>.
</td>
</tr>
<tr>
<td>
<code>npm test</code>
</td>
<td>
Runs tests locally after running <code>npm run dist</code>
</td>
</tr>
<tr>
<td>
<code>npm run docs</code>
</td>
<td>
Builds and lints CSS and JavaScript for docs. You can then run the documentation locally via <code>npm run docs-serve</code>.
</td>
</tr>
</tbody>
</table>
## Autoprefixer

View File

@ -48,7 +48,7 @@ This is the most basic form of Bootstrap: precompiled files for quick drop-in us
Bootstrap includes a handful of options for including some or all of our compiled CSS.
<table class="table table-bordered">
<table class="table">
<thead>
<tr>
<th scope="col">CSS files</th>
@ -64,30 +64,30 @@ Bootstrap includes a handful of options for including some or all of our compile
<div><code class="font-weight-normal text-nowrap">bootstrap.css</code></div>
<div><code class="font-weight-normal text-nowrap">bootstrap.min.css</code></div>
</th>
<td class="text-success">Included</td>
<td class="text-success">Included</td>
<td class="text-success">Included</td>
<td class="text-success">Included</td>
<td>Included</td>
<td>Included</td>
<td>Included</td>
<td>Included</td>
</tr>
<tr>
<th scope="row">
<div><code class="font-weight-normal text-nowrap">bootstrap-grid.css</code></div>
<div><code class="font-weight-normal text-nowrap">bootstrap-grid.min.css</code></div>
</th>
<td><a class="text-warning" href="{{< docsref "/layout/grid" >}}">Only grid system</a></td>
<td class="bg-light text-muted">Not included</td>
<td class="bg-light text-muted">Not included</td>
<td><a class="text-warning" href="{{< docsref "/utilities/flex" >}}">Only flex utilities</a></td>
<td><a class="text-muted" href="{{< docsref "/layout/grid" >}}">Only grid system</a></td>
<td class="text-muted">&mdash;</td>
<td class="text-muted">&mdash;</td>
<td><a class="text-muted" href="{{< docsref "/utilities/flex" >}}">Only flex utilities</a></td>
</tr>
<tr>
<th scope="row">
<div><code class="font-weight-normal text-nowrap">bootstrap-reboot.css</code></div>
<div><code class="font-weight-normal text-nowrap">bootstrap-reboot.min.css</code></div>
</th>
<td class="bg-light text-muted">Not included</td>
<td><a class="text-warning" href="{{< docsref "/content/reboot" >}}">Only Reboot</a></td>
<td class="bg-light text-muted">Not included</td>
<td class="bg-light text-muted">Not included</td>
<td class="text-muted">&mdash;</td>
<td><a class="text-muted" href="{{< docsref "/content/reboot" >}}">Only Reboot</a></td>
<td class="text-muted">&mdash;</td>
<td class="text-muted">&mdash;</td>
</tr>
</tbody>
</table>
@ -96,7 +96,7 @@ Bootstrap includes a handful of options for including some or all of our compile
Similarly, we have options for including some or all of our compiled JavaScript.
<table class="table table-bordered">
<table class="table">
<thead>
<tr>
<th scope="col">JS files</th>
@ -109,14 +109,14 @@ Similarly, we have options for including some or all of our compiled JavaScript.
<div><code class="font-weight-normal text-nowrap">bootstrap.bundle.js</code></div>
<div><code class="font-weight-normal text-nowrap">bootstrap.bundle.min.js</code></div>
</th>
<td class="text-success">Included</td>
<td>Included</td>
</tr>
<tr>
<th scope="row">
<div><code class="font-weight-normal text-nowrap">bootstrap.js</code></div>
<div><code class="font-weight-normal text-nowrap">bootstrap.min.js</code></div>
</th>
<td class="bg-light text-muted">Not included</td>
<td class="text-muted">&mdash;</td>
</tr>
</tbody>
</table>

View File

@ -53,35 +53,35 @@ While Bootstrap uses `em`s or `rem`s for defining most sizes, `px`s are used for
See how aspects of the Bootstrap grid system work across multiple devices with a handy table.
<table class="table table-bordered table-striped">
<table class="table">
<thead>
<tr>
<th></th>
<th class="text-center">
<th>
Extra small<br>
<small>&lt;576px</small>
<span class="font-weight-normal">&lt;576px</span>
</th>
<th class="text-center">
<th>
Small<br>
<small>&ge;576px</small>
<span class="font-weight-normal">&ge;576px</span>
</th>
<th class="text-center">
<th>
Medium<br>
<small>&ge;768px</small>
<span class="font-weight-normal">&ge;768px</span>
</th>
<th class="text-center">
<th>
Large<br>
<small>&ge;992px</small>
<span class="font-weight-normal">&ge;992px</span>
</th>
<th class="text-center">
<th>
Extra large<br>
<small>&ge;1200px</small>
<span class="font-weight-normal">&ge;1200px</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<th class="text-nowrap" scope="row">Max container width</th>
<th class="text-nowrap" scope="row">Container <code class="font-weight-normal">max-width</code></th>
<td>None (auto)</td>
<td>540px</td>
<td>720px</td>

View File

@ -53,16 +53,25 @@ Changes to any layout tools and our grid system.
Changes to Reboot, typography, tables, and more.
- **Todo:** Make RFS enabled by default
- Reset default horizontal `padding` on `<ul>` and `<ol>` elements from browser default `40px` to `2rem`.
## Forms
- Dropped support for `.form-control-plaintext` inside `.input-group`
- **Todo:** Move forms documentation to it's own top-level section
- **Todo:** Rearrange source Sass files (under `scss/forms/`)
- **Todo:** Combine native and custom checkboxes and radios
- **Todo:** Rewrite checks to support sizing (via `em`/`font-size` or explicit modifier classes)
- **Todo:** Combine native and custom selects
- **Todo:** Combine native and custom file and range inputs
- Rearranged form documentation under its own top-level section.
- Split out old Forms page into several subpages
- Moved input groups docs under new Forms section
- Rearranged source Sass files under `scss/forms/`, including moving over input group styles.
- Combined native and custom checkboxes and radios into single `.form-check` class.
- New checks support sizing via `em`/`font-size` or explicit modifier classes now.
- Dropped `.custom-control` and associated classes.
- Combined native and custom selects into `.form-select`.
- Dropped `.custom-select` and associated classes.
- Dropped native `.form-control-file` and `.form-control-range` components.
- Renamed `.custom-file` to `.form-file` (including variables).
- Refactored `.form-file` markup to resolve some visual bugs while allowing translation and button text changes via HTML instead of CSS.
- Renamed `.custom-range` to `.form-range` (including variables).
- Dropped `.form-group` for margin utilities (we've replaced our docs examples with `.mb-3`).
- Dropped support for `.form-control-plaintext` inside `.input-group`s.
## Components

View File

@ -55,20 +55,64 @@ To hide elements simply use the `.d-none` class or one of the `.d-{sm,md,lg,xl}-
To show an element only on a given interval of screen sizes you can combine one `.d-*-none` class with a `.d-*-*` class, for example `.d-none .d-md-block .d-xl-none` will hide the element for all screen sizes except on medium and large devices.
| Screen Size | Class |
| --- | --- |
| Hidden on all | `.d-none` |
| Hidden only on xs | `.d-none .d-sm-block` |
| Hidden only on sm | `.d-sm-none .d-md-block` |
| Hidden only on md | `.d-md-none .d-lg-block` |
| Hidden only on lg | `.d-lg-none .d-xl-block` |
| Hidden only on xl | `.d-xl-none` |
| Visible on all | `.d-block` |
| Visible only on xs | `.d-block .d-sm-none` |
| Visible only on sm | `.d-none .d-sm-block .d-md-none` |
| Visible only on md | `.d-none .d-md-block .d-lg-none` |
| Visible only on lg | `.d-none .d-lg-block .d-xl-none` |
| Visible only on xl | `.d-none .d-xl-block` |
<table>
<thead>
<tr>
<th>Screen size</th>
<th>Class</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hidden on all</td>
<td><code>.d-none</code></td>
</tr>
<tr>
<td>Hidden only on xs</td>
<td><code>.d-none .d-sm-block</code></td>
</tr>
<tr>
<td>Hidden only on sm</td>
<td><code>.d-sm-none .d-md-block</code></td>
</tr>
<tr>
<td>Hidden only on md</td>
<td><code>.d-md-none .d-lg-block</code></td>
</tr>
<tr>
<td>Hidden only on lg</td>
<td><code>.d-lg-none .d-xl-block</code></td>
</tr>
<tr>
<td>Hidden only on xl</td>
<td><code>.d-xl-none</code></td>
</tr>
<tr>
<td>Visible on all</td>
<td><code>.d-block</code></td>
</tr>
<tr>
<td>Visible only on xs</td>
<td><code>.d-block .d-sm-none</code></td>
</tr>
<tr>
<td>Visible only on sm</td>
<td><code>.d-none .d-sm-block .d-md-none</code></td>
</tr>
<tr>
<td>Visible only on md</td>
<td><code>.d-none .d-md-block .d-lg-none</code></td>
</tr>
<tr>
<td>Visible only on lg</td>
<td><code>.d-none .d-lg-block .d-xl-none</code></td>
</tr>
<tr>
<td>Visible only on xl</td>
<td><code>.d-none .d-xl-block</code></td>
</tr>
</tbody>
</table>
{{< example >}}
<div class="d-lg-none">hide on lg and wider screens</div>

View File

@ -26,6 +26,18 @@
- title: Tables
- title: Figures
- title: Forms
pages:
- title: Overview
- title: Form control
- title: Select
- title: Checks
- title: File
- title: Range
- title: Input group
- title: Layout
- title: Validation
- title: Components
pages:
- title: Alerts
@ -38,8 +50,9 @@
- title: Close icon
- title: Collapse
- title: Dropdowns
- title: Forms
- title: Input group
- title: Icons
# - title: Forms
# - title: Input group
- title: List group
- title: Modal
- title: Navs
@ -59,7 +72,7 @@
- title: Position
- title: Screen readers
- title: Stretched link
- title: Text truncation
# - title: Text
- title: Utilities
pages:
@ -83,8 +96,6 @@
- title: Approach
- title: Icons
- title: Migration
- title: About
pages:
- title: Overview

View File

@ -8,27 +8,59 @@
{{ partial "docs-navbar" . }}
<div class="container-fluid">
<nav class="bd-subnavbar pt-2 pb-3 pb-md-2 mb-4">
<div class="container d-flex align-items-md-center flex-column flex-md-row">
<div class="d-flex align-items-center mb-2 mb-md-0 mr-md-auto">
<a class="link-dark" href="/" onclick="ga('send', 'event', 'Subnav', 'click', 'Bootstrap');">Bootstrap</a>
{{ partial "icons/booticon-chevron-right.svg" (dict "class" "booticon d-inline-block mx-2 flex-shrink-0" "width" "12px" "height" "12px") }}
<a class="link-dark" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Subnav', 'click', 'Documentation');">Documentation</a>
{{ partial "icons/booticon-chevron-right.svg" (dict "class" "booticon d-inline-block mx-2 flex-shrink-0" "width" "12px" "height" "12px") }}
{{ partial "docs-versions" . }}
</div>
<form class="bd-search d-flex align-items-center">
<input type="search" class="form-control" id="search-input" placeholder="Search..." aria-label="Search for..." autocomplete="off" data-docs-version="{{ .Site.Params.docs_version }}">
</form>
</div>
</nav>
<div class="container">
<div class="row flex-xl-nowrap">
<div class="col-md-3 col-xl-2 bd-sidebar">
<div class="col-md-3 bd-sidebar">
{{ partial "docs-sidebar" . }}
</div>
{{ if (eq .Page.Params.toc true) }}
<nav class="d-none d-xl-block col-xl-2 bd-toc" aria-label="Secondary navigation">
{{ .TableOfContents }}
</nav>
{{ end }}
<main class="col-md-9 col-xl-8 py-md-3 pl-md-5 bd-content" role="main">
<main class="col-md-9 py-md-3 pl-md-5 bd-content" role="main">
<h1 class="bd-title" id="content">{{ .Title | markdownify }}</h1>
<p class="bd-lead">{{ .Page.Params.Description | markdownify }}</p>
{{ partial "ads" . }}
{{ if .Page.Params.sections }}
<div class="row my-5">
{{ range .Page.Params.sections }}
<div class="col-md-6 mb-4">
<a class="d-block text-decoration-none" href="../{{ urlize .title }}/">
<strong class="d-block h5 mb-0">{{ .title }}</strong>
<span class="text-secondary">{{ .description }}</span>
</a>
</div>
{{ end }}
</div>
{{ end }}
{{ if (eq .Page.Params.toc true) }}
<strong class="d-block h3 mt-5 mb-3">On this page</strong>
<nav class="bd-toc mb-5" aria-label="Secondary navigation">
{{ .TableOfContents }}
</nav>
{{ end }}
{{ .Content }}
</main>
</div>
</div>
{{ partial "footer" . }}
{{ partial "scripts" . }}
</body>
</html>

View File

@ -8,8 +8,23 @@
{{ partial "docs-navbar" . }}
<header class="d-flex flex-column flex-md-row align-items-md-center p-5 bg-light">
<div class="pt-md-3 pb-md-4">
<nav class="bd-subnavbar pt-2 pb-3 pb-md-2 mb-4">
<div class="container d-flex align-items-md-center flex-column flex-md-row">
<div class="d-flex align-items-center mb-2 mb-md-0 mr-md-auto">
<a class="link-dark" href="/" onclick="ga('send', 'event', 'Subnav', 'click', 'Bootstrap');">Bootstrap</a>
{{ partial "icons/booticon-chevron-right.svg" (dict "class" "booticon d-inline-block mx-2 flex-shrink-0" "width" "12px" "height" "12px") }}
<a class="link-dark" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Subnav', 'click', 'Documentation');">Documentation</a>
{{ partial "icons/booticon-chevron-right.svg" (dict "class" "booticon d-inline-block mx-2 flex-shrink-0" "width" "12px" "height" "12px") }}
{{ partial "docs-versions" . }}
{{ partial "icons/booticon-chevron-right.svg" (dict "class" "booticon d-inline-block mx-2 flex-shrink-0" "width" "12px" "height" "12px") }}
<span class="text-muted">Examples</span>
</div>
{{ partial "docs-search" . }}
</div>
</nav>
<header class="d-flex flex-column flex-md-row align-items-md-center p-5 border-bottom">
<div class="container pt-md-1 pb-md-4">
<h1 class="bd-title mt-0">{{ .Title | markdownify }}</h1>
<p class="bd-lead">{{ .Page.Params.Description | markdownify }}</p>
{{ if eq .Title "Examples" }}
@ -19,8 +34,10 @@
{{ partial "ads" . }}
</header>
<main class="bd-content p-5" id="content" role="main">
{{ .Content }}
<main class="bd-content py-5" id="content" role="main">
<div class="container">
{{ .Content }}
</div>
</main>
{{ partial "footer" . }}

View File

@ -1,6 +1,7 @@
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bd-navbar">
<div class="container" style="padding: 0 15px;">
<a class="navbar-brand mr-0 mr-md-2" href="/" aria-label="Bootstrap">
{{ partial "icons/bootstrap.svg" (dict "class" "d-block" "width" "36" "height" "36") }}
{{ partial "icons/bootstrap-logo-solid.svg" (dict "class" "d-block" "width" "32" "height" "32") }}
</a>
<div class="navbar-nav-scroll">
@ -9,7 +10,7 @@
<a class="nav-link{{ if .IsHome }} active{{ end }}" href="/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Bootstrap');">Home</a>
</li>
<li class="nav-item">
<a class="nav-link{{ if eq .Page.Layout "docs" }} active{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Docs');">Documentation</a>
<a class="nav-link{{ if eq .Page.Layout "docs" }} active{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Docs');">Docs</a>
</li>
<li class="nav-item">
<a class="nav-link{{ if eq .Page.Title "Examples" }} active{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/examples/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Examples');">Examples</a>
@ -27,24 +28,6 @@
</div>
<ul class="navbar-nav ml-md-auto">
<li class="nav-item dropdown">
<a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" id="bd-versions" data-toggle="dropdown" aria-expanded="false">
v{{ .Site.Params.docs_version }}
</a>
<div class="dropdown-menu dropdown-menu-md-right" aria-labelledby="bd-versions">
<a class="dropdown-item active" href="/docs/{{ .Site.Params.docs_version }}/">Latest (4.3.x)</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/4.2/">v4.2.1</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/4.0/">v4.0.0</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="https://v4-alpha.getbootstrap.com/">v4 Alpha 6</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/3.4/">v3.4.1</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/3.3/">v3.3.7</a>
<a class="dropdown-item" href="https://getbootstrap.com/2.3.2/">v2.3.2</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/docs/versions/">All versions</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link p-2" href="{{ .Site.Params.repo }}" target="_blank" rel="noopener" aria-label="GitHub">
{{ partial "icons/github.svg" (dict "class" "navbar-nav-svg" "width" "36" "height" "36") }}
@ -68,4 +51,5 @@
</ul>
<a class="btn btn-bd-download d-none d-lg-inline-block mb-3 mb-md-0 ml-md-3" href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Download</a>
</div>
</header>

View File

@ -0,0 +1,3 @@
<form role="search" class="bd-search d-flex align-items-center">
<input type="search" class="form-control" id="search-input" placeholder="Search v{{ .Site.Params.docs_version }} docs..." aria-label="Search for..." autocomplete="off" data-docs-version="{{ .Site.Params.docs_version }}">
</form>

View File

@ -1,14 +1,8 @@
<form role="search" class="bd-search d-flex align-items-center">
<input type="search" class="form-control" id="search-input" placeholder="Search..." aria-label="Search for..." autocomplete="off" data-docs-version="{{ .Site.Params.docs_version }}">
<button class="btn btn-link bd-search-docs-toggle d-md-none p-0 ml-3" type="button" data-toggle="collapse" data-target="#bd-docs-nav" aria-controls="bd-docs-nav" aria-expanded="false" aria-label="Toggle docs navigation">
{{ partial "icons/menu.svg" (dict "width" "30" "height" "30") }}
</button>
</form>
<nav class="collapse bd-links" id="bd-docs-nav" aria-label="Main navigation">
<nav class="collapse bd-links pb-3" id="bd-docs-nav" aria-label="Main navigation">
{{- $url := split .Permalink "/" -}}
{{- $page_slug := index $url (sub (len $url) 2) -}}
<ul class="list-unstyled">
{{- range $group := .Site.Data.nav -}}
{{- $link := $group.title -}}
{{- $link_slug := $link | urlize -}}
@ -21,13 +15,14 @@
{{- $group_slug := $group.title | urlize -}}
{{- $active_group := eq $.Page.Params.group $group_slug }}
<div class="bd-toc-item{{ if $active_group }} active{{ end }}">
<a class="bd-toc-link" href="/docs/{{ $.Site.Params.docs_version }}/{{ $group_slug }}/{{ if $group.pages }}{{ $link_slug }}/{{ end }}">
{{- $group.title -}}
<li class="bd-sidenav-group my-1{{ if $active_group }} active{{ end }} js-sidenav-group">
<a class="d-inline-flex align-items-center bd-sidenav-group-link" href="/docs/{{ $.Site.Params.docs_version }}/{{ $group_slug }}/{{ if $group.pages }}{{ $link_slug }}/{{ end }}">
<svg class="bd-sidenav-group-link-icon" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="currentColor" stroke-width="2" d="M5 14l6-6-6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>
<div>{{- $group.title -}}</div>
</a>
{{- if and $active_group $group.pages }}
<ul class="nav bd-sidenav">
{{- if $group.pages }}
<ul class="nav bd-sidenav mb-2">
{{- range $doc := $group.pages -}}
{{- $doc_slug := $doc.title | urlize }}
<li{{ if and $active_group (eq $page_slug $doc_slug) }} class="active bd-sidenav-active"{{ end }}>
@ -38,6 +33,12 @@
{{- end }}
</ul>
{{- end }}
</div>
{{- end }}
</li>
{{- end }}
<li class="my-3 mx-4 border-top"></li>
<li class="bd-sidenav-group pl-3">
<a class="d-inline-flex bd-sidenav-group-link" href="/migration">Migration</a>
</li>
</ul>
</nav>

View File

@ -0,0 +1,19 @@
<div class="dropdown">
<button class="btn btn-link dropdown-toggle p-0 link-dark" id="bd-versions" data-toggle="dropdown" aria-expanded="false">
v{{ .Site.Params.docs_version }}
</button>
<div class="dropdown-menu dropdown-menu-md-right" aria-labelledby="bd-versions">
<a class="dropdown-item active" href="/docs/{{ .Site.Params.docs_version }}/">Latest (5.0.x)</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/docs/{{ .Site.Params.docs_version }}/">v4.3.1</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/4.2/">v4.2.1</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/4.0/">v4.0.0</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="https://v4-alpha.getbootstrap.com/">v4 Alpha 6</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/3.4/">v3.4.1</a>
<a class="dropdown-item" href="https://getbootstrap.com/docs/3.3/">v3.3.7</a>
<a class="dropdown-item" href="https://getbootstrap.com/2.3.2/">v2.3.2</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/docs/versions/">All versions</a>
</div>
</div>

View File

@ -1,5 +1,5 @@
<footer class="bd-footer text-muted">
<div class="container-fluid p-3 p-md-5">
<footer class="bd-footer p-3 p-md-5 mt-5 text-muted">
<div class="container">
<ul class="bd-footer-links">
<li><a href="{{ .Site.Params.repo }}">GitHub</a></li>
<li><a href="https://twitter.com/{{ .Site.Params.twitter }}">Twitter</a></li>

View File

@ -1,46 +1,103 @@
<div class="masthead-followup row m-0 border border-white">
<div class="col-md-4 p-3 p-md-5 bg-light border border-white">
{{ "<!-- Icon by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ partial "icons/import.svg" (dict "class" "text-primary mb-2" "width" "32" "height" "32") }}
<h3>Installation</h3>
<p>Include Bootstraps source Sass and JavaScript files via npm, Composer or Meteor. Package managed installs dont include documentation, but do include our build system and readme.</p>
{{ "<!-- Icons by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ highlight "npm install bootstrap" "sh" "" }}
{{ highlight (printf ("gem install bootstrap -v %s") .Site.Params.current_ruby_version) "sh" "" }}
<hr class="half-rule">
<a class="btn btn-outline-primary" href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Read installation docs</a>
<div class="container py-5 my-5 text-center">
<div class="home-icon home-icon-blue mx-auto mb-3">
{{ partial "icons/import.svg" (dict "width" "3rem" "height" "3rem") }}
</div>
<h2 class="display-4">Installation</h2>
<p class="lead lead-lg mw-md-75 mx-auto">
Include Bootstraps source Sass and JavaScript files via npm, Composer, or Meteor. Package managed installs dont include documentation, but do include our build system and readme.
</p>
<a class="btn btn-lg btn-outline-primary mb-4" href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Read installation docs</a>
<div class="text-left mx-md-5 px-md-5">
{{ highlight "npm install bootstrap" "sh" "" }}
{{ highlight (printf ("gem install bootstrap -v %s") .Site.Params.current_ruby_version) "sh" "" }}
</div>
</div>
<div class="col-md-4 p-3 p-md-5 bg-light border border-white">
{{ "<!-- Icon by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ partial "icons/download.svg" (dict "class" "text-primary mb-2" "width" "32" "height" "32") }}
<h3>BootstrapCDN</h3>
<p>When you only need to include Bootstraps compiled CSS or JS, you can use <a href="https://www.bootstrapcdn.com/">BootstrapCDN</a>.</p>
<div class="container py-5 my-5 text-center">
<div class="home-icon home-icon-purple mx-auto mb-3">
{{ partial "icons/download.svg" (dict "width" "3rem" "height" "3rem") }}
</div>
<h2 class="display-4">BootstrapCDN</h2>
<p class="lead lead-lg mw-md-75 mx-auto">
Use the <a href="https://bootstrapcdn.com/">BootstrapCDN</a> to deliver fast, cached, and compiled versions of Bootstraps CSS and JavaScript. No jQuery is required, but don't forget to include Popper.js for some components.
</p>
<a class="btn btn-lg btn-outline-primary mb-4" href="/docs/{{ .Site.Params.docs_version }}/layout/overview/">Explore the docs</a>
<div class="text-left mx-md-5 px-md-5">
<h5>CSS only</h5>
{{ highlight (printf (`<link rel="stylesheet" href="%s" integrity="%s" crossorigin="anonymous">`) .Site.Params.cdn.css .Site.Params.cdn.css_hash) "html" "" }}
<h5>JS and Popper.js</h5>
{{ highlight (printf (`<script src="%s" integrity="%s" crossorigin="anonymous"></script>
<script src="%s" integrity="%s" crossorigin="anonymous"></script>
`) .Site.Params.cdn.popper .Site.Params.cdn.popper_hash .Site.Params.cdn.js .Site.Params.cdn.js_hash) "html" "" }}
<hr class="half-rule">
<a class="btn btn-outline-primary" href="/docs/{{ .Site.Params.docs_version }}/layout/overview/">Explore the docs</a>
</div>
<div class="col-md-4 p-3 p-md-5 bg-light border border-white">
{{ "<!-- Icon by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ partial "icons/lightning.svg" (dict "class" "text-primary mb-2" "width" "32" "height" "32") }}
<h3>Official Themes</h3>
<p>
Take Bootstrap 4 to the next level with official premium themes—toolkits built on Bootstrap with new components and plugins, docs, and build tools.
</p>
<img class="img-fluid mt-3 mx-auto" srcset="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes.png,
/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes@2x.png 2x"
src="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes.png" alt="Bootstrap Themes" width="500" height="200">
<hr class="half-rule">
<a href="{{ .Site.Params.themes }}/" class="btn btn-outline-primary">Browse themes</a>
</div>
</div>
<div class="container py-5 my-5 text-center">
<div class="home-icon home-icon-yellow mx-auto mb-3">
{{ partial "icons/lightning.svg" (dict "width" "3rem" "height" "3rem") }}
</div>
<h2 class="display-4">Official Themes</h2>
<p class="lead lead-lg mw-md-75 mx-auto">
Take Bootstrap 4 to the next level with official premium themes—toolkits built on Bootstrap with new components and plugins, docs, and build tools.
</p>
<a class="btn btn-lg btn-outline-primary mb-4" href="{{ .Site.Params.themes }}/">Browse themes</a>
<div class="mx-5 border-bottom">
<img class="img-fluid mt-3 mx-auto" src="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes@2x.png" alt="Bootstrap Themes" width="600">
</div>
</div>
<div class="masthead-followup container d-none">
<div class="row py-5 mb-5">
<div class="col-md-5">
{{ "<!-- Icon by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ partial "icons/import.svg" (dict "class" "text-primary mb-2" "width" "32" "height" "32") }}
<h3>Installation</h3>
<p>Include Bootstraps source Sass and JavaScript files via npm, Composer, or Meteor. Package managed installs dont include documentation, but do include our build system and readme.</p>
<hr class="half-rule">
<a class="btn btn-outline-primary" href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Read installation docs</a>
</div>
<div class="col-md-6 offset-md-1">
{{ highlight "npm install bootstrap" "sh" "" }}
{{ highlight (printf ("gem install bootstrap -v %s") .Site.Params.current_ruby_version) "sh" "" }}
</div>
</div>
<div class="row pb-5 mb-5">
<div class="col-md-6">
{{ "<!-- Icon by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ partial "icons/download.svg" (dict "class" "text-primary mb-2" "width" "32" "height" "32") }}
<h3>BootstrapCDN</h3>
<p>Use the <a href="https://bootstrapcdn.com/">BootstrapCDN</a> to deliver fast, cached, and compiled versions of Bootstraps CSS and JavaScript. No jQuery is required, but don't forget to include Popper.js for some components.</p>
<hr class="half-rule">
<a class="btn btn-outline-primary" href="/docs/{{ .Site.Params.docs_version }}/layout/overview/">Explore the docs</a>
</div>
<div class="col-md-6">
<h5>CSS only</h5>
{{ highlight (printf (`<link rel="stylesheet" href="%s" integrity="%s" crossorigin="anonymous">`) .Site.Params.cdn.css .Site.Params.cdn.css_hash) "html" "" }}
<h5>JS and Popper.js</h5>
{{ highlight (printf (`<script src="%s" integrity="%s" crossorigin="anonymous"></script>
<script src="%s" integrity="%s" crossorigin="anonymous"></script>
`) .Site.Params.cdn.popper .Site.Params.cdn.popper_hash .Site.Params.cdn.js .Site.Params.cdn.js_hash) "html" "" }}
</div>
</div>
<div class="row pb-5 mb-5">
<div class="col-md-6">
{{ "<!-- Icon by Bytesize https://github.com/danklammer/bytesize-icons -->" | safeHTML }}
{{ partial "icons/lightning.svg" (dict "class" "text-primary mb-2" "width" "32" "height" "32") }}
<h3>Official Themes</h3>
<p>
Take Bootstrap 4 to the next level with official premium themes—toolkits built on Bootstrap with new components and plugins, docs, and build tools.
</p>
<hr class="half-rule">
<a href="{{ .Site.Params.themes }}/" class="btn btn-outline-primary">Browse themes</a>
</div>
<div class="col-md-6">
<img class="img-fluid mt-3 mx-auto" srcset="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes.png,
/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes@2x.png 2x"
src="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes.png" alt="Bootstrap Themes" width="500" height="200">
</div>
</div>
</div>

View File

@ -1,27 +1,27 @@
<main class="bd-masthead" id="content" role="main">
<main class="bd-masthead mb-5 border-bottom" id="content" role="main">
<div class="container">
<div class="row align-items-center">
<div class="col-6 mx-auto col-md-6 order-md-2">
<div class="row align-items-start">
<div class="col-6 mx-auto col-md-4 order-md-2 col-lg-5">
{{ partial "icons/bootstrap-stack.svg" (dict "class" "img-fluid mb-3 mb-md-0" "width" "512" "height" "430") }}
</div>
<div class="col-md-6 order-md-1 text-center text-md-left pr-md-5">
<div class="col-md-7 order-md-1 col-lg-6 text-center text-md-left">
<h1 class="mb-3 bd-text-purple-bright">Bootstrap</h1>
<p class="lead">
Build responsive, mobile-first projects on the web with the worlds most popular front-end component library.
<p class="lead lead-lg">
Build responsive, mobile-first projects for the web with the worlds most popular open source front-end component library.
</p>
<p class="lead mb-4">
Bootstrap is an open source toolkit for developing with HTML, CSS, and JS. Quickly prototype your ideas or build your entire app with our Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful plugins built with VanillaJS.
<p class="mb-4">
Quickly prototype your ideas, spin up internal tools, or build your entire production app or site with powerful features and customization like Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful JavaScript plugins.
</p>
<div class="row mx-n2">
<div class="col-md px-2">
<a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" class="btn btn-lg btn-bd-primary w-100 mb-3" onclick="ga('send', 'event', 'Jumbotron actions', 'Get started', 'Get started');">Get started</a>
</div>
<div class="col-md px-2">
<a href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/" class="btn btn-lg btn-outline-secondary w-100 mb-3" onclick="ga('send', 'event', 'Jumbotron actions', 'Download', 'Download {{ .Site.Params.current_version }}');">Download</a>
</div>
<div class="d-flex flex-column flex-md-row">
<a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" class="btn btn-lg btn-bd-primary w-100 mb-3 mr-md-3" onclick="ga('send', 'event', 'Jumbotron actions', 'Get started', 'Get started');">Get started</a>
<a href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/" class="btn btn-lg btn-outline-secondary w-100 mb-3" onclick="ga('send', 'event', 'Jumbotron actions', 'Download', 'Download {{ .Site.Params.current_version }}');">Download</a>
</div>
<hr class="half-rule">
<p class="text-muted mb-0">
Currently v{{ .Site.Params.current_version }}
Currently <strong>v{{ .Site.Params.current_version }}</strong>
<span class="px-1">&middot;</span>
<a href="" class="text-muted">Previous releases</a>
</p>
</div>
</div>

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg"{{ with .width }} width="{{ . }}"{{ end }}{{ with .height }} height="{{ . }}"{{ end }}{{ with .class }} class="{{ . }}"{{ end }} viewBox="0 0 16 16" role="img"><path stroke="currentColor" stroke-width="2" d="M5 14l6-6-6-6" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg"{{ with .width }} width="{{ . }}"{{ end }}{{ with .height }} height="{{ . }}"{{ end }}{{ with .class }} class="{{ . }}"{{ end }} viewBox="0 0 64 64" role="img"><title>{{ with .title }}{{ . }}{{ else }}Bootstrap{{ end }}</title><path d="M16 0h32c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H16C7.163 64 0 56.837 0 48V16C0 7.163 7.163 0 16 0zm18.14 49c7.22 0 11.555-3.633 11.555-9.586 0-4.406-3.047-7.664-7.617-8.133v-.398c3.328-.563 5.93-3.727 5.93-7.266 0-5.203-3.82-8.437-10.172-8.437H20.242V49h13.899zm-8.648-29.367h7.125c3.89 0 6.164 1.828 6.164 4.945 0 3.211-2.414 4.922-7.054 4.922h-6.235v-9.867zm0 24.914V33.648h7.29c4.945 0 7.546 1.852 7.546 5.391 0 3.586-2.508 5.508-7.242 5.508h-7.594z" fill="currentColor" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 787 B

View File

@ -19,6 +19,20 @@
return [].slice.call(list)
}
var sidenavGroups = document.querySelectorAll('.js-sidenav-group')
var groupHasLinks
var groupLink
sidenavGroups.forEach(sidenavGroup => {
groupHasLinks = Boolean(sidenavGroup.querySelector('li'))
groupLink = sidenavGroup.querySelector('a')
if (groupHasLinks) {
groupLink.addEventListener('click', function (e) {
e.preventDefault()
e.target.parentNode.classList.toggle('active')
}, true)
}
})
// Tooltip and popover demos
makeArray(document.querySelectorAll('.tooltip-demo'))
.forEach(function (tooltip) {

View File

@ -21,10 +21,10 @@
}
}
> table {
width: 100%;
// Override Bootstrap defaults
> .table {
max-width: 100%;
margin-bottom: 1rem;
margin-bottom: 1.5rem;
@include media-breakpoint-down(md) {
display: block;
@ -35,22 +35,10 @@
}
}
// Cells
> thead,
> tbody,
> tfoot {
> tr {
> th,
> td {
padding: $table-cell-padding;
vertical-align: top;
border: 1px solid $table-border-color;
> p:last-child {
margin-bottom: 0;
}
}
}
th,
td {
&:first-child { padding-left: 0; }
&:not(:last-child) { padding-right: 1.5rem; }
}
// Prevent breaking of code (e.g., Grunt tasks list)
@ -94,30 +82,16 @@
> ol li {
margin-bottom: .25rem;
}
@include media-breakpoint-up(lg) {
> ul,
> ol,
> p {
max-width: 80%;
}
}
}
.bd-title {
margin-top: 1rem;
margin-bottom: .5rem;
font-weight: 300;
@include font-size(3rem);
}
.bd-lead {
@include font-size(1.5rem);
font-weight: 300;
@include media-breakpoint-up(lg) {
max-width: 80%;
}
}
.bd-text-purple { color: $bd-purple; }

View File

@ -3,13 +3,17 @@
.bd-masthead {
position: relative;
padding: 3rem ($grid-gutter-width / 2);
// background-image: linear-gradient(45deg, #fafafa, #f5f5f5);
background-image: linear-gradient(45deg, #fafafa, #f5f5f5);
h1 {
@include font-size(4rem);
line-height: 1;
}
p:not(.lead) {
color: $gray-700;
}
.btn {
padding: .8rem 2rem;
font-weight: 600;
@ -37,16 +41,46 @@
}
}
.lead-lg {
@include font-size(1.5rem);
}
.home-icon {
width: 6rem;
height: 6rem;
padding: 1.5rem;
color: #fff;
text-shadow: 0 -.125rem 0 rgba(0, 0, 0, .1);
@include border-radius(25%);
box-shadow: 0 .25rem .5rem rgba(0, 0, 0, .15), inset 0 -1px 0 rgba(0, 0, 0, .15);
&-purple {
background-image: linear-gradient(180deg, $pink, $purple);
}
&-blue {
background-image: linear-gradient(180deg, $teal, $blue);
}
&-yellow {
background-image: linear-gradient(180deg, $yellow, $orange);
}
}
@include media-breakpoint-up(md) {
.mw-md-75 { max-width: 75%; }
}
.half-rule {
width: 6rem;
margin: 2.5rem 0;
margin: 2rem 0;
}
.masthead-followup {
.bd-clipboard { display: none; }
.highlight {
padding: .5rem 0;
background-color: transparent;
// padding: .5rem 0;
// background-color: transparent;
}
}

View File

@ -2,10 +2,47 @@
// Main navbar
//
.bd-subnavbar {
background-color: rgba(#fff, .75);
backdrop-filter: blur(1rem);
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .15);
.booticon {
opacity: .25;
}
.dropdown-toggle {
@include font-size(100%);
text-decoration: none;
}
.dropdown-menu {
@include font-size(90%);
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05);
}
@include media-breakpoint-up(md) {
@supports (position: sticky) {
position: sticky;
top: 0;
z-index: 1071; // over everything in bootstrap
}
}
}
.link-dark {
font-weight: 500;
color: $dark;
&:hover {
color: $blue;
text-decoration: none;
}
}
.bd-navbar {
min-height: 4rem;
background-color: $bd-purple;
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .1);
background-color: $bd-purple-bright;
@include media-breakpoint-down(md) {
padding-right: .5rem;
@ -26,14 +63,6 @@
}
}
@include media-breakpoint-up(md) {
@supports (position: sticky) {
position: sticky;
top: 0;
z-index: 1071; // over everything in bootstrap
}
}
.navbar-nav {
.nav-link {
padding-right: .5rem;

View File

@ -1,91 +1,15 @@
// stylelint-disable declaration-no-important
//
// Right side table of contents
//
.bd-toc {
@supports (position: sticky) {
position: sticky;
top: 4rem;
height: calc(100vh - 4rem);
overflow-y: auto;
}
order: 2;
padding-top: 1.5rem;
padding-bottom: 1.5rem;
@include font-size(.875rem);
}
// stylelint-disable selector-max-type, selector-max-combinators, selector-max-compound-selectors
.bd-toc nav {
padding-left: 0;
border-left: 1px solid #eee;
> ul,
> ul > li > ul {
padding: 0;
}
a code {
font: inherit;
}
li {
display: block;
ul li ul {
padding-left: 1rem;
}
a {
display: block;
padding: .125rem 1.5rem;
color: #77757a;
&:hover {
color: $blue;
text-decoration: none;
}
}
}
}
// stylelint-enable selector-max-type, selector-max-combinators, selector-max-compound-selectors
//
// Left side navigation
//
.bd-sidebar {
order: 0;
// background-color: #f5f2f9;
border-bottom: 1px solid rgba(0, 0, 0, .1);
@include media-breakpoint-up(md) {
@supports (position: sticky) {
position: sticky;
top: 4rem;
z-index: 1000;
height: calc(100vh - 4rem);
}
border-right: 1px solid rgba(0, 0, 0, .1);
}
@include media-breakpoint-up(xl) {
flex: 0 1 320px;
}
}
.bd-links {
padding-top: 1rem;
padding-bottom: 1rem;
margin-right: -15px;
margin-left: -15px;
@include media-breakpoint-up(md) {
@supports (position: sticky) {
max-height: calc(100vh - 9rem);
overflow-y: auto;
position: sticky;
top: 5rem;
z-index: 1000;
}
}
@ -97,10 +21,6 @@
.bd-search {
position: relative; // To contain the Algolia search
padding: 1rem 15px;
margin-right: -15px;
margin-left: -15px;
border-bottom: 1px solid rgba(0, 0, 0, .05);
.form-control:focus {
border-color: $bd-purple-bright;
@ -117,32 +37,35 @@
display: none;
}
.bd-toc-link {
display: block;
padding: .25rem 1.5rem;
.bd-sidenav-group-link {
padding: .25rem .625rem .25rem .5rem;
font-weight: 600;
color: rgba(0, 0, 0, .65);
@include border-radius(.25rem);
> * { pointer-events: none; }
&:hover {
color: rgba(0, 0, 0, .85);
text-decoration: none;
background-color: rgba($bd-purple-bright, .1);
}
}
.bd-toc-item {
&.active {
margin-bottom: 1rem;
.bd-sidenav-group-link-icon {
width: .875rem;
margin-right: .25rem;
opacity: .5;
}
&:not(:first-child) {
margin-top: 1rem;
.bd-sidenav-group {
&.active {
.bd-sidenav-group-link-icon {
transform: rotate(90deg);
}
> .bd-toc-link {
> .bd-sidenav-group-link {
color: rgba(0, 0, 0, .85);
&:hover {
background-color: transparent;
}
}
> .bd-sidenav {
@ -152,22 +75,26 @@
}
// All levels of nav
.bd-sidebar .nav > li > a {
display: block;
padding: .25rem 1.5rem;
@include font-size(90%);
color: rgba(0, 0, 0, .65);
}
.bd-sidebar .nav {
padding-left: 1.25rem;
.bd-sidebar .nav > li > a:hover {
color: rgba(0, 0, 0, .85);
text-decoration: none;
background-color: transparent;
}
> li > a {
display: inline-block;
padding: .25rem .5rem;
@include font-size(.875rem);
color: rgba(0, 0, 0, .65);
@include border-radius(.25rem);
.bd-sidebar .nav > .active > a,
.bd-sidebar .nav > .active:hover > a {
font-weight: 600;
color: rgba(0, 0, 0, .85);
background-color: transparent;
&:hover {
color: rgba(0, 0, 0, .85);
text-decoration: none;
background-color: rgba($bd-purple-bright, .1);
}
}
> .active > a,
> .active:hover > a {
font-weight: 600;
color: rgba(0, 0, 0, .85);
}
}

View File

@ -0,0 +1,25 @@
// stylelint-disable selector-max-type, selector-max-combinators, selector-max-compound-selectors
.bd-toc nav {
padding-top: .125em;
padding-bottom: .125em;
border-left: .25em solid #eee;
> ul {
padding-left: .5rem;
margin-bottom: 0;
}
> ul > li {
display: block;
}
li ul li {
margin-bottom: .25rem;
list-style-type: disc;
}
a code {
font: inherit;
}
}

View File

@ -36,6 +36,7 @@
@import "content";
@import "skippy";
@import "sidebar";
@import "toc";
@import "footer";
@import "component-examples";
@import "buttons";
@ -50,3 +51,17 @@
@import "syntax";
@import "anchor";
@import "algolia";
// Temp
.booticons-list {
.booticon {
display: inline;
width: 4rem;
padding: 1rem;
margin-right: 1rem;
margin-bottom: 1rem;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, .1);
@include border-radius(.25rem);
}
}