mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-23 05:58:26 +08:00
refactor(components): update to use shadow DOM and work with css variables
- updates components to use shadow DOM or scoped if they require css variables - moves global styles to an external stylesheet that needs to be imported - adds support for additional colors and removes the Sass loops to generate colors for each component - several property renames, bug fixes, and test updates Co-authored-by: Manu Mtz.-Almeida <manu.mtza@gmail.com> Co-authored-by: Adam Bradley <adambradley25@gmail.com> Co-authored-by: Cam Wiegert <cam@camwiegert.com>
This commit is contained in:
24
core/src/css/colors.scss
Normal file
24
core/src/css/colors.scss
Normal file
@ -0,0 +1,24 @@
|
||||
@import "../themes/ionic.globals";
|
||||
|
||||
@mixin generate-color($color-name) {
|
||||
$value: map-get($colors, $color-name);
|
||||
|
||||
$base: map-get($value, base);
|
||||
$contrast: map-get($value, contrast);
|
||||
$shade: map-get($value, shade);
|
||||
$tint: map-get($value, tint);
|
||||
|
||||
--ion-color-base: var(--ion-color-#{$color-name}, #{$base}) !important;
|
||||
--ion-color-base-rgb: var(--ion-color-#{$color-name}-rgb, #{color-to-rgb-list($base)}) !important;
|
||||
--ion-color-contrast: var(--ion-color-#{$color-name}-contrast, #{$contrast}) !important;
|
||||
--ion-color-contrast-rgb: var(--ion-color-#{$color-name}-contrast-rgb, #{color-to-rgb-list($contrast)}) !important;
|
||||
--ion-color-shade: var(--ion-color-#{$color-name}-shade, #{$shade}) !important;
|
||||
--ion-color-tint: var(--ion-color-#{$color-name}-tint, #{$tint}) !important;
|
||||
}
|
||||
|
||||
@each $color-name, $value in $colors {
|
||||
.ion-color-#{$color-name} {
|
||||
@include generate-color($color-name);
|
||||
}
|
||||
}
|
||||
|
82
core/src/css/flex-utils.scss
Normal file
82
core/src/css/flex-utils.scss
Normal file
@ -0,0 +1,82 @@
|
||||
// Column Alignment
|
||||
// --------------------------------------------------
|
||||
|
||||
[align-self-start] {
|
||||
align-self: flex-start !important;
|
||||
}
|
||||
|
||||
[align-self-end] {
|
||||
align-self: flex-end !important;
|
||||
}
|
||||
|
||||
[align-self-center] {
|
||||
align-self: center !important;
|
||||
}
|
||||
|
||||
[align-self-stretch] {
|
||||
align-self: stretch !important;
|
||||
}
|
||||
|
||||
[align-self-baseline] {
|
||||
align-self: baseline !important;
|
||||
}
|
||||
|
||||
|
||||
// Column Wrap
|
||||
// --------------------------------------------------
|
||||
|
||||
[nowrap] {
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
[wrap-reverse] {
|
||||
flex-wrap: wrap-reverse !important;
|
||||
}
|
||||
|
||||
|
||||
// Justify Content
|
||||
// --------------------------------------------------
|
||||
|
||||
[justify-content-start] {
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
[justify-content-center] {
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
[justify-content-end] {
|
||||
justify-content: flex-end !important;
|
||||
}
|
||||
|
||||
[justify-content-around] {
|
||||
justify-content: space-around !important;
|
||||
}
|
||||
|
||||
[justify-content-between] {
|
||||
justify-content: space-between !important;
|
||||
}
|
||||
|
||||
|
||||
// Align Items
|
||||
// --------------------------------------------------
|
||||
|
||||
[align-items-start] {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
[align-items-center] {
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
[align-items-end] {
|
||||
align-items: flex-end !important;
|
||||
}
|
||||
|
||||
[align-items-stretch] {
|
||||
align-items: stretch !important;
|
||||
}
|
||||
|
||||
[align-items-baseline] {
|
||||
align-items: baseline !important;
|
||||
}
|
28
core/src/css/float-elements.scss
Normal file
28
core/src/css/float-elements.scss
Normal file
@ -0,0 +1,28 @@
|
||||
@import "../themes/ionic.globals";
|
||||
@import "../themes/ionic.mixins";
|
||||
|
||||
|
||||
// Creates text transform attributes based on screen size
|
||||
@each $breakpoint in map-keys($screen-breakpoints) {
|
||||
$infix: breakpoint-infix($breakpoint, $screen-breakpoints);
|
||||
|
||||
@include media-breakpoint-up($breakpoint, $screen-breakpoints) {
|
||||
// Provide `[float-{bp}]` attributes for floating the element based
|
||||
// on the breakpoint
|
||||
[float#{$infix}-left] {
|
||||
@include float(left, !important);
|
||||
}
|
||||
|
||||
[float#{$infix}-right] {
|
||||
@include float(right, !important);
|
||||
}
|
||||
|
||||
[float#{$infix}-start] {
|
||||
@include float(start, !important);
|
||||
}
|
||||
|
||||
[float#{$infix}-end] {
|
||||
@include float(end, !important);
|
||||
}
|
||||
}
|
||||
}
|
10
core/src/css/ionic.scss
Normal file
10
core/src/css/ionic.scss
Normal file
@ -0,0 +1,10 @@
|
||||
@import "./normalize";
|
||||
@import "./structure";
|
||||
@import "./typography";
|
||||
@import "./colors";
|
||||
|
||||
@import "./padding";
|
||||
@import "./float-elements";
|
||||
@import "./text-alignment";
|
||||
@import "./text-transformation";
|
||||
@import "./flex-utils";
|
234
core/src/css/normalize.scss
vendored
Normal file
234
core/src/css/normalize.scss
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
// ! normalize.css v3.0.2 | MIT License | github.com/necolas/normalize.css
|
||||
|
||||
|
||||
// HTML5 display definitions
|
||||
// ==========================================================================
|
||||
|
||||
// 1. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
vertical-align: baseline; // 1
|
||||
}
|
||||
|
||||
// Prevent modern browsers from displaying `audio` without controls.
|
||||
// Remove excess height in iOS 5 devices.
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
|
||||
height: 0;
|
||||
}
|
||||
|
||||
|
||||
// Text-level semantics
|
||||
// ==========================================================================
|
||||
|
||||
// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
// Embedded content
|
||||
// ==========================================================================
|
||||
|
||||
// Remove border when inside `a` element in IE 8/9/10.
|
||||
img {
|
||||
max-width: 100%;
|
||||
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Correct overflow not hidden in IE 9/10/11.
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
// Grouping content
|
||||
// ==========================================================================
|
||||
|
||||
// Address margin not present in IE 8/9 and Safari.
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 1px;
|
||||
|
||||
border-width: 0;
|
||||
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
// Contain overflow in all browsers.
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
// Address odd `em`-unit font size rendering in all browsers.
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
|
||||
// Forms
|
||||
// ==========================================================================
|
||||
|
||||
// Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||
// styling of `select`, unless a `border` property is set.
|
||||
|
||||
// 1. Correct color not being inherited.
|
||||
// Known issue: affects color of disabled elements.
|
||||
// 2. Correct font properties not being inherited.
|
||||
// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
label,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
|
||||
height: auto;
|
||||
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
textarea::placeholder {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
form,
|
||||
input,
|
||||
optgroup,
|
||||
select {
|
||||
margin: 0; // 3
|
||||
|
||||
font: inherit; // 2
|
||||
color: inherit; // 1
|
||||
}
|
||||
|
||||
// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
// and `video` controls.
|
||||
// 2. Correct inability to style clickable `input` types in iOS.
|
||||
// 3. Improve usability and consistency of cursor style between image-type
|
||||
// `input` and others.
|
||||
html input[type="button"], // 1
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
cursor: pointer; // 3
|
||||
|
||||
-webkit-appearance: button; // 2
|
||||
}
|
||||
|
||||
// remove 300ms delay
|
||||
a,
|
||||
a div,
|
||||
a span,
|
||||
a ion-icon,
|
||||
a ion-label,
|
||||
button,
|
||||
button div,
|
||||
button span,
|
||||
button ion-icon,
|
||||
button ion-label,
|
||||
[tappable],
|
||||
[tappable] div,
|
||||
[tappable] span,
|
||||
[tappable] ion-icon,
|
||||
[tappable] ion-label,
|
||||
input,
|
||||
textarea {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
a ion-label,
|
||||
button ion-label {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
font-family: inherit;
|
||||
font-style: inherit;
|
||||
font-variant: inherit;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
cursor: pointer;
|
||||
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
[tappable] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// Re-set default cursor for disabled elements.
|
||||
a[disabled],
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
// Remove inner padding and border in Firefox 4+.
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
padding: 0;
|
||||
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||
// 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||
// 2. Remove excess padding in IE 8/9/10.
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
padding: 0; // 2
|
||||
|
||||
box-sizing: border-box; // 1
|
||||
}
|
||||
|
||||
// Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||
// `font-size` values of the `input`, it causes the cursor style of the
|
||||
// decrement button to change from `default` to `text`.
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
// Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||
// Safari (but not Chrome) clips the cancel button when the search input has
|
||||
// padding (and `textfield` appearance).
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
|
||||
// Tables
|
||||
// ==========================================================================//
|
||||
|
||||
// Remove most spacing between table cells.
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
108
core/src/css/padding.scss
Normal file
108
core/src/css/padding.scss
Normal file
@ -0,0 +1,108 @@
|
||||
@import "../themes/ionic.globals";
|
||||
@import "../themes/ionic.mixins";
|
||||
|
||||
$padding: var(--ion-padding, 16px);
|
||||
$margin: var(--ion-margin, 16px);
|
||||
|
||||
[no-padding] {
|
||||
@include padding(0);
|
||||
|
||||
--padding-start: 0;
|
||||
--padding-end: 0;
|
||||
--padding-top: 0;
|
||||
--padding-bottom: 0;
|
||||
}
|
||||
|
||||
[padding] {
|
||||
@include padding($padding);
|
||||
|
||||
--padding-start: #{$padding};
|
||||
--padding-end: #{$padding};
|
||||
--padding-top: #{$padding};
|
||||
--padding-bottom: #{$padding};
|
||||
}
|
||||
|
||||
[padding-top] {
|
||||
@include padding($padding, null, null, null);
|
||||
|
||||
--padding-top: #{$padding};
|
||||
}
|
||||
|
||||
[padding-start] {
|
||||
@include padding-horizontal($padding, null);
|
||||
|
||||
--padding-start: #{$padding};
|
||||
}
|
||||
|
||||
[padding-end] {
|
||||
@include padding-horizontal(null, $padding);
|
||||
|
||||
--padding-end: #{$padding};
|
||||
}
|
||||
|
||||
[padding-bottom] {
|
||||
@include padding(null, null, $padding, null);
|
||||
|
||||
--padding-bottom: #{$padding};
|
||||
}
|
||||
|
||||
[padding-vertical] {
|
||||
@include padding($padding, null, $padding, null);
|
||||
|
||||
--padding-top: #{$padding};
|
||||
--padding-bottom: #{$padding};
|
||||
}
|
||||
|
||||
[padding-horizontal] {
|
||||
@include padding-horizontal($padding);
|
||||
|
||||
--padding-start: #{$padding};
|
||||
--padding-end: #{$padding};
|
||||
}
|
||||
|
||||
|
||||
// Content Margin
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-app [no-margin] {
|
||||
@include margin(0);
|
||||
}
|
||||
|
||||
[margin] {
|
||||
@include margin($margin);
|
||||
}
|
||||
|
||||
[margin-top] {
|
||||
@include margin($margin, null, null, null);
|
||||
}
|
||||
|
||||
[margin-left] {
|
||||
// scss-lint:disable PropertySpelling
|
||||
margin-left: $margin;
|
||||
}
|
||||
|
||||
[margin-start] {
|
||||
@include margin-horizontal($margin, null);
|
||||
}
|
||||
|
||||
[margin-right] {
|
||||
// scss-lint:disable PropertySpelling
|
||||
margin-right: $margin;
|
||||
}
|
||||
|
||||
[margin-end] {
|
||||
@include margin-horizontal(null, $margin);
|
||||
}
|
||||
|
||||
[margin-bottom] {
|
||||
@include margin(null, null, $margin, null);
|
||||
}
|
||||
|
||||
[margin-vertical] {
|
||||
@include margin($margin, null, $margin, null);
|
||||
}
|
||||
|
||||
[margin-horizontal] {
|
||||
@include margin-horizontal($margin);
|
||||
}
|
||||
|
49
core/src/css/structure.scss
Normal file
49
core/src/css/structure.scss
Normal file
@ -0,0 +1,49 @@
|
||||
@import "../themes/ionic.globals";
|
||||
@import "../themes/ionic.mixins";
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-touch-callout: none;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
@include font-smoothing();
|
||||
@include margin(0);
|
||||
@include padding(0);
|
||||
|
||||
position: fixed;
|
||||
overflow: hidden;
|
||||
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
text-rendering: optimizeLegibility;
|
||||
|
||||
-webkit-user-drag: none;
|
||||
|
||||
-ms-content-zooming: none;
|
||||
touch-action: manipulation;
|
||||
|
||||
word-wrap: break-word;
|
||||
|
||||
overscroll-behavior-y: contain;
|
||||
|
||||
text-size-adjust: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
46
core/src/css/text-alignment.scss
Normal file
46
core/src/css/text-alignment.scss
Normal file
@ -0,0 +1,46 @@
|
||||
@import "../themes/ionic.globals";
|
||||
@import "../themes/ionic.mixins";
|
||||
|
||||
|
||||
// Creates text alignment attributes based on screen size
|
||||
@each $breakpoint in map-keys($screen-breakpoints) {
|
||||
$infix: breakpoint-infix($breakpoint, $screen-breakpoints);
|
||||
|
||||
@include media-breakpoint-up($breakpoint, $screen-breakpoints) {
|
||||
// Provide `[text-{bp}]` attributes for aligning the text based
|
||||
// on the breakpoint
|
||||
[text#{$infix}-center] {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-justify] {
|
||||
text-align: justify !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-start] {
|
||||
text-align: start !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-end] {
|
||||
text-align: end !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-left] {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-right] {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-nowrap] {
|
||||
// scss-lint:disable ImportantRule
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-wrap] {
|
||||
// scss-lint:disable ImportantRule
|
||||
white-space: normal !important;
|
||||
}
|
||||
}
|
||||
}
|
27
core/src/css/text-transformation.scss
Normal file
27
core/src/css/text-transformation.scss
Normal file
@ -0,0 +1,27 @@
|
||||
@import "../themes/ionic.globals";
|
||||
@import "../themes/ionic.mixins";
|
||||
|
||||
|
||||
// Creates text transform attributes based on screen size
|
||||
@each $breakpoint in map-keys($screen-breakpoints) {
|
||||
$infix: breakpoint-infix($breakpoint, $screen-breakpoints);
|
||||
|
||||
@include media-breakpoint-up($breakpoint, $screen-breakpoints) {
|
||||
// Provide `[text-{bp}]` attributes for transforming the text based
|
||||
// on the breakpoint
|
||||
[text#{$infix}-uppercase] {
|
||||
// scss-lint:disable ImportantRule
|
||||
text-transform: uppercase !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-lowercase] {
|
||||
// scss-lint:disable ImportantRule
|
||||
text-transform: lowercase !important;
|
||||
}
|
||||
|
||||
[text#{$infix}-capitalize] {
|
||||
// scss-lint:disable ImportantRule
|
||||
text-transform: capitalize !important;
|
||||
}
|
||||
}
|
||||
}
|
110
core/src/css/typography.scss
Normal file
110
core/src/css/typography.scss
Normal file
@ -0,0 +1,110 @@
|
||||
@import "../themes/ionic.globals";
|
||||
@import "../themes/ionic.mixins";
|
||||
|
||||
// App Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Font weight of all headings
|
||||
$headings-font-weight: 500 !default;
|
||||
|
||||
/// @prop - Line height of all headings
|
||||
$headings-line-height: 1.2 !default;
|
||||
|
||||
$h-step: var(--ion-header-step, 2px) !default;
|
||||
|
||||
/// @prop - Font size of heading level 1
|
||||
$h1-font-size: var(--ion-header-size, 26px) !default;
|
||||
|
||||
/// @prop - Font size of heading level 2
|
||||
$h2-font-size: calc(#{$h1-font-size} - #{$h-step}) !default;
|
||||
|
||||
/// @prop - Font size of heading level 3
|
||||
$h3-font-size: calc(#{$h1-font-size} - #{$h-step} * 2) !default;
|
||||
|
||||
/// @prop - Font size of heading level 4
|
||||
$h4-font-size: calc(#{$h1-font-size} - #{$h-step} * 3) !default;
|
||||
|
||||
/// @prop - Font size of heading level 5
|
||||
$h5-font-size: calc(#{$h1-font-size} - #{$h-step} * 4) !default;
|
||||
|
||||
/// @prop - Font size of heading level 6
|
||||
$h6-font-size: calc(#{$h1-font-size} - #{$h-step} * 5) !default;
|
||||
|
||||
|
||||
:root[mode=ios] {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Roboto", sans-serif;
|
||||
|
||||
--ion-font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Roboto", sans-serif;
|
||||
}
|
||||
|
||||
:root[mode=md] {
|
||||
font-family: "Roboto", "Helvetica Neue", sans-serif;
|
||||
|
||||
--ion-font-family: "Roboto", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
color: ion-color(primary, base);
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
@include margin(16px, null, 10px, null);
|
||||
|
||||
font-weight: $headings-font-weight;
|
||||
line-height: $headings-line-height;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include margin(20px, null, null, null);
|
||||
|
||||
font-size: $h1-font-size;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include margin(18px, null, null, null);
|
||||
|
||||
font-size: $h2-font-size;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $h3-font-size;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: $h4-font-size;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $h5-font-size;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: $h6-font-size;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
}
|
Reference in New Issue
Block a user