octicon-rss(16/)
You've already forked ionic-framework
mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
⚠️ This is a combination of previously approved PRs with the
exception of
fe9dca513c.
This change was made as a result of
https://github.com/ionic-team/ionic-framework-design-documents/pull/248.
Issue number: Internal
---------
<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->
<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->
Users do not have a way of increasing the contrast in Ionic apps. This
is valuable for people with low vision as increasing the contrast
between foreground and background content helps improve readability.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Adds a high contrast light and high contrast dark theme. As with our
other themes, developers can choose between system, class, and always
stylesheets.
While we aim to improve contrast for text and UI components, this
feature prioritizes text in the event that both text and UI component
cannot be improved without one negatively impacting the other.
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
<!--
If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer
for more information.
-->
## Other information
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
Dev build: `7.6.7-dev.11706894781.1cd59fde`
Testing instructions:
1. Open `src/themes/test/css-variables`. Activate the high contrast
light and dark themes to verify that contrast does increase.
2. Use the dev build to integrate the theme into a test app (conference
app, starter app, etc).
I'd recommend using these imports:
```css
@import "@ionic/angular/css/themes/high-contrast.system.css";
@import "@ionic/angular/css/themes/high-contrast-dark.system.css";
```
Note: Make sure this is imported **after** `core.scss`
---------
Co-authored-by: Shawn Taylor <shawn@ionic.io>
Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com>
Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
Co-authored-by: Amanda Johnston <90629384+amandaejohnston@users.noreply.github.com>
713 lines
18 KiB
SCSS
713 lines
18 KiB
SCSS
@import "./textarea.vars";
|
|
|
|
// Textarea
|
|
// --------------------------------------------------
|
|
|
|
:host {
|
|
/**
|
|
* @prop --background: Background of the textarea
|
|
*
|
|
* @prop --border-radius: Border radius of the textarea
|
|
* @prop --border-color: Color of the border below the textarea when using helper text, error text, or counter
|
|
* @prop --border-radius: Radius of the textarea border. A large radius may display unevenly when using fill="outline"; if needed, use shape="round" instead or increase --padding-start.
|
|
* @prop --border-style: Style of the border below the textarea when using helper text, error text, or counter
|
|
* @prop --border-width: Width of the border below the textarea when using helper text, error text, or counter
|
|
*
|
|
* @prop --color: Color of the text
|
|
*
|
|
* @prop --placeholder-color: Color of the placeholder text
|
|
* @prop --placeholder-font-style: Style of the placeholder text
|
|
* @prop --placeholder-font-weight: Weight of the placeholder text
|
|
* @prop --placeholder-opacity: Opacity of the placeholder text
|
|
*
|
|
* @prop --highlight-color-focused: The color of the highlight on the textarea when focused
|
|
* @prop --highlight-color-valid: The color of the highlight on the textarea when valid
|
|
* @prop --highlight-color-invalid: The color of the highlight on the textarea when invalid
|
|
*
|
|
* @prop --padding-top: Top padding of the textarea
|
|
* @prop --padding-end: Right padding if direction is left-to-right, and left padding if direction is right-to-left of the textarea
|
|
* @prop --padding-bottom: Bottom padding of the textarea
|
|
* @prop --padding-start: Left padding if direction is left-to-right, and right padding if direction is right-to-left of the textarea
|
|
*/
|
|
--background: initial;
|
|
--color: initial;
|
|
--placeholder-color: initial;
|
|
--placeholder-font-style: initial;
|
|
--placeholder-font-weight: initial;
|
|
--placeholder-opacity: #{$placeholder-opacity};
|
|
--padding-top: 0;
|
|
--padding-end: 0;
|
|
--padding-bottom: #{$textarea-padding-bottom};
|
|
--padding-start: 0;
|
|
--border-radius: 0;
|
|
--border-style: solid;
|
|
--highlight-color-focused: #{ion-color(primary, base)};
|
|
--highlight-color-valid: #{ion-color(success, base)};
|
|
--highlight-color-invalid: #{ion-color(danger, base)};
|
|
|
|
/**
|
|
* This is a private API that is used to switch
|
|
* out the highlight color based on the state
|
|
* of the component without having to write
|
|
* different selectors for different fill variants.
|
|
*/
|
|
--highlight-color: var(--highlight-color-focused);
|
|
|
|
display: block;
|
|
position: relative;
|
|
|
|
width: 100%;
|
|
|
|
min-height: 44px;
|
|
|
|
color: var(--color);
|
|
|
|
font-family: $font-family-base;
|
|
|
|
z-index: $z-index-item-input;
|
|
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
// Textarea Wrapper
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Since the label sits on top of the element,
|
|
* the component needs to be taller otherwise the
|
|
* label will appear too close to the textarea text.
|
|
* Also, floating and stacked labels should not
|
|
* push the label down since it it
|
|
* sits on top of the textarea.
|
|
*/
|
|
:host(.textarea-label-placement-floating),
|
|
:host(.textarea-label-placement-stacked) {
|
|
--padding-top: 0px;
|
|
|
|
min-height: 56px;
|
|
}
|
|
|
|
/**
|
|
* When the cols property is set we should
|
|
* respect that width instead of defaulting
|
|
* to taking up the entire line.
|
|
* Requires both the cols and autoGrow
|
|
* properties to be reflected as attributes
|
|
* on the host.
|
|
*
|
|
* cols does not work with autoGrow because
|
|
* autoGrow would prevent line breaks from naturally
|
|
* occurring until the textarea takes up the entire line width.
|
|
*/
|
|
:host([cols]:not([auto-grow])) {
|
|
width: fit-content;
|
|
}
|
|
|
|
:host(.ion-color) {
|
|
--highlight-color-focused: #{current-color(base)};
|
|
|
|
background: initial;
|
|
}
|
|
|
|
// Textarea Within An Item
|
|
// --------------------------------------------------
|
|
|
|
:host-context(ion-item) {
|
|
align-self: baseline;
|
|
}
|
|
|
|
:host-context(ion-item:not(.item-label)) {
|
|
--padding-start: 0;
|
|
}
|
|
|
|
:host-context(ion-item)[slot="start"],
|
|
:host-context(ion-item)[slot="end"] {
|
|
width: auto;
|
|
}
|
|
|
|
// Native Textarea
|
|
// --------------------------------------------------
|
|
|
|
.native-textarea {
|
|
// Browsers may add a default margin to the textarea
|
|
@include margin(0);
|
|
@include padding(0, 0, 0, 0);
|
|
|
|
display: block;
|
|
|
|
position: relative;
|
|
|
|
flex: 1;
|
|
|
|
width: 100%;
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
|
|
border: 0;
|
|
|
|
outline: none;
|
|
|
|
background: transparent;
|
|
|
|
white-space: pre-wrap;
|
|
|
|
/**
|
|
* This ensures the textarea
|
|
* remains on top of any decoration
|
|
* that we render (particularly the
|
|
* outline border when fill="outline").
|
|
* If we did not do this then Axe would
|
|
* be unable to determine the color
|
|
* contrast of the textarea.
|
|
*/
|
|
z-index: 1;
|
|
box-sizing: border-box;
|
|
resize: none;
|
|
appearance: none;
|
|
|
|
&::placeholder {
|
|
@include padding(0);
|
|
|
|
color: var(--placeholder-color);
|
|
|
|
font-family: inherit;
|
|
font-style: var(--placeholder-font-style);
|
|
font-weight: var(--placeholder-font-weight);
|
|
|
|
opacity: var(--placeholder-opacity);
|
|
}
|
|
}
|
|
|
|
.native-textarea {
|
|
color: inherit;
|
|
|
|
font-family: inherit;
|
|
font-size: inherit;
|
|
font-style: inherit;
|
|
font-weight: inherit;
|
|
|
|
letter-spacing: inherit;
|
|
|
|
text-align: inherit;
|
|
text-decoration: inherit;
|
|
text-indent: inherit;
|
|
text-overflow: inherit;
|
|
text-transform: inherit;
|
|
|
|
grid-area: 1 / 1 / 2 / 2;
|
|
|
|
word-break: break-word;
|
|
}
|
|
|
|
// Input Cover: Unfocused
|
|
// --------------------------------------------------
|
|
// The input cover is the div that actually receives the
|
|
// tap/click event when scroll assist is configured to true.
|
|
// This make it so the native input element is not clickable.
|
|
// This will only show when the scroll assist is configured
|
|
// otherwise the .input-cover will not be rendered at all
|
|
// The input cover is not clickable when the input is disabled
|
|
.cloned-input {
|
|
@include position(0, null, 0, 0);
|
|
|
|
position: absolute;
|
|
|
|
pointer-events: none;
|
|
}
|
|
|
|
/**
|
|
* The cloned input needs to be disabled on
|
|
* Android otherwise the viewport will still
|
|
* shift when running scroll assist.
|
|
*/
|
|
.cloned-input:disabled {
|
|
opacity: 1;
|
|
}
|
|
|
|
:host([auto-grow]) .cloned-input {
|
|
// Workaround for webkit rendering issue with scroll assist.
|
|
// When cloning the textarea and scrolling into view,
|
|
// a white box is rendered from the difference in height
|
|
// from the auto grow container.
|
|
// This change forces the cloned input to match the true
|
|
// height of the textarea container.
|
|
height: 100%;
|
|
}
|
|
|
|
:host([auto-grow]) .native-textarea {
|
|
overflow: hidden;
|
|
}
|
|
|
|
// Item Floating: Placeholder
|
|
// ----------------------------------------------------------------
|
|
// When used with a floating item the placeholder should hide
|
|
|
|
:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value)) {
|
|
opacity: 0;
|
|
}
|
|
|
|
:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value).item-has-focus) {
|
|
transition: opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
opacity: 1;
|
|
}
|
|
|
|
// Textarea Wrapper
|
|
// ----------------------------------------------------------------
|
|
|
|
.textarea-wrapper {
|
|
@include padding(0px, var(--padding-end), 0px, var(--padding-start));
|
|
@include border-radius(var(--border-radius));
|
|
|
|
display: flex;
|
|
|
|
position: relative;
|
|
|
|
flex-grow: 1;
|
|
|
|
align-items: flex-start;
|
|
|
|
height: inherit;
|
|
|
|
min-height: inherit;
|
|
|
|
transition: background-color 15ms linear;
|
|
|
|
background: var(--background);
|
|
|
|
line-height: normal;
|
|
}
|
|
|
|
// Textarea Native Wrapper
|
|
// ----------------------------------------------------------------
|
|
|
|
.native-wrapper {
|
|
position: relative;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
}
|
|
|
|
// Textarea Native
|
|
// ----------------------------------------------------------------
|
|
|
|
:host(.has-focus) textarea {
|
|
caret-color: var(--highlight-color);
|
|
}
|
|
|
|
.native-wrapper textarea {
|
|
@include padding(var(--padding-top), 0px, var(--padding-bottom), 0px);
|
|
}
|
|
|
|
.native-wrapper {
|
|
display: grid;
|
|
|
|
min-width: inherit;
|
|
max-width: inherit;
|
|
min-height: inherit;
|
|
max-height: inherit;
|
|
|
|
/**
|
|
* This avoids a WebKit bug where
|
|
* the height of the inner textarea
|
|
* is incorrect and flows outside the
|
|
* parent container: https://bugs.webkit.org/show_bug.cgi?id=256781
|
|
* TODO FW-4734
|
|
*/
|
|
grid-auto-rows: 100%;
|
|
|
|
&::after {
|
|
// This technique is used for an auto-resizing textarea.
|
|
// The text contents are reflected as a pseudo-element that is visually hidden.
|
|
// This causes the textarea container to grow as needed to fit the contents.
|
|
|
|
white-space: pre-wrap;
|
|
|
|
content: attr(data-replicated-value) " ";
|
|
|
|
visibility: hidden;
|
|
}
|
|
}
|
|
|
|
.native-wrapper::after {
|
|
@include padding(var(--padding-top), 0, var(--padding-bottom), 0);
|
|
@include margin(0, 0, 0, 0);
|
|
@include border-radius(var(--border-radius));
|
|
|
|
/**
|
|
* Note: Do not use @include text-inherit()
|
|
* as that sets white-space: inherit
|
|
* Instead, we use white-space: pre-wrap above.
|
|
*/
|
|
color: inherit;
|
|
|
|
font-family: inherit;
|
|
font-size: inherit;
|
|
font-style: inherit;
|
|
font-weight: inherit;
|
|
|
|
letter-spacing: inherit;
|
|
|
|
text-align: inherit;
|
|
text-decoration: inherit;
|
|
text-indent: inherit;
|
|
text-overflow: inherit;
|
|
text-transform: inherit;
|
|
|
|
grid-area: 1 / 1 / 2 / 2;
|
|
|
|
word-break: break-word;
|
|
}
|
|
|
|
.textarea-wrapper-inner {
|
|
display: flex;
|
|
|
|
width: 100%;
|
|
min-height: inherit;
|
|
}
|
|
|
|
// Textarea Highlight
|
|
// ----------------------------------------------------------------
|
|
|
|
:host(.ion-touched.ion-invalid) {
|
|
--highlight-color: var(--highlight-color-invalid);
|
|
}
|
|
|
|
/**
|
|
* The component highlight is only shown
|
|
* on focus, so we can safely set the valid
|
|
* color state when touched/valid. If we
|
|
* set it when .has-focus is present then
|
|
* the highlight color would change
|
|
* from the valid color to the component's
|
|
* color during the transition after the
|
|
* component loses focus.
|
|
*/
|
|
:host(.ion-valid) {
|
|
--highlight-color: var(--highlight-color-valid);
|
|
}
|
|
|
|
// Textarea Bottom Content
|
|
// ----------------------------------------------------------------
|
|
|
|
.textarea-bottom {
|
|
/**
|
|
* The bottom content should take on the start and end
|
|
* padding so it is always aligned with either the label
|
|
* or the start of the textarea.
|
|
*/
|
|
@include padding(5px, var(--padding-end), 0, var(--padding-start));
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
border-top: var(--border-width) var(--border-style) var(--border-color);
|
|
|
|
font-size: dynamic-font(12px);
|
|
}
|
|
|
|
/**
|
|
* If the textarea has a validity state, the
|
|
* border and label should reflect that as a color.
|
|
*/
|
|
:host(.has-focus.ion-valid),
|
|
:host(.ion-touched.ion-invalid) {
|
|
--border-color: var(--highlight-color);
|
|
}
|
|
|
|
// Textarea Hint Text
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Error text should only be shown when .ion-invalid is
|
|
* present on the textarea. Otherwise the helper text should
|
|
* be shown.
|
|
*/
|
|
.textarea-bottom .error-text {
|
|
display: none;
|
|
|
|
color: var(--highlight-color-invalid);
|
|
}
|
|
|
|
.textarea-bottom .helper-text {
|
|
display: block;
|
|
|
|
color: #{$text-color-step-450};
|
|
}
|
|
|
|
:host(.ion-touched.ion-invalid) .textarea-bottom .error-text {
|
|
display: block;
|
|
}
|
|
|
|
:host(.ion-touched.ion-invalid) .textarea-bottom .helper-text {
|
|
display: none;
|
|
}
|
|
|
|
// Textarea Max Length Counter
|
|
// ----------------------------------------------------------------
|
|
|
|
.textarea-bottom .counter {
|
|
/**
|
|
* Counter should always be at
|
|
* the end of the container even
|
|
* when no helper/error texts are used.
|
|
*/
|
|
@include margin-horizontal(auto, null);
|
|
|
|
color: #{$text-color-step-450};
|
|
|
|
white-space: nowrap;
|
|
|
|
padding-inline-start: 16px;
|
|
}
|
|
|
|
// Textarea Label
|
|
// ----------------------------------------------------------------
|
|
|
|
.label-text-wrapper {
|
|
@include padding(var(--padding-top), 0px, var(--padding-bottom), 0px);
|
|
|
|
/**
|
|
* Label text should not extend
|
|
* beyond the bounds of the textarea.
|
|
* However, we do not set the max
|
|
* width to 100% because then
|
|
* only the label would show and users
|
|
* would not be able to see what they are typing.
|
|
*/
|
|
max-width: 200px;
|
|
|
|
transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
/**
|
|
* This ensures that double tapping this text
|
|
* clicks the <label> and focuses the textarea
|
|
* when a screen reader is enabled.
|
|
*/
|
|
pointer-events: none;
|
|
}
|
|
|
|
/**
|
|
* We need to use two elements instead of
|
|
* one. The .label-text-wrapper is responsible
|
|
* for centering the label text vertically regardless
|
|
* of the textarea height using flexbox.
|
|
*
|
|
* The .label-text element is responsible for controlling
|
|
* overflow when label-placement="fixed".
|
|
* We want the ellipses to show up when the
|
|
* fixed label overflows, but text-overflow: ellipsis only
|
|
* works on block-level elements. A flex item is
|
|
* considered blockified (https://www.w3.org/TR/css-display-3/#blockify).
|
|
*/
|
|
.label-text,
|
|
::slotted([slot="label"]) {
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
overflow: hidden;
|
|
}
|
|
|
|
/**
|
|
* If no label text is placed into the slot
|
|
* then the element should be hidden otherwise
|
|
* there will be additional margins added.
|
|
*/
|
|
.label-text-wrapper-hidden,
|
|
.textarea-outline-notch-hidden {
|
|
display: none;
|
|
}
|
|
|
|
.textarea-wrapper textarea {
|
|
/**
|
|
* When the floating label appears on top of the
|
|
* textarea, we need to fade the textarea out so that the
|
|
* label does not overlap with the placeholder.
|
|
*/
|
|
transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
|
|
// Textarea Label Placement - Start
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Label is on the left of the textarea in LTR and
|
|
* on the right in RTL.
|
|
*/
|
|
:host(.textarea-label-placement-start) .textarea-wrapper {
|
|
flex-direction: row;
|
|
}
|
|
|
|
:host(.textarea-label-placement-start) .label-text-wrapper {
|
|
/**
|
|
* The margin between the label and
|
|
* the textarea should be on the end
|
|
* when the label sits at the start.
|
|
*/
|
|
@include margin(0, $form-control-label-margin, 0, 0);
|
|
}
|
|
|
|
// Textarea Label Placement - End
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Label is on the right of the textarea in LTR and
|
|
* on the left in RTL.
|
|
*/
|
|
:host(.textarea-label-placement-end) .textarea-wrapper {
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
/**
|
|
* The margin between the label and
|
|
* the textarea should be on the start
|
|
* when the label sits at the end.
|
|
*/
|
|
:host(.textarea-label-placement-end) .label-text-wrapper {
|
|
@include margin(0, 0, 0, $form-control-label-margin);
|
|
}
|
|
|
|
// Textarea Label Placement - Fixed
|
|
// ----------------------------------------------------------------
|
|
|
|
:host(.textarea-label-placement-fixed) .label-text-wrapper {
|
|
/**
|
|
* The margin between the label and
|
|
* the textarea should be on the end
|
|
* when the label sits at the start.
|
|
*/
|
|
@include margin(0, $form-control-label-margin, 0, 0);
|
|
}
|
|
|
|
/**
|
|
* Label is on the left of the textarea in LTR and
|
|
* on the right in RTL. Label also has a fixed width.
|
|
*/
|
|
:host(.textarea-label-placement-fixed) .label-text {
|
|
flex: 0 0 100px;
|
|
|
|
width: 100px;
|
|
min-width: 100px;
|
|
max-width: 200px;
|
|
}
|
|
|
|
// Textarea Label Placement - Stacked and Floating
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Stacked: Label sits above the textarea and is scaled down.
|
|
* Floating: Label sits over the textarea when the textarea has no
|
|
* value and is blurred. Label sits above the textarea and is scaled
|
|
* down when the textarea is focused or has a value.
|
|
*
|
|
*/
|
|
:host(.textarea-label-placement-stacked) .textarea-wrapper,
|
|
:host(.textarea-label-placement-floating) .textarea-wrapper {
|
|
flex-direction: column;
|
|
align-items: start;
|
|
}
|
|
|
|
/**
|
|
* Ensures that the label animates
|
|
* up and to the left in LTR or
|
|
* up and to the right in RTL.
|
|
*/
|
|
:host(.textarea-label-placement-stacked) .label-text-wrapper,
|
|
:host(.textarea-label-placement-floating) .label-text-wrapper {
|
|
@include transform-origin(start, top);
|
|
@include padding(0px);
|
|
|
|
max-width: 100%;
|
|
|
|
/**
|
|
* The 2 ensures the label
|
|
* remains on top of any browser
|
|
* autofill background too.
|
|
*/
|
|
z-index: 2;
|
|
}
|
|
|
|
/**
|
|
* Ensures the textarea does not
|
|
* overlap the label.
|
|
*/
|
|
:host(.textarea-label-placement-stacked) textarea,
|
|
:host(.textarea-label-placement-floating) textarea,
|
|
:host(.textarea-label-placement-stacked[auto-grow]) .native-wrapper::after,
|
|
:host(.textarea-label-placement-floating[auto-grow]) .native-wrapper::after {
|
|
@include margin(8px, 0px, 0px, 0px);
|
|
}
|
|
|
|
:host(.textarea-label-placement-stacked) ::slotted([slot="start"]),
|
|
:host(.textarea-label-placement-stacked) ::slotted([slot="end"]),
|
|
:host(.textarea-label-placement-floating) ::slotted([slot="start"]),
|
|
:host(.textarea-label-placement-floating) ::slotted([slot="end"]) {
|
|
margin-top: 8px;
|
|
}
|
|
|
|
/**
|
|
* This makes the label sit over the textarea
|
|
* when the textarea is blurred and has no value.
|
|
*/
|
|
:host(.textarea-label-placement-floating) .label-text-wrapper {
|
|
@include transform(translateY(100%), scale(1));
|
|
}
|
|
|
|
/**
|
|
* The textarea should be hidden when the label
|
|
* is on top of the textarea. This prevents the label
|
|
* from overlapping any placeholder value.
|
|
*/
|
|
:host(.textarea-label-placement-floating) textarea {
|
|
opacity: 0;
|
|
}
|
|
|
|
:host(.has-focus.textarea-label-placement-floating) textarea,
|
|
:host(.has-value.textarea-label-placement-floating) textarea {
|
|
opacity: 1;
|
|
}
|
|
|
|
/**
|
|
* This makes the label sit above the textarea.
|
|
*/
|
|
:host(.label-floating) .label-text-wrapper {
|
|
@include transform(translateY(50%), scale(#{$form-control-label-stacked-scale}));
|
|
|
|
/**
|
|
* Label text should not extend
|
|
* beyond the bounds of the textarea.
|
|
*/
|
|
max-width: calc(100% / #{$form-control-label-stacked-scale});
|
|
}
|
|
|
|
// Start/End Slots
|
|
// ----------------------------------------------------------------
|
|
|
|
.start-slot-wrapper, .end-slot-wrapper {
|
|
@include padding(var(--padding-top), 0, var(--padding-bottom), 0);
|
|
|
|
display: flex;
|
|
|
|
flex-shrink: 0;
|
|
|
|
align-self: start;
|
|
}
|
|
|
|
::slotted([slot="start"]),
|
|
::slotted([slot="end"]) {
|
|
margin-top: 0; // ensure slot content is vertically aligned with label
|
|
}
|
|
|
|
::slotted([slot="start"]) {
|
|
margin-inline-end: $form-control-label-margin;
|
|
margin-inline-start: 0;
|
|
}
|
|
|
|
::slotted([slot="end"]) {
|
|
margin-inline-start: $form-control-label-margin;
|
|
margin-inline-end: 0;
|
|
}
|