_mixins.scss 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. @use 'sass:math';
  2. @use 'sass:map';
  3. @use 'sass:color';
  4. @use 'variables' as v;
  5. @mixin respond-to-min($breakpoint) {
  6. $value: map.get(v.$breakpoints, $breakpoint);
  7. @if $value != null {
  8. @media (min-width: $value) {
  9. @content;
  10. }
  11. } @else {
  12. @error "No value found for breakpoint '#{$breakpoint}'";
  13. }
  14. }
  15. @mixin respond-to-max($breakpoint) {
  16. $value: map.get(v.$breakpoints, $breakpoint);
  17. @if $value != null {
  18. @media (max-width: $value) {
  19. @content;
  20. }
  21. } @else {
  22. @error "No value found for breakpoint '#{$breakpoint}'";
  23. }
  24. }
  25. @mixin flex($direction: row, $justify: flex-start, $align: stretch, $wrap: nowrap) {
  26. display: -webkit-box;
  27. display: -webkit-flex;
  28. display: -moz-box;
  29. display: -ms-flexbox;
  30. display: flex;
  31. -webkit-box-orient: if($direction == column or $direction == column-reverse, vertical, horizontal);
  32. -webkit-box-direction: if($direction == row-reverse or $direction == column-reverse, reverse, normal);
  33. -webkit-flex-direction: $direction;
  34. -moz-flex-direction: $direction;
  35. -ms-flex-direction: $direction;
  36. flex-direction: $direction;
  37. @if $justify == flex-start {
  38. -webkit-box-pack: start;
  39. } @else if $justify == flex-end {
  40. -webkit-box-pack: end;
  41. } @else if $justify == center {
  42. -webkit-box-pack: center;
  43. } @else if $justify == space-between {
  44. -webkit-box-pack: justify;
  45. }
  46. -webkit-justify-content: $justify;
  47. -moz-justify-content: $justify;
  48. -ms-justify-content: $justify;
  49. justify-content: $justify;
  50. @if $align == flex-start {
  51. -webkit-box-align: start;
  52. } @else if $align == flex-end {
  53. -webkit-box-align: end;
  54. } @else {
  55. -webkit-box-align: $align;
  56. }
  57. -webkit-align-items: $align;
  58. -moz-align-items: $align;
  59. -ms-align-items: $align;
  60. align-items: $align;
  61. -webkit-flex-wrap: $wrap;
  62. -moz-flex-wrap: $wrap;
  63. -ms-flex-wrap: $wrap;
  64. flex-wrap: $wrap;
  65. }
  66. @mixin inline-flex($direction: row, $justify: flex-start, $align: stretch, $wrap: nowrap) {
  67. display: -webkit-inline-box;
  68. display: -webkit-inline-flex;
  69. display: -moz-inline-box;
  70. display: -ms-inline-flexbox;
  71. display: inline-flex;
  72. -webkit-box-orient: if($direction == column or $direction == column-reverse, vertical, horizontal);
  73. -webkit-box-direction: if($direction == row-reverse or $direction == column-reverse, reverse, normal);
  74. -webkit-flex-direction: $direction;
  75. -moz-flex-direction: $direction;
  76. -ms-flex-direction: $direction;
  77. flex-direction: $direction;
  78. @if $justify == flex-start {
  79. -webkit-box-pack: start;
  80. } @else if $justify == flex-end {
  81. -webkit-box-pack: end;
  82. } @else if $justify == center {
  83. -webkit-box-pack: center;
  84. } @else if $justify == space-between {
  85. -webkit-box-pack: justify;
  86. }
  87. -webkit-justify-content: $justify;
  88. -moz-justify-content: $justify;
  89. -ms-justify-content: $justify;
  90. justify-content: $justify;
  91. @if $align == flex-start {
  92. -webkit-box-align: start;
  93. } @else if $align == flex-end {
  94. -webkit-box-align: end;
  95. } @else {
  96. -webkit-box-align: $align;
  97. }
  98. -webkit-align-items: $align;
  99. -moz-align-items: $align;
  100. -ms-align-items: $align;
  101. align-items: $align;
  102. -webkit-flex-wrap: $wrap;
  103. -moz-flex-wrap: $wrap;
  104. -ms-flex-wrap: $wrap;
  105. flex-wrap: $wrap;
  106. }
  107. @mixin grid($columns: 1, $gap: 1rem) {
  108. display: -ms-grid;
  109. display: grid;
  110. -ms-grid-columns: repeat($columns, 1fr);
  111. grid-template-columns: repeat($columns, 1fr);
  112. gap: $gap;
  113. @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
  114. display: block;
  115. > * {
  116. display: inline-block;
  117. width: calc(#{math.div(100%, $columns)} - #{$gap});
  118. margin-right: $gap;
  119. vertical-align: top;
  120. &:nth-child(#{$columns}n) {
  121. margin-right: 0;
  122. }
  123. }
  124. }
  125. }
  126. @mixin grid-custom($columns, $gap: 1rem) {
  127. display: grid;
  128. grid-template-columns: $columns;
  129. gap: $gap;
  130. }
  131. @mixin transform($transforms) {
  132. -webkit-transform: $transforms;
  133. -moz-transform: $transforms;
  134. -ms-transform: $transforms;
  135. -o-transform: $transforms;
  136. transform: $transforms;
  137. }
  138. @mixin transition($transition) {
  139. -webkit-transition: $transition;
  140. -moz-transition: $transition;
  141. -ms-transition: $transition;
  142. -o-transition: $transition;
  143. transition: $transition;
  144. }
  145. @mixin flex-direction($direction) {
  146. -webkit-box-orient: if($direction == column or $direction == column-reverse, vertical, horizontal);
  147. -webkit-box-direction: if($direction == row-reverse or $direction == column-reverse, reverse, normal);
  148. -webkit-flex-direction: $direction;
  149. -moz-flex-direction: $direction;
  150. -ms-flex-direction: $direction;
  151. flex-direction: $direction;
  152. }
  153. @mixin flex-wrap($wrap) {
  154. -webkit-flex-wrap: $wrap;
  155. -moz-flex-wrap: $wrap;
  156. -ms-flex-wrap: $wrap;
  157. flex-wrap: $wrap;
  158. }
  159. @mixin justify-content($justify) {
  160. @if $justify == flex-start {
  161. -webkit-box-pack: start;
  162. } @else if $justify == flex-end {
  163. -webkit-box-pack: end;
  164. } @else if $justify == center {
  165. -webkit-box-pack: center;
  166. } @else if $justify == space-between {
  167. -webkit-box-pack: justify;
  168. }
  169. -webkit-justify-content: $justify;
  170. -moz-justify-content: $justify;
  171. -ms-justify-content: $justify;
  172. justify-content: $justify;
  173. }
  174. @mixin align-items($align) {
  175. @if $align == flex-start {
  176. -webkit-box-align: start;
  177. } @else if $align == flex-end {
  178. -webkit-box-align: end;
  179. } @else {
  180. -webkit-box-align: $align;
  181. }
  182. -webkit-align-items: $align;
  183. -moz-align-items: $align;
  184. -ms-align-items: $align;
  185. align-items: $align;
  186. }
  187. @mixin flex-property($flex) {
  188. @if $flex == none {
  189. -webkit-box-flex: 0;
  190. -webkit-flex: none;
  191. -moz-flex: none;
  192. -ms-flex: none;
  193. flex: none;
  194. } @else {
  195. -webkit-box-flex: 1;
  196. -webkit-flex: $flex;
  197. -moz-flex: $flex;
  198. -ms-flex: $flex;
  199. flex: $flex;
  200. }
  201. }
  202. @mixin flex-basis($basis) {
  203. -webkit-flex-basis: $basis;
  204. -moz-flex-basis: $basis;
  205. -ms-flex-basis: $basis;
  206. flex-basis: $basis;
  207. }
  208. @mixin flex-grow($grow) {
  209. @if $grow > 0 {
  210. -webkit-box-flex: $grow;
  211. }
  212. -webkit-flex-grow: $grow;
  213. -moz-flex-grow: $grow;
  214. -ms-flex-grow: $grow;
  215. flex-grow: $grow;
  216. }
  217. @mixin flex-shrink($shrink) {
  218. -webkit-flex-shrink: $shrink;
  219. -moz-flex-shrink: $shrink;
  220. -ms-flex-shrink: $shrink;
  221. flex-shrink: $shrink;
  222. }
  223. @mixin border-radius($radius) {
  224. -webkit-border-radius: $radius;
  225. -moz-border-radius: $radius;
  226. border-radius: $radius;
  227. }
  228. @mixin box-shadow($shadow) {
  229. -webkit-box-shadow: $shadow;
  230. -moz-box-shadow: $shadow;
  231. box-shadow: $shadow;
  232. }
  233. @mixin svg-style($color: currentColor, $size: 24px) {
  234. svg {
  235. width: $size;
  236. height: $size;
  237. fill: $color;
  238. color: $color;
  239. }
  240. }
  241. @mixin svg-icon($color: currentColor, $size: 24px, $hover-color: null) {
  242. svg {
  243. width: $size;
  244. height: $size;
  245. fill: $color;
  246. color: $color;
  247. @include transition(v.$transition-base);
  248. @if $hover-color {
  249. &:hover {
  250. fill: $hover-color;
  251. color: $hover-color;
  252. }
  253. } @else {
  254. &:hover {
  255. fill: color.scale($color, $lightness: -15%);
  256. color: color.scale($color, $lightness: -15%);
  257. }
  258. }
  259. }
  260. }
  261. @mixin svg-button-icon($color: currentColor, $size: 20px) {
  262. svg {
  263. width: $size;
  264. height: $size;
  265. fill: $color;
  266. color: $color;
  267. margin-right: 0.5rem;
  268. &:last-child {
  269. margin-right: 0;
  270. margin-left: 0.5rem;
  271. }
  272. &:only-child {
  273. margin: 0;
  274. }
  275. }
  276. }
  277. @mixin svg-icon-box($color: v.$primary, $size: 48px, $bg-color: null) {
  278. @if $bg-color {
  279. background-color: $bg-color;
  280. padding: 1rem;
  281. @include border-radius(v.$border-radius);
  282. }
  283. svg {
  284. width: $size;
  285. height: $size;
  286. fill: $color;
  287. color: $color;
  288. display: block;
  289. margin: 0 auto;
  290. }
  291. }
  292. @mixin svg-responsive($mobile: 20px, $tablet: 24px, $desktop: 28px) {
  293. svg {
  294. width: $mobile;
  295. height: $mobile;
  296. @include respond-to-min('md') {
  297. width: $tablet;
  298. height: $tablet;
  299. }
  300. @include respond-to-min('lg') {
  301. width: $desktop;
  302. height: $desktop;
  303. }
  304. }
  305. }
  306. @mixin svg-stroke($color: currentColor, $width: 2px, $size: 24px) {
  307. svg {
  308. width: $size;
  309. height: $size;
  310. fill: none;
  311. stroke: $color;
  312. stroke-width: $width;
  313. stroke-linecap: round;
  314. stroke-linejoin: round;
  315. }
  316. }
  317. @mixin svg-states($default: currentColor, $disabled: v.$gray, $active: v.$primary) {
  318. svg {
  319. fill: $default;
  320. color: $default;
  321. @include transition(v.$transition-base);
  322. }
  323. &:disabled,
  324. &.disabled {
  325. svg {
  326. fill: $disabled;
  327. color: $disabled;
  328. opacity: 0.5;
  329. }
  330. }
  331. &.active,
  332. &:active {
  333. svg {
  334. fill: $active;
  335. color: $active;
  336. }
  337. }
  338. }
  339. @mixin button-base {
  340. display: inline-flex;
  341. cursor: pointer;
  342. text-decoration: none;
  343. outline: none;
  344. -webkit-appearance: none;
  345. -moz-appearance: none;
  346. appearance: none;
  347. padding: 0.375rem 1.5rem;
  348. font-size: map.get(v.$font-sizes, 'sm');
  349. font-weight: map.get(v.$font-weights, 'medium');
  350. line-height: 1.3;
  351. @include flex(row, center, center);
  352. @include border-radius(v.$border-radius);
  353. @include transition(v.$transition-base);
  354. @include respond-to-min('md') {
  355. padding: 0.5rem 2rem;
  356. font-size: map.get(v.$font-sizes, 'base');
  357. line-height: 1.4;
  358. }
  359. @include respond-to-min('lg') {
  360. padding: 0.625rem 2.5rem;
  361. font-size: map.get(v.$font-sizes, 'base');
  362. line-height: 1.4;
  363. }
  364. @include respond-to-min('xl') {
  365. padding: 0.75rem 3rem;
  366. font-size: map.get(v.$font-sizes, 'base');
  367. line-height: 1.5;
  368. }
  369. }
  370. @mixin button-primary {
  371. @include button-base;
  372. background-color: v.$primary;
  373. color: v.$white;
  374. &:hover {
  375. background-color: color.scale(v.$primary, $lightness: -10%);
  376. @include box-shadow(v.$box-shadow);
  377. }
  378. }
  379. @mixin button-secondary {
  380. @include button-base;
  381. background-color: transparent;
  382. color: v.$primary;
  383. border: 1px solid v.$primary;
  384. &:hover {
  385. background-color: rgba(v.$primary, 0.1);
  386. }
  387. }
  388. @mixin card {
  389. background-color: v.$white;
  390. @include border-radius(v.$border-radius);
  391. @include box-shadow(v.$box-shadow);
  392. padding: map.get(v.$spacers, 4);
  393. @include transition(v.$transition-base);
  394. &:hover {
  395. @include box-shadow(v.$box-shadow-lg);
  396. @include transform(translateY(-5px));
  397. }
  398. }
  399. @mixin icon-box {
  400. @include svg-icon-box(v.$primary, 48px);
  401. margin-bottom: map.get(v.$spacers, 3);
  402. }
  403. @mixin center-absolute {
  404. position: absolute;
  405. top: 50%;
  406. left: 50%;
  407. @include transform(translate(-50%, -50%));
  408. }
  409. @mixin truncate {
  410. overflow: hidden;
  411. text-overflow: ellipsis;
  412. white-space: nowrap;
  413. }
  414. @mixin grid-display() {
  415. display: -ms-grid;
  416. display: grid;
  417. }
  418. @mixin grid-auto-fit($min-width: 300px) {
  419. @include grid-display();
  420. -ms-grid-columns: repeat(auto-fit, minmax($min-width, 1fr));
  421. grid-template-columns: repeat(auto-fit, minmax($min-width, 1fr));
  422. }
  423. @mixin grid-auto-fill($min-width: 300px) {
  424. @include grid-display();
  425. -ms-grid-columns: repeat(auto-fill, minmax($min-width, 1fr));
  426. grid-template-columns: repeat(auto-fill, minmax($min-width, 1fr));
  427. }
  428. @mixin grid-justify-items($justify) {
  429. @if $justify == start {
  430. -ms-grid-column-align: start;
  431. } @else if $justify == end {
  432. -ms-grid-column-align: end;
  433. } @else if $justify == center {
  434. -ms-grid-column-align: center;
  435. } @else if $justify == stretch {
  436. -ms-grid-column-align: stretch;
  437. }
  438. justify-items: $justify;
  439. }
  440. @mixin grid-align-items($align) {
  441. @if $align == start {
  442. -ms-grid-row-align: start;
  443. } @else if $align == end {
  444. -ms-grid-row-align: end;
  445. } @else if $align == center {
  446. -ms-grid-row-align: center;
  447. } @else if $align == stretch {
  448. -ms-grid-row-align: stretch;
  449. }
  450. align-items: $align;
  451. }
  452. @mixin place-items($align) {
  453. @if $align == start {
  454. -ms-grid-column-align: start;
  455. -ms-grid-row-align: start;
  456. } @else if $align == end {
  457. -ms-grid-column-align: end;
  458. -ms-grid-row-align: end;
  459. } @else if $align == center {
  460. -ms-grid-column-align: center;
  461. -ms-grid-row-align: center;
  462. } @else if $align == stretch {
  463. -ms-grid-column-align: stretch;
  464. -ms-grid-row-align: stretch;
  465. }
  466. place-items: $align;
  467. }
  468. @mixin background($image, $color, $size, $repeat, $position, $attachment) {
  469. background-image: $image;
  470. background-color: $color;
  471. background-size: $size;
  472. background-repeat: $repeat;
  473. background-position: $position;
  474. background-attachment: $attachment;
  475. }