@ionic/core
Version:
Base components for Ionic
650 lines (582 loc) • 17.6 kB
CSS
/**
* Convert a font size to a dynamic font size.
* Fonts that participate in Dynamic Type should use
* dynamic font sizes.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param unit (optional) - The unit to convert to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* a maximum font size.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* a minimum font size.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* maximum and minimum font sizes.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
* @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* A heuristic that applies CSS to tablet
* viewports.
*
* Usage:
* @include tablet-viewport() {
* :host {
* background-color: green;
* }
* }
*/
/**
* A heuristic that applies CSS to mobile
* viewports (i.e. phones, not tablets).
*
* Usage:
* @include mobile-viewport() {
* :host {
* background-color: blue;
* }
* }
*/
:host {
/**
* @prop --track-background: Background of the toggle track
* @prop --track-background-checked: Background of the toggle track when checked
* @prop --border-radius: Border radius of the toggle track
*
* @prop --handle-background: Background of the toggle handle
* @prop --handle-background-checked: Background of the toggle handle when checked
*
* @prop --handle-border-radius: Border radius of the toggle handle
* @prop --handle-box-shadow: Box shadow of the toggle handle
* @prop --handle-height: Height of the toggle handle
* @prop --handle-max-height: Maximum height of the toggle handle
* @prop --handle-width: Width of the toggle handle
* @prop --handle-spacing: Horizontal spacing around the toggle handle
* @prop --handle-transition: Transition of the toggle handle
*/
/* stylelint-disable-next-line declaration-no-important */
box-sizing: content-box ;
display: inline-block;
position: relative;
max-width: 100%;
outline: none;
cursor: pointer;
user-select: none;
z-index: 2;
}
:host(.in-item) {
flex: 1 1 0;
width: 100%;
height: 100%;
}
/**
* Toggle can be slotted
* in components such as item and
* toolbar which is why we do not
* limit the below behavior to just ion-item.
*/
:host([slot=start]),
:host([slot=end]) {
flex: initial;
width: auto;
}
:host(.ion-focused) input {
border: 2px solid #5e9ed6;
}
:host(.toggle-disabled) {
pointer-events: none;
}
input {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 0;
outline: 0;
clip: rect(0 0 0 0);
opacity: 0;
overflow: hidden;
-webkit-appearance: none;
-moz-appearance: none;
}
.toggle-wrapper {
display: flex;
position: relative;
flex-grow: 1;
align-items: center;
justify-content: space-between;
height: inherit;
transition: background-color 15ms linear;
cursor: inherit;
}
.label-text-wrapper {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
:host(.in-item) .label-text-wrapper {
margin-top: 10px;
margin-bottom: 10px;
}
:host(.in-item.toggle-label-placement-stacked) .label-text-wrapper {
margin-top: 10px;
margin-bottom: 16px;
}
:host(.in-item.toggle-label-placement-stacked) .native-wrapper {
margin-bottom: 10px;
}
/**
* 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 {
display: none;
}
.native-wrapper {
display: flex;
align-items: center;
}
.toggle-bottom {
padding-top: 4px;
display: flex;
justify-content: space-between;
font-size: 0.75rem;
white-space: normal;
}
:host(.toggle-label-placement-stacked) .toggle-bottom {
font-size: 1rem;
}
/**
* Error text should only be shown when .ion-invalid is
* present on the checkbox. Otherwise the helper text should
* be shown.
*/
.toggle-bottom .error-text {
display: none;
color: var(--ion-color-danger, #c5000f);
}
.toggle-bottom .helper-text {
display: block;
color: var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));
}
:host(.ion-touched.ion-invalid) .toggle-bottom .error-text {
display: block;
}
:host(.ion-touched.ion-invalid) .toggle-bottom .helper-text {
display: none;
}
/**
* Label is on the left of the input in LTR and
* on the right in RTL.
*/
:host(.toggle-label-placement-start) .toggle-wrapper {
flex-direction: row;
}
:host(.toggle-label-placement-start) .label-text-wrapper {
/**
* The margin between the label and
* the input should be on the end
* when the label sits at the start.
*/
-webkit-margin-start: 0;
margin-inline-start: 0;
-webkit-margin-end: 16px;
margin-inline-end: 16px;
}
/**
* Label is on the right of the input in LTR and
* on the left in RTL.
*/
:host(.toggle-label-placement-end) .toggle-wrapper {
flex-direction: row-reverse;
justify-content: start;
}
/**
* The margin between the label and
* the input should be on the start
* when the label sits at the end.
*/
:host(.toggle-label-placement-end) .label-text-wrapper {
-webkit-margin-start: 16px;
margin-inline-start: 16px;
-webkit-margin-end: 0;
margin-inline-end: 0;
}
:host(.toggle-label-placement-fixed) .label-text-wrapper {
/**
* The margin between the label and
* the input should be on the end
* when the label sits at the start.
*/
-webkit-margin-start: 0;
margin-inline-start: 0;
-webkit-margin-end: 16px;
margin-inline-end: 16px;
}
/**
* Label is on the left of the input in LTR and
* on the right in RTL. Label also has a fixed width.
*/
:host(.toggle-label-placement-fixed) .label-text-wrapper {
flex: 0 0 100px;
width: 100px;
min-width: 100px;
max-width: 200px;
}
/**
* Label is on top of the toggle.
*/
:host(.toggle-label-placement-stacked) .toggle-wrapper {
flex-direction: column;
text-align: center;
}
:host(.toggle-label-placement-stacked) .label-text-wrapper {
transform: scale(0.75);
/**
* The margin between the label and
* the toggle should be on the bottom
* when the label sits on top.
*/
margin-left: 0;
margin-right: 0;
margin-bottom: 16px;
/**
* Label text should not extend
* beyond the bounds of the toggle.
*/
max-width: calc(100% / 0.75);
}
:host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper {
transform-origin: left top;
}
:host-context([dir=rtl]):host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper, :host-context([dir=rtl]).toggle-label-placement-stacked.toggle-alignment-start .label-text-wrapper {
transform-origin: right top;
}
@supports selector(:dir(rtl)) {
:host(.toggle-label-placement-stacked.toggle-alignment-start:dir(rtl)) .label-text-wrapper {
transform-origin: right top;
}
}
:host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper {
transform-origin: center top;
}
:host-context([dir=rtl]):host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper, :host-context([dir=rtl]).toggle-label-placement-stacked.toggle-alignment-center .label-text-wrapper {
transform-origin: calc(100% - center) top;
}
@supports selector(:dir(rtl)) {
:host(.toggle-label-placement-stacked.toggle-alignment-center:dir(rtl)) .label-text-wrapper {
transform-origin: calc(100% - center) top;
}
}
:host(.toggle-justify-space-between) .toggle-wrapper {
justify-content: space-between;
}
:host(.toggle-justify-start) .toggle-wrapper {
justify-content: start;
}
:host(.toggle-justify-end) .toggle-wrapper {
justify-content: end;
}
:host(.toggle-alignment-start) .toggle-wrapper {
align-items: start;
}
:host(.toggle-alignment-center) .toggle-wrapper {
align-items: center;
}
:host(.toggle-justify-space-between),
:host(.toggle-justify-start),
:host(.toggle-justify-end),
:host(.toggle-alignment-start),
:host(.toggle-alignment-center) {
display: block;
}
.toggle-icon-wrapper {
display: flex;
position: relative;
align-items: center;
width: 100%;
height: 100%;
transition: var(--handle-transition);
will-change: transform;
}
.toggle-icon {
border-radius: var(--border-radius);
display: block;
position: relative;
width: 100%;
height: 100%;
background: var(--track-background);
overflow: inherit;
}
:host(.toggle-checked) .toggle-icon {
background: var(--track-background-checked);
}
.toggle-inner {
border-radius: var(--handle-border-radius);
position: absolute;
left: var(--handle-spacing);
width: var(--handle-width);
height: var(--handle-height);
max-height: var(--handle-max-height);
transition: var(--handle-transition);
background: var(--handle-background);
box-shadow: var(--handle-box-shadow);
contain: strict;
}
/**
* We do not use the @ltr and @rtl mixins
* here because ion-toggle uses the Shadow DOM
* and WebKit does not support :host-context.
*/
:host(.toggle-ltr) .toggle-inner {
left: var(--handle-spacing);
}
:host(.toggle-rtl) .toggle-inner {
right: var(--handle-spacing);
}
:host(.toggle-ltr.toggle-checked) .toggle-icon-wrapper {
transform: translate3d(calc(100% - var(--handle-width)), 0, 0);
}
:host(.toggle-rtl.toggle-checked) .toggle-icon-wrapper {
transform: translate3d(calc(-100% + var(--handle-width)), 0, 0);
}
:host(.toggle-checked) .toggle-inner {
background: var(--handle-background-checked);
}
:host(.toggle-ltr.toggle-checked) .toggle-inner {
transform: translate3d(calc(var(--handle-spacing) * -2), 0, 0);
}
:host(.toggle-rtl.toggle-checked) .toggle-inner {
transform: translate3d(calc(var(--handle-spacing) * 2), 0, 0);
}
/**
* Convert a font size to a dynamic font size.
* Fonts that participate in Dynamic Type should use
* dynamic font sizes.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param unit (optional) - The unit to convert to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* a maximum font size.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* a minimum font size.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* maximum and minimum font sizes.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
* @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* A heuristic that applies CSS to tablet
* viewports.
*
* Usage:
* @include tablet-viewport() {
* :host {
* background-color: green;
* }
* }
*/
/**
* A heuristic that applies CSS to mobile
* viewports (i.e. phones, not tablets).
*
* Usage:
* @include mobile-viewport() {
* :host {
* background-color: blue;
* }
* }
*/
/**
* Convert a font size to a dynamic font size.
* Fonts that participate in Dynamic Type should use
* dynamic font sizes.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param unit (optional) - The unit to convert to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* a maximum font size.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* a minimum font size.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* Convert a font size to a dynamic font size but impose
* maximum and minimum font sizes.
* @param size - The initial font size including the unit (i.e. px or pt)
* @param minScale - The minimum scale of the font (i.e. 0.8 for a minimum 80% scale).
* @param maxScale - The maximum scale of the font (i.e. 2.5 for a maximum 250% scale).
* @param unit (optional) - The unit to convert the initial font size to. Use this if you want to
* convert to a unit other than $baselineUnit.
*/
/**
* A heuristic that applies CSS to tablet
* viewports.
*
* Usage:
* @include tablet-viewport() {
* :host {
* background-color: green;
* }
* }
*/
/**
* A heuristic that applies CSS to mobile
* viewports (i.e. phones, not tablets).
*
* Usage:
* @include mobile-viewport() {
* :host {
* background-color: blue;
* }
* }
*/
:host {
--track-background: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.088);
--track-background-checked: var(--ion-color-primary, #0054e9);
--border-radius: 15.5px;
--handle-background: #ffffff;
--handle-background-checked: #ffffff;
--handle-border-radius: 25.5px;
--handle-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.06), 0 3px 8px rgba(0, 0, 0, 0.06);
--handle-height: calc(31px - (2px * 2));
--handle-max-height: calc(100% - var(--handle-spacing) * 2);
--handle-width: calc(31px - (2px * 2));
--handle-spacing: 2px;
--handle-transition: transform 300ms, width 120ms ease-in-out 80ms, left 110ms ease-in-out 80ms, right 110ms ease-in-out 80ms;
}
.native-wrapper .toggle-icon {
width: 51px;
height: 31px;
/**
* The handle box shadow should not
* overflow outside of the track container.
*/
overflow: hidden;
}
:host(.ion-color.toggle-checked) .toggle-icon {
background: var(--ion-color-base);
}
:host(.toggle-activated) .toggle-switch-icon {
opacity: 0;
}
.toggle-icon {
transform: translate3d(0, 0, 0);
transition: background-color 300ms;
}
.toggle-inner {
will-change: transform;
}
.toggle-switch-icon {
position: absolute;
top: 50%;
width: 11px;
height: 11px;
transform: translateY(-50%);
transition: opacity 300ms, color 300ms;
}
.toggle-switch-icon {
position: absolute;
color: var(--ion-color-dark, #222428);
}
:host(.toggle-ltr) .toggle-switch-icon {
/* stylelint-disable-next-line property-disallowed-list */
right: 6px;
}
:host(.toggle-rtl) .toggle-switch-icon {
/* stylelint-disable property-disallowed-list */
right: initial;
left: 6px;
/* stylelint-enable property-disallowed-list */
}
:host(.toggle-checked) .toggle-switch-icon.toggle-switch-icon-checked {
color: var(--ion-color-contrast, #fff);
}
:host(.toggle-checked) .toggle-switch-icon:not(.toggle-switch-icon-checked) {
opacity: 0;
}
.toggle-switch-icon-checked {
position: absolute;
width: 15px;
height: 15px;
transform: translateY(-50%) rotate(90deg);
}
:host(.toggle-ltr) .toggle-switch-icon-checked {
/* stylelint-disable property-disallowed-list */
right: initial;
left: 4px;
/* stylelint-enable property-disallowed-list */
}
:host(.toggle-rtl) .toggle-switch-icon-checked {
/* stylelint-disable-next-line property-disallowed-list */
right: 4px;
}
:host(.toggle-activated) .toggle-icon::before,
:host(.toggle-checked) .toggle-icon::before {
transform: scale3d(0, 0, 0);
}
:host(.toggle-activated.toggle-checked) .toggle-inner::before {
transform: scale3d(0, 0, 0);
}
:host(.toggle-activated) .toggle-inner {
width: calc(var(--handle-width) + 6px);
}
:host(.toggle-ltr.toggle-activated.toggle-checked) .toggle-icon-wrapper {
transform: translate3d(calc(100% - var(--handle-width) - 6px), 0, 0);
}
:host(.toggle-rtl.toggle-activated.toggle-checked) .toggle-icon-wrapper {
transform: translate3d(calc(-100% + var(--handle-width) + 6px), 0, 0);
}
:host(.toggle-disabled) {
opacity: 0.3;
}