UNPKG

19.8 kBSCSSView Raw
1@import "ionic.functions";
2
3// Appearance
4// --------------------------------------------------
5
6@mixin appearance($val) {
7 -moz-appearance: $val;
8 -ms-appearance: $val;
9 -webkit-appearance: $val;
10 appearance: $val;
11}
12
13// Input Placeholder
14// --------------------------------------------------
15
16@mixin placeholder($color: #999, $text-indent: 0) {
17 &::-moz-placeholder { // Firefox 19+
18 color: $color;
19 }
20
21 &:-ms-input-placeholder {
22 color: $color;
23 }
24
25 &::-webkit-input-placeholder {
26 // Safari placeholder margin issue
27 text-indent: $text-indent;
28 color: $color;
29 }
30}
31
32// Check that the given map values are in ascending order
33// ---------------------------------------------------------------------------------
34
35@mixin assert-ascending($map, $map-name) {
36 $prev-key: null;
37 $prev-num: null;
38 @each $key, $num in $map {
39 @if $prev-num == null {
40 // Do nothing
41 } @else if not comparable($prev-num, $num) {
42 @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
43 } @else if $prev-num >= $num {
44 @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
45 }
46 $prev-key: $key;
47 $prev-num: $num;
48 }
49}
50
51// Check that the first value in the given map starts at 0
52// ---------------------------------------------------------------------------------
53
54@mixin assert-starts-at-zero($map, $map-name) {
55 $values: map-values($map);
56 $first-value: nth($values, 1);
57 @if $first-value != 0 {
58 @warn "First value in `#{$map-name}` must start at 0, but starts at #{$first-value}.";
59 }
60}
61
62// Breakpoint Mixins
63// ---------------------------------------------------------------------------------
64
65// Breakpoint viewport sizes and media queries.
66//
67// Breakpoints are defined as a map of (name: minimum width), order from small to large:
68//
69// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
70//
71// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
72
73// ---------------------------------------------------------------------------------
74
75// Minimum breakpoint width. Null for the smallest (first) breakpoint.
76//
77// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
78// 576px
79@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
80 $min: map-get($breakpoints, $name);
81 @return if($min != 0, $min, null);
82}
83
84// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
85// Useful for making responsive utilities.
86//
87// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
88// "" (Returns a blank string)
89// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
90// "-sm"
91@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
92 @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
93}
94
95// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
96// Makes the @content apply to the given breakpoint and wider.
97@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
98 $min: breakpoint-min($name, $breakpoints);
99 @if $min {
100 @media (min-width: $min) {
101 @content;
102 }
103 } @else {
104 @content;
105 }
106}
107
108// Name of the next breakpoint, or null for the last breakpoint.
109//
110// >> breakpoint-next(sm)
111// md
112// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
113// md
114// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
115// md
116@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
117 $n: index($breakpoint-names, $name);
118 @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
119}
120
121// Maximum breakpoint width. Null for the largest (last) breakpoint.
122// The maximum value is calculated as the minimum of the next one less 0.1.
123//
124// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
125// 767px
126@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
127 $next: breakpoint-next($name, $breakpoints);
128 @return if($next, breakpoint-min($next, $breakpoints) - 1px, null);
129}
130
131// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
132// Makes the @content apply to the given breakpoint and narrower.
133@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
134 $max: breakpoint-max($name, $breakpoints);
135 @if $max {
136 @media (max-width: $max) {
137 @content;
138 }
139 } @else {
140 @content;
141 }
142}
143
144@mixin multi-dir() {
145 @if $app-direction == multi {
146 $root: #{&};
147 @at-root [dir="ltr"], [dir="rtl"] {
148 #{$root} {
149 @content;
150 }
151 }
152 } @else {
153 @content;
154 }
155}
156
157@mixin rtl() {
158 @if $app-direction == multi {
159 $root: #{&};
160 @at-root [dir="rtl"] {
161 #{$root} {
162 @content;
163 }
164 }
165 } @else if $app-direction == rtl {
166 @content;
167 }
168}
169
170@mixin ltr() {
171 @if $app-direction == multi {
172 $root: #{&};
173 @at-root [dir="ltr"] {
174 #{$root} {
175 @content;
176 }
177 }
178 } @else if $app-direction == ltr {
179 @content;
180 }
181}
182
183// If deprecated variable exists, use it, otherwise, use alternative
184// @param {string} $property - property to default
185// @param {string} $variable - the deprecated variable
186// ----------------------------------------------------------
187@mixin deprecated-variable($property, $variable) {
188 @if $variable == null {
189 @content;
190 } @else {
191 // TODO find variable name
192 @warn "you are using a deprecated variable";
193 #{$property}: $variable;
194 }
195}
196
197// SVG Background Image Mixin
198// @param {string} $svg
199// ----------------------------------------------------------
200@mixin svg-background-image($svg, $flip-rtl: false) {
201 $url: url-encode($svg);
202 $viewBox: str-split(str-extract($svg, "viewBox='", "'"), " ");
203
204 @if $flip-rtl != true or $viewBox == null {
205 @include multi-dir() {
206 background-image: url("data:image/svg+xml;charset=utf-8,#{$url}");
207 }
208 } @else {
209 $transform: "transform='translate(#{nth($viewBox, 3)}, 0) scale(-1, 1)'";
210 $flipped-url: $svg;
211 $flipped-url: str-replace($flipped-url, "<path", "<path #{$transform}");
212 $flipped-url: str-replace($flipped-url, "<line", "<line #{$transform}");
213 $flipped-url: str-replace($flipped-url, "<polygon", "<polygon #{$transform}");
214 $flipped-url: url-encode($flipped-url);
215
216 @include ltr () {
217 background-image: url("data:image/svg+xml;charset=utf-8,#{$url}");
218 }
219 @include rtl() {
220 background-image: url("data:image/svg+xml;charset=utf-8,#{$flipped-url}");
221 }
222 }
223}
224
225// Add property horizontal
226// @param {string} $start
227// @param {string} $end
228// ----------------------------------------------------------
229@mixin property-horizontal($prop, $start, $end: $start) {
230 @if $start == $end {
231 @include multi-dir() {
232 #{$prop}-left: $start;
233 #{$prop}-right: $end;
234 }
235 } @else {
236 @include ltr() {
237 #{$prop}-left: $start;
238 #{$prop}-right: $end;
239 }
240 @include rtl() {
241 #{$prop}-left: $end;
242 #{$prop}-right: $start;
243 }
244 }
245}
246
247// Add property for all directions
248// @param {string} $prop
249// @param {string} $top
250// @param {string} $end
251// @param {string} $bottom
252// @param {string} $start
253// @param {boolean} $content include content or use default
254// ----------------------------------------------------------
255@mixin property($prop, $top, $end: $top, $bottom: $top, $start: $end) {
256 @if $top == $end and $top == $bottom and $top == $start {
257 @include multi-dir() {
258 #{$prop}: $top;
259 }
260 } @else if $top == $bottom and $end == $start and $top != null and $end != null {
261 @include multi-dir() {
262 #{$prop}: $top $end;
263 }
264 } @else if $end == $start and $top != null and $end != null and $bottom != null {
265 @include multi-dir() {
266 #{$prop}: $top $end $bottom;
267 }
268 } @else if $top != null and $end != null and $bottom != null and $start != null {
269 @include ltr() {
270 #{$prop}: $top $end $bottom $start;
271 }
272 @include rtl() {
273 #{$prop}: $top $start $bottom $end;
274 }
275 } @else {
276 @include property-horizontal($prop, $start, $end);
277 @include multi-dir() {
278 #{$prop}-top: $top;
279 #{$prop}-bottom: $bottom;
280 }
281 }
282}
283
284// Add padding horizontal
285// @param {string} $start
286// @param {string} $end
287// ----------------------------------------------------------
288@mixin padding-horizontal($start, $end: $start) {
289 @include property-horizontal(padding, $start, $end);
290}
291
292// Add padding for all directions
293// @param {string} $top
294// @param {string} $end
295// @param {string} $bottom
296// @param {string} $start
297// ----------------------------------------------------------
298@mixin padding($top, $end: $top, $bottom: $top, $start: $end) {
299 @include property(padding, $top, $end, $bottom, $start);
300}
301
302// Add margin horizontal
303// @param {string} $start
304// @param {string} $end
305// ----------------------------------------------------------
306@mixin margin-horizontal($start, $end: $start) {
307 @include property-horizontal(margin, $start, $end);
308}
309
310// Add margin for all directions
311// @param {string} $top
312// @param {string} $end
313// @param {string} $bottom
314// @param {string} $start
315// ----------------------------------------------------------
316@mixin margin($top, $end: $top, $bottom: $top, $start: $end) {
317 @include property(margin, $top, $end, $bottom, $start);
318}
319
320// Add position horizontal
321// @param {string} $start - amount to position start
322// @param {string} $end - amount to left: 0; end
323// ----------------------------------------------------------
324@mixin position-horizontal($start: null, $end: null) {
325 @if $start == $end {
326 @include multi-dir() {
327 left: $start;
328 right: $end;
329 }
330 } @else {
331 @include ltr() {
332 left: $start;
333 right: $end;
334 }
335 @include rtl() {
336 left: $end;
337 right: $start;
338 }
339 }
340}
341
342// Add position for all directions
343// @param {string} $top
344// @param {string} $end
345// @param {string} $bottom
346// @param {string} $start
347// ----------------------------------------------------------
348@mixin position($top: null, $end: null, $bottom: null, $start: null) {
349 @include position-horizontal($start, $end);
350 top: $top;
351 bottom: $bottom;
352}
353
354// Add border radius for all directions
355// @param {string} $top-start
356// @param {string} $top-end
357// @param {string} $bottom-end
358// @param {string} $bottom-start
359// ----------------------------------------------------------
360@mixin border-radius($top-start, $top-end: $top-start, $bottom-end: $top-start, $bottom-start: $top-end) {
361 @if $top-start == $top-end and $top-start == $bottom-end and $top-start == $bottom-start {
362 @include multi-dir() {
363 border-radius: $top-start;
364 }
365 } @else {
366 @include ltr() {
367 border-top-left-radius: $top-start;
368 border-top-right-radius: $top-end;
369 border-bottom-right-radius: $bottom-end;
370 border-bottom-left-radius: $bottom-start;
371 }
372
373 @include rtl() {
374 border-top-left-radius: $top-end;
375 border-top-right-radius: $top-start;
376 border-bottom-right-radius: $bottom-start;
377 border-bottom-left-radius: $bottom-end;
378 }
379 }
380}
381
382// Sets correct text align with support for old browsers
383// @param {string} $direction - text direction
384// @param {string} $decorator - !important
385// ----------------------------------------------------------
386@mixin text-align($direction, $decorator: null) {
387 @if $direction == start {
388 text-align: left;
389 text-align: start $decorator;
390 } @else if $direction == end {
391 text-align: right;
392 text-align: end $decorator;
393 } @else {
394 text-align: $direction $decorator;
395 }
396}
397
398// Add direction for all directions
399// @param {string} $dir - Direction on LTR
400@mixin direction($dir) {
401 $other-dir: null;
402
403 @if $dir == ltr {
404 $other-dir: rtl;
405 } @else {
406 $other-dir: ltr;
407 }
408
409 @include ltr() {
410 direction: $dir;
411 }
412 @include rtl() {
413 direction: $other-dir;
414 }
415}
416
417// Add float for all directions
418// @param {string} $side
419// @param {string} $decorator - !important
420@mixin float($side, $decorator: null) {
421 @if $side == start {
422 @include ltr() {
423 float: left $decorator;
424 }
425 @include rtl() {
426 float: right $decorator;
427 }
428 } @else if $side == end {
429 @include ltr() {
430 float: right $decorator;
431 }
432 @include rtl() {
433 float: left $decorator;
434 }
435 } @else {
436 @include multi-dir() {
437 float: $side $decorator;
438 }
439 }
440}
441
442@mixin background-position($horizontal, $horizontal-amount: null, $vertical: null, $vertical-amount: null) {
443 @if $horizontal == start or $horizontal == end {
444 $horizontal-ltr: null;
445 $horizontal-rtl: null;
446 @if $horizontal == start {
447 $horizontal-ltr: left;
448 $horizontal-rtl: right;
449 } @else {
450 $horizontal-ltr: right;
451 $horizontal-rtl: left;
452 }
453
454 @include ltr() {
455 background-position: $horizontal-ltr $horizontal-amount $vertical $vertical-amount;
456 }
457 @include rtl() {
458 background-position: $horizontal-rtl $horizontal-amount $vertical $vertical-amount;
459 }
460 } @else {
461 @include multi-dir() {
462 background-position: $horizontal $horizontal-amount $vertical $vertical-amount;
463 }
464 }
465}
466
467@mixin transform-origin($x-axis, $y-axis: null) {
468 @if $x-axis == start {
469 @include ltr() {
470 transform-origin: left $y-axis;
471 }
472 @include rtl() {
473 transform-origin: right $y-axis;
474 }
475 } @else if $x-axis == end {
476 @include ltr() {
477 transform-origin: right $y-axis;
478 }
479 @include rtl() {
480 transform-origin: left $y-axis;
481 }
482 } @else if $x-axis == left or $x-axis == right {
483 @include multi-dir() {
484 transform-origin: $x-axis $y-axis;
485 }
486 } @else {
487 @include ltr() {
488 transform-origin: $x-axis $y-axis;
489 }
490 @include rtl() {
491 transform-origin: calc(100% - #{$x-axis}) $y-axis;
492 }
493 }
494}
495
496// Add transform for all directions
497// @param {string} $transforms - comma separated list of transforms
498@mixin transform($transforms...) {
499 $extra: null;
500
501 $x: null;
502 $ltr-translate: null;
503 $rtl-translate: null;
504
505 @each $transform in $transforms {
506 @if (str-index($transform, translate3d)) {
507 $transform: str-replace($transform, 'translate3d(');
508 $transform: str-replace($transform, ')');
509
510 $coordinates: str-split($transform, ',');
511
512 $x: nth($coordinates, 1);
513 $y: nth($coordinates, 2);
514 $z: nth($coordinates, 3);
515
516 $ltr-translate: translate3d($x, $y, $z);
517 $rtl-translate: translate3d(calc(-1 * #{$x}), $y, $z);
518 } @else {
519 @if $extra == null {
520 $extra: $transform;
521 } @else {
522 $extra: $extra $transform;
523 }
524 }
525 }
526
527 @if $x == '0' or $x == null {
528 @include multi-dir() {
529 transform: $ltr-translate $extra;
530 }
531 } @else {
532 @include ltr() {
533 transform: $ltr-translate $extra;
534 }
535
536 @include rtl() {
537 transform: $rtl-translate $extra;
538 }
539 }
540}
541
542
543// Add safe-area transform for all directions
544// Used by item-reorder
545// @param {string} $transforms - comma separated list of transforms
546@mixin reorder-safe-translate($transforms...) {
547 $extra: null;
548
549 $x: null;
550 $ltr-translate: null;
551 $rtl-translate: null;
552
553 @each $transform in $transforms {
554 @if (str-index($transform, translate3d)) {
555 $transform: str-replace($transform, 'translate3d(');
556 $transform: str-replace($transform, ')');
557
558 $coordinates: str-split($transform, ',');
559
560 $x: nth($coordinates, 1);
561 $y: nth($coordinates, 2);
562 $z: nth($coordinates, 3);
563
564 $ltr-translate: translate3d(calc(-1 * constant(safe-area-inset-right)), 0, 0);
565 $rtl-translate: translate3d(constant(safe-area-inset-left), $y, $z);
566
567 $ltr-env-translate: translate3d(calc(-1 * env(safe-area-inset-right)), 0, 0);
568 $rtl-env-translate: translate3d(env(safe-area-inset-left), $y, $z);
569
570 } @else {
571 @if $extra == null {
572 $extra: $transform;
573 } @else {
574 $extra: $extra $transform;
575 }
576 }
577 }
578
579 @if $x == '0' or $x == null {
580 @include multi-dir() {
581 transform: $ltr-translate $extra;
582 transform: $ltr-env-translate $extra;
583 }
584 } @else {
585 @include ltr() {
586 transform: $ltr-translate $extra;
587 transform: $ltr-env-translate $extra;
588 }
589
590 @include rtl() {
591 transform: $rtl-translate $extra;
592 transform: $rtl-env-translate $extra;
593 }
594 }
595}
596
597// Add safe-area-padding for all directions
598// @param {string} $top
599// @param {string} $end
600// @param {string} $bottom
601// @param {string} $start
602// ----------------------------------------------------------
603@mixin safe-area-padding($top, $end: $top, $bottom: $top, $start: $end) {
604 $safe-area-start: null;
605 $safe-area-end: null;
606 $safe-area-start-env: null;
607 $safe-area-end-env: null;
608
609 @if ($start) {
610 $safe-area-start: calc(constant(safe-area-inset-left) + #{$start});
611 $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start});
612 }
613 @if ($end) {
614 $safe-area-end-env: calc(constant(safe-area-inset-right) + #{$end});
615 $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end});
616 }
617
618 @include padding($top, $end, $bottom, $start);
619
620 @media screen and (orientation: landscape) {
621 @include padding($top, $safe-area-end, $bottom, $safe-area-start);
622 @include padding($top, $safe-area-end-env, $bottom, $safe-area-start-env);
623 }
624}
625
626
627// Add safe area padding horizontal
628// @param {string} $start
629// @param {string} $end
630// ----------------------------------------------------------
631@mixin safe-area-padding-horizontal($start, $end: $start) {
632 $safe-area-end: null;
633 $safe-area-start: null;
634 $safe-area-start-env: null;
635 $safe-area-end-env: null;
636
637 @if ($end) {
638 $safe-area-end: calc(constant(safe-area-inset-right) + #{$end});
639 $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end});
640 }
641 @if ($start) {
642 $safe-area-start: calc(constant(safe-area-inset-left) + #{$start});
643 $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start});
644 }
645
646 @include padding-horizontal($start, $end);
647
648 @media screen and (orientation: landscape) {
649 @include padding-horizontal($safe-area-start, $safe-area-end);
650 @include padding-horizontal($safe-area-start-env, $safe-area-end-env);
651 }
652}
653
654
655// Add safe position horizontal
656// @param {string} $start - amount to position start
657// @param {string} $end - amount to left: 0; end
658// ----------------------------------------------------------
659@mixin safe-position-horizontal($start: null, $end: null){
660 $safe-area-start: null;
661 $safe-area-end: null;
662 $safe-area-start-env: null;
663 $safe-area-end-env: null;
664 @if ($start) {
665 $safe-area-start: calc(constant(safe-area-inset-left) + #{$start});
666 $safe-area-start-env: calc(env(safe-area-inset-left) + #{$start});
667 }
668 @if ($end) {
669 $safe-area-end: calc(constant(safe-area-inset-right) + #{$end});
670 $safe-area-end-env: calc(env(safe-area-inset-right) + #{$end});
671 }
672
673 @if $safe-area-start == $safe-area-end {
674 @include multi-dir() {
675 left: $safe-area-start;
676 right: $safe-area-end;
677 }
678 @include multi-dir() {
679 left: $safe-area-start-env;
680 right: $safe-area-end-env;
681 }
682 } @else {
683 @include ltr() {
684 left: $safe-area-start;
685 right: $safe-area-end;
686 }
687 @include ltr() {
688 left: $safe-area-start-env;
689 right: $safe-area-end-env;
690 }
691 @include rtl() {
692 left: $safe-area-end;
693 right: $safe-area-start;
694 }
695 @include rtl() {
696 left: $safe-area-end-env;
697 right: $safe-area-start-env;
698 }
699 }
700}
701