mirror of
https://github.com/Hopiu/bootstrap.git
synced 2026-04-05 22:00:58 +00:00
v5: Floating labels (#30449)
* v5: Promote floating labels example to component - Adds new .form-floating - Stubs out basics of a docs page - Removes existing Example * Update floating labels to support .form-select, make inputs and selects more consistent - To do this, I made the .form-control and .form-select consistent in min-height vs height - Removed some unused variables now - Updated -color to be the -color because I don't know why this was any different before - Update page to include some examples for layout, validation, and value - Rewrite styles to not modify padding, but instead transform and opacity * Streamline and bulletproof some things - Apply some optimizations from code review - Removed unecessary properties from the label - Add some comments for what properties are required - Move from fixed height for labels to height 100% so we can support textareas - Improve docs a little bit, add ToC * Move some values to variables, switch from scaling font-size to scale, update transforms * Bring over changes from #30966 and add to them to tighten things up * Delete the now unused example images * Fix typo * Allowlist the calc function * Add transform-origin, update transform values * Test out autofill fix * Fix linter issue * Mention it in the migration guide * Bump bundlesize * Add one more variable per review * Shave .25rem off the height Co-authored-by: XhmikosR <xhmikosr@gmail.com>
This commit is contained in:
parent
582f52e9e1
commit
3e2f9ab237
45 changed files with 770 additions and 443 deletions
|
|
@ -30,7 +30,7 @@
|
|||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap.min.css",
|
||||
"maxSize": "21.5 kB"
|
||||
"maxSize": "21.6 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.js",
|
||||
|
|
|
|||
BIN
dist/css/bootstrap-grid.css.map
vendored
BIN
dist/css/bootstrap-grid.css.map
vendored
Binary file not shown.
10
dist/css/bootstrap-reboot.css
vendored
10
dist/css/bootstrap-reboot.css
vendored
|
|
@ -11,9 +11,15 @@
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
|
|
@ -183,7 +189,7 @@ a {
|
|||
}
|
||||
|
||||
a:hover {
|
||||
color: #024dbc;
|
||||
color: #0a58ca;
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
|
|
|
|||
BIN
dist/css/bootstrap-reboot.css.map
vendored
BIN
dist/css/bootstrap-reboot.css.map
vendored
Binary file not shown.
105
dist/css/bootstrap-utilities.css
vendored
105
dist/css/bootstrap-utilities.css
vendored
|
|
@ -48,6 +48,14 @@
|
|||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.overflow-visible {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.overflow-scroll {
|
||||
overflow: scroll !important;
|
||||
}
|
||||
|
||||
.d-inline {
|
||||
display: inline !important;
|
||||
}
|
||||
|
|
@ -242,7 +250,7 @@
|
|||
}
|
||||
|
||||
.border-dark {
|
||||
border-color: #343a40 !important;
|
||||
border-color: #212529 !important;
|
||||
}
|
||||
|
||||
.border-white {
|
||||
|
|
@ -899,6 +907,38 @@
|
|||
padding-left: 3rem !important;
|
||||
}
|
||||
|
||||
.fs-1 {
|
||||
font-size: calc(1.375rem + 1.5vw) !important;
|
||||
}
|
||||
|
||||
.fs-2 {
|
||||
font-size: calc(1.325rem + 0.9vw) !important;
|
||||
}
|
||||
|
||||
.fs-3 {
|
||||
font-size: calc(1.3rem + 0.6vw) !important;
|
||||
}
|
||||
|
||||
.fs-4 {
|
||||
font-size: calc(1.275rem + 0.3vw) !important;
|
||||
}
|
||||
|
||||
.fs-5 {
|
||||
font-size: 1.25rem !important;
|
||||
}
|
||||
|
||||
.fs-6 {
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
|
||||
.fst-italic {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
.fst-normal {
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
.font-weight-light {
|
||||
font-weight: 300 !important;
|
||||
}
|
||||
|
|
@ -972,7 +1012,7 @@
|
|||
}
|
||||
|
||||
.text-dark {
|
||||
color: #343a40 !important;
|
||||
color: #212529 !important;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
|
|
@ -1044,7 +1084,7 @@
|
|||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #343a40 !important;
|
||||
background-color: #212529 !important;
|
||||
}
|
||||
|
||||
.bg-body {
|
||||
|
|
@ -1083,14 +1123,6 @@
|
|||
text-decoration: line-through !important;
|
||||
}
|
||||
|
||||
.font-italic {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
.font-normal {
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
.text-break {
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-word !important;
|
||||
|
|
@ -3561,6 +3593,57 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.fs-1 {
|
||||
font-size: 2.5rem !important;
|
||||
}
|
||||
.fs-2 {
|
||||
font-size: 2rem !important;
|
||||
}
|
||||
.fs-3 {
|
||||
font-size: 1.75rem !important;
|
||||
}
|
||||
.fs-4 {
|
||||
font-size: 1.5rem !important;
|
||||
}
|
||||
.fs-sm-1 {
|
||||
font-size: 2.5rem !important;
|
||||
}
|
||||
.fs-sm-2 {
|
||||
font-size: 2rem !important;
|
||||
}
|
||||
.fs-sm-3 {
|
||||
font-size: 1.75rem !important;
|
||||
}
|
||||
.fs-sm-4 {
|
||||
font-size: 1.5rem !important;
|
||||
}
|
||||
.fs-md-1 {
|
||||
font-size: 2.5rem !important;
|
||||
}
|
||||
.fs-md-2 {
|
||||
font-size: 2rem !important;
|
||||
}
|
||||
.fs-md-3 {
|
||||
font-size: 1.75rem !important;
|
||||
}
|
||||
.fs-md-4 {
|
||||
font-size: 1.5rem !important;
|
||||
}
|
||||
.fs-lg-1 {
|
||||
font-size: 2.5rem !important;
|
||||
}
|
||||
.fs-lg-2 {
|
||||
font-size: 2rem !important;
|
||||
}
|
||||
.fs-lg-3 {
|
||||
font-size: 1.75rem !important;
|
||||
}
|
||||
.fs-lg-4 {
|
||||
font-size: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.d-print-inline {
|
||||
display: inline !important;
|
||||
|
|
|
|||
BIN
dist/css/bootstrap-utilities.css.map
vendored
BIN
dist/css/bootstrap-utilities.css.map
vendored
Binary file not shown.
File diff suppressed because it is too large
Load diff
BIN
dist/css/bootstrap.css.map
vendored
BIN
dist/css/bootstrap.css.map
vendored
Binary file not shown.
23
dist/js/bootstrap.bundle.js
vendored
23
dist/js/bootstrap.bundle.js
vendored
|
|
@ -975,17 +975,6 @@
|
|||
top: element.offsetTop,
|
||||
left: element.offsetLeft
|
||||
};
|
||||
},
|
||||
toggleClass: function toggleClass(element, className) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.classList.contains(className)) {
|
||||
element.classList.remove(className);
|
||||
} else {
|
||||
element.classList.add(className);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4844,8 +4833,10 @@
|
|||
|
||||
this._element.setAttribute('aria-expanded', true);
|
||||
|
||||
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1);
|
||||
Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
EventHandler.trigger(parent, EVENT_SHOWN$1, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
@ -4868,8 +4859,10 @@
|
|||
this._popper.destroy();
|
||||
}
|
||||
|
||||
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1);
|
||||
Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
dist/js/bootstrap.bundle.js.map
vendored
BIN
dist/js/bootstrap.bundle.js.map
vendored
Binary file not shown.
23
dist/js/bootstrap.esm.js
vendored
23
dist/js/bootstrap.esm.js
vendored
|
|
@ -971,17 +971,6 @@ var Manipulator = {
|
|||
top: element.offsetTop,
|
||||
left: element.offsetLeft
|
||||
};
|
||||
},
|
||||
toggleClass: function toggleClass(element, className) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.classList.contains(className)) {
|
||||
element.classList.remove(className);
|
||||
} else {
|
||||
element.classList.add(className);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2226,8 +2215,10 @@ var Dropdown = /*#__PURE__*/function () {
|
|||
|
||||
this._element.setAttribute('aria-expanded', true);
|
||||
|
||||
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1);
|
||||
Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
EventHandler.trigger(parent, EVENT_SHOWN$1, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
@ -2250,8 +2241,10 @@ var Dropdown = /*#__PURE__*/function () {
|
|||
this._popper.destroy();
|
||||
}
|
||||
|
||||
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1);
|
||||
Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
dist/js/bootstrap.esm.js.map
vendored
BIN
dist/js/bootstrap.esm.js.map
vendored
Binary file not shown.
|
|
@ -979,17 +979,6 @@
|
|||
top: element.offsetTop,
|
||||
left: element.offsetLeft
|
||||
};
|
||||
},
|
||||
toggleClass: function toggleClass(element, className) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.classList.contains(className)) {
|
||||
element.classList.remove(className);
|
||||
} else {
|
||||
element.classList.add(className);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2234,8 +2223,10 @@
|
|||
|
||||
this._element.setAttribute('aria-expanded', true);
|
||||
|
||||
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1);
|
||||
Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
EventHandler.trigger(parent, EVENT_SHOWN$1, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
@ -2258,8 +2249,10 @@
|
|||
this._popper.destroy();
|
||||
}
|
||||
|
||||
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1);
|
||||
Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW$1);
|
||||
|
||||
EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
dist/js/bootstrap.js.map
vendored
BIN
dist/js/bootstrap.js.map
vendored
Binary file not shown.
BIN
js/dist/alert.js.map
vendored
BIN
js/dist/alert.js.map
vendored
Binary file not shown.
BIN
js/dist/button.js.map
vendored
BIN
js/dist/button.js.map
vendored
Binary file not shown.
BIN
js/dist/carousel.js.map
vendored
BIN
js/dist/carousel.js.map
vendored
Binary file not shown.
BIN
js/dist/collapse.js.map
vendored
BIN
js/dist/collapse.js.map
vendored
Binary file not shown.
BIN
js/dist/dom/data.js.map
vendored
BIN
js/dist/dom/data.js.map
vendored
Binary file not shown.
BIN
js/dist/dom/event-handler.js.map
vendored
BIN
js/dist/dom/event-handler.js.map
vendored
Binary file not shown.
11
js/dist/dom/manipulator.js
vendored
11
js/dist/dom/manipulator.js
vendored
|
|
@ -77,17 +77,6 @@
|
|||
top: element.offsetTop,
|
||||
left: element.offsetLeft
|
||||
};
|
||||
},
|
||||
toggleClass: function toggleClass(element, className) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.classList.contains(className)) {
|
||||
element.classList.remove(className);
|
||||
} else {
|
||||
element.classList.add(className);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
js/dist/dom/manipulator.js.map
vendored
BIN
js/dist/dom/manipulator.js.map
vendored
Binary file not shown.
BIN
js/dist/dom/polyfill.js.map
vendored
BIN
js/dist/dom/polyfill.js.map
vendored
Binary file not shown.
BIN
js/dist/dom/selector-engine.js.map
vendored
BIN
js/dist/dom/selector-engine.js.map
vendored
Binary file not shown.
12
js/dist/dropdown.js
vendored
12
js/dist/dropdown.js
vendored
|
|
@ -258,8 +258,10 @@
|
|||
|
||||
this._element.setAttribute('aria-expanded', true);
|
||||
|
||||
Manipulator__default['default'].toggleClass(this._menu, CLASS_NAME_SHOW);
|
||||
Manipulator__default['default'].toggleClass(this._element, CLASS_NAME_SHOW);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW);
|
||||
|
||||
EventHandler__default['default'].trigger(parent, EVENT_SHOWN, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
@ -282,8 +284,10 @@
|
|||
this._popper.destroy();
|
||||
}
|
||||
|
||||
Manipulator__default['default'].toggleClass(this._menu, CLASS_NAME_SHOW);
|
||||
Manipulator__default['default'].toggleClass(this._element, CLASS_NAME_SHOW);
|
||||
this._menu.classList.toggle(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.toggle(CLASS_NAME_SHOW);
|
||||
|
||||
EventHandler__default['default'].trigger(parent, EVENT_HIDDEN, relatedTarget);
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
js/dist/dropdown.js.map
vendored
BIN
js/dist/dropdown.js.map
vendored
Binary file not shown.
BIN
js/dist/modal.js.map
vendored
BIN
js/dist/modal.js.map
vendored
Binary file not shown.
BIN
js/dist/popover.js.map
vendored
BIN
js/dist/popover.js.map
vendored
Binary file not shown.
BIN
js/dist/scrollspy.js.map
vendored
BIN
js/dist/scrollspy.js.map
vendored
Binary file not shown.
BIN
js/dist/tab.js.map
vendored
BIN
js/dist/tab.js.map
vendored
Binary file not shown.
BIN
js/dist/toast.js.map
vendored
BIN
js/dist/toast.js.map
vendored
Binary file not shown.
BIN
js/dist/tooltip.js.map
vendored
BIN
js/dist/tooltip.js.map
vendored
Binary file not shown.
|
|
@ -5,5 +5,6 @@
|
|||
@import "forms/form-check";
|
||||
@import "forms/form-file";
|
||||
@import "forms/form-range";
|
||||
@import "forms/floating-labels";
|
||||
@import "forms/input-group";
|
||||
@import "forms/validation";
|
||||
|
|
|
|||
|
|
@ -648,7 +648,7 @@ $input-bg: $white !default;
|
|||
$input-disabled-bg: $gray-200 !default;
|
||||
$input-disabled-border-color: null !default;
|
||||
|
||||
$input-color: $gray-700 !default;
|
||||
$input-color: $body-color !default;
|
||||
$input-border-color: $gray-400 !default;
|
||||
$input-border-width: $input-btn-border-width !default;
|
||||
$input-box-shadow: $box-shadow-inset !default;
|
||||
|
|
@ -733,7 +733,6 @@ $input-group-addon-color: $input-color !default;
|
|||
$input-group-addon-bg: $gray-200 !default;
|
||||
$input-group-addon-border-color: $input-border-color !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;
|
||||
|
|
@ -824,6 +823,14 @@ $form-file-padding-x-lg: $input-padding-x-lg !default;
|
|||
$form-file-font-size-lg: $input-font-size-lg !default;
|
||||
$form-file-height-lg: $input-height-lg !default;
|
||||
|
||||
$form-floating-height: add(3.5rem, $input-height-border) !default;
|
||||
$form-floating-padding-x: $input-padding-x !default;
|
||||
$form-floating-padding-y: 1rem !default;
|
||||
$form-floating-input-padding-t: 1.625rem !default;
|
||||
$form-floating-input-padding-b: .625rem !default;
|
||||
$form-floating-label-opacity: .65 !default;
|
||||
$form-floating-label-transform: scale(.85) translateY(-.5rem) translateX(.15rem) !default;
|
||||
$form-floating-transition: opacity .1s ease-in-out, transform .1s ease-in-out !default;
|
||||
|
||||
// Form validation
|
||||
|
||||
|
|
|
|||
85
scss/forms/_floating-labels.scss
Normal file
85
scss/forms/_floating-labels.scss
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
// stylelint-disable selector-no-vendor-prefix
|
||||
|
||||
.form-floating {
|
||||
position: relative;
|
||||
|
||||
> .form-control,
|
||||
> .form-select {
|
||||
height: $form-floating-height;
|
||||
padding: $form-floating-padding-y $form-floating-padding-x;
|
||||
}
|
||||
|
||||
> label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%; // allow textareas
|
||||
padding: $form-floating-padding-y $form-floating-padding-x;
|
||||
pointer-events: none;
|
||||
border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model
|
||||
transform-origin: 0 0;
|
||||
@include transition($form-floating-transition);
|
||||
}
|
||||
|
||||
// stylelint-disable no-duplicate-selectors
|
||||
> .form-control {
|
||||
&::placeholder {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:not(:placeholder-shown) {
|
||||
padding-top: $form-floating-input-padding-t;
|
||||
padding-bottom: $form-floating-input-padding-b;
|
||||
}
|
||||
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
|
||||
&:-webkit-autofill {
|
||||
padding-top: $form-floating-input-padding-t;
|
||||
padding-bottom: $form-floating-input-padding-b;
|
||||
}
|
||||
}
|
||||
|
||||
> .form-select {
|
||||
padding-top: $form-floating-input-padding-t;
|
||||
padding-bottom: $form-floating-input-padding-b;
|
||||
}
|
||||
|
||||
> .form-control:focus,
|
||||
> .form-control:not(:placeholder-shown),
|
||||
> .form-select {
|
||||
~ label {
|
||||
opacity: $form-floating-label-opacity;
|
||||
transform: $form-floating-label-transform;
|
||||
}
|
||||
}
|
||||
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
|
||||
> .form-control:-webkit-autofill {
|
||||
~ label {
|
||||
opacity: $form-floating-label-opacity;
|
||||
transform: $form-floating-label-transform;
|
||||
}
|
||||
}
|
||||
// stylelint-enable no-duplicate-selectors
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Fallback for classic Edge
|
||||
//
|
||||
|
||||
@supports (-ms-ime-align: auto) {
|
||||
.form-floating {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.form-floating > label {
|
||||
position: static;
|
||||
padding: 0;
|
||||
margin-bottom: calc(#{$form-floating-padding-y} / 2); // stylelint-disable-line function-disallowed-list
|
||||
border: 0;
|
||||
@include transition(none);
|
||||
}
|
||||
.form-floating > .form-control::-ms-input-placeholder {
|
||||
color: $input-placeholder-color;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
.form-select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $form-select-height;
|
||||
min-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);
|
||||
|
|
|
|||
|
|
@ -1,101 +0,0 @@
|
|||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-label-group {
|
||||
position: relative;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.form-label-group input,
|
||||
.form-label-group label {
|
||||
height: 3.125rem;
|
||||
padding: .75rem;
|
||||
}
|
||||
|
||||
.form-label-group label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
color: #495057;
|
||||
pointer-events: none;
|
||||
cursor: text; /* Match the input under the label */
|
||||
border: 1px solid transparent;
|
||||
border-radius: .25rem;
|
||||
transition: all .1s ease-in-out;
|
||||
}
|
||||
|
||||
.form-label-group input::-webkit-input-placeholder {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.form-label-group input::-moz-placeholder {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.form-label-group input::-ms-input-placeholder {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.form-label-group input::placeholder {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.form-label-group input:not(:-moz-placeholder-shown) {
|
||||
padding-top: 1.25rem;
|
||||
padding-bottom: .25rem;
|
||||
}
|
||||
|
||||
.form-label-group input:not(:placeholder-shown) {
|
||||
padding-top: 1.25rem;
|
||||
padding-bottom: .25rem;
|
||||
}
|
||||
|
||||
.form-label-group input:not(:-moz-placeholder-shown) ~ label {
|
||||
padding-top: .25rem;
|
||||
padding-bottom: .25rem;
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.form-label-group input:not(:placeholder-shown) ~ label {
|
||||
padding-top: .25rem;
|
||||
padding-bottom: .25rem;
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
/* Fallback for Edge
|
||||
-------------------------------------------------- */
|
||||
@supports (-ms-ime-align: auto) {
|
||||
.form-label-group {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.form-label-group label {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.form-label-group input::-ms-input-placeholder {
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
layout: examples
|
||||
title: Floating labels example
|
||||
extra_css:
|
||||
- "floating-labels.css"
|
||||
include_js: false
|
||||
---
|
||||
|
||||
<main class="form-signin">
|
||||
<form>
|
||||
<div class="text-center mb-4">
|
||||
<img class="mb-4" src="/docs/{{< param docs_version >}}/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
|
||||
<h1 class="h3 mb-3 font-weight-normal">Floating labels</h1>
|
||||
<p>Build form controls with floating labels via the <code>:placeholder-shown</code> pseudo-element. <a href="https://caniuse.com/#feat=css-placeholder-shown">Works in latest Chrome, Safari, and Firefox.</a></p>
|
||||
</div>
|
||||
|
||||
<div class="form-label-group">
|
||||
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
|
||||
<label for="inputEmail">Email address</label>
|
||||
</div>
|
||||
|
||||
<div class="form-label-group">
|
||||
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
|
||||
<label for="inputPassword">Password</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox mb-3">
|
||||
<label>
|
||||
<input type="checkbox" value="remember-me"> Remember me
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
|
||||
<p class="mt-5 mb-3 text-muted text-center">© 2017-{{< year >}}</p>
|
||||
</form>
|
||||
</main>
|
||||
104
site/content/docs/5.0/forms/floating-labels.md
Normal file
104
site/content/docs/5.0/forms/floating-labels.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
layout: docs
|
||||
title: Floating labels
|
||||
description: Create beautifully simple form labels that float over your input fields.
|
||||
group: forms
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Example
|
||||
|
||||
Wrap a pair of `<input class="form-control">` and `<label>` elements in `.form-floating` to enable floating labels with Bootstrap's textual form fields. A `placeholder` is required on each `<input>` as our method of CSS-only floating labels uses the `:placeholder-shown` pseudo-element. Also note that the `<input>` must come first so we can utilize a sibling selector (e.g., `~`).
|
||||
|
||||
This approach works in the new Microsoft Edge built on Chromium and gracefully degrades on older versions.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-floating mb-3">
|
||||
<input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
|
||||
<label for="floatingInput">Email address</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control" id="floatingPassword" placeholder="Password">
|
||||
<label for="floatingPassword">Password</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
When there's a `value` already defined, `<label>`s will automatically adjust to their floated position.
|
||||
|
||||
{{< example >}}
|
||||
<form class="form-floating">
|
||||
<input type="email" class="form-control" id="floatingInputValue" placeholder="name@example.com" value="test@example.com">
|
||||
<label for="floatingInputValue">Input with value</label>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
Form validation styles also work as expected.
|
||||
|
||||
{{< example >}}
|
||||
<form class="form-floating">
|
||||
<input type="email" class="form-control is-invalid" id="floatingInputInvalid" placeholder="name@example.com" value="test@example.com">
|
||||
<label for="floatingInputInvalid">Invalid input</label>
|
||||
</form>
|
||||
{{< /example >}}
|
||||
|
||||
## Textareas
|
||||
|
||||
By default, `<textarea>`s with `.form-control` will be the same height as `<input>`s.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-floating">
|
||||
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea"></textarea>
|
||||
<label for="floatingTextarea">Comments</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
To set a custom height on your `<textarea>`, do not use the `rows` attribute. Instead, set an explicit `height` (either inline or via custom CSS).
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-floating">
|
||||
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea2" style="height: 100px"></textarea>
|
||||
<label for="floatingTextarea2">Comments</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Selects
|
||||
|
||||
Other than `.form-control`, floating labels only available on `.form-select`s. They work in the same way, but unlike `<input>`s, they'll always show the `<label>` in its floated state.
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-floating">
|
||||
<select class="form-select" id="floatingSelect" aria-label="Floating label select example">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<label for="floatingSelect">Works with selects</label>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
||||
## Layout
|
||||
|
||||
When working with the Bootstrap grid system, be sure to place form elements within column classes.
|
||||
|
||||
{{< example >}}
|
||||
<div class="row g-2">
|
||||
<div class="col-md">
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" id="floatingInputGrid" placeholder="name@example.com" value="mdo@example.com">
|
||||
<label for="floatingInputGrid">Email address</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="form-floating">
|
||||
<select class="form-select" id="floatingSelectGrid" aria-label="Floating label select example">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<label for="floatingSelectGrid">Works with selects</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{< /example >}}
|
||||
|
|
@ -18,6 +18,8 @@ sections:
|
|||
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: Floating labels
|
||||
description: Create beautifully simple form labels that float over your input fields.
|
||||
- title: Layout
|
||||
description: Create inline, horizontal, or complex grid-based layouts with your forms.
|
||||
- title: Validation
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ toc: true
|
|||
### Forms
|
||||
|
||||
- The longstanding [Missing border radius on input group with validation feedback bug](https://github.com/twbs/bootstrap/issues/25110) is finally fixed by adding an additional `.has-validation` class to input groups with validation.
|
||||
- Promoted the Floating labels example to fully supported form component. [See the new Floating labels page.]({{< docsref "/forms/floating-labels" >}})
|
||||
|
||||
### Utilities
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,6 @@
|
|||
- category: Experiments
|
||||
description: "Examples that focus on future-friendly features or techniques."
|
||||
examples:
|
||||
- name: Floating labels
|
||||
description: "Beautifully simple forms with floating labels over your inputs."
|
||||
- name: Offcanvas
|
||||
description: "Turn your expandable navbar into a sliding offcanvas menu."
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
- title: File
|
||||
- title: Range
|
||||
- title: Input group
|
||||
- title: Floating labels
|
||||
- title: Layout
|
||||
- title: Validation
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
Loading…
Reference in a new issue