# mixin
- 和繼承功能一樣,屬於被繼承的樣式
- 被繼承幾次,就會產生幾份
- 大部分都把變數和 function,在其中一起實作
# 基本用法
@mixin clearfix {
&::before,
&::after {
content: '';
display: table;
}
&::after {
clear: both;
}
}
@mixin hide-text {
text-indent: 110%;
white-space: nowrap;
overflow: hidden;
}
h1 {
@include hide-text;
}
.box {
@include clearfix;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
產生結果
h1 {
text-indent: 110%;
white-space: nowrap;
overflow: hidden;
}
.box::before,
.box::after {
content: '';
display: table;
}
.box::after {
clear: both;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 加入變數
變數可以加入預設值。
@mixin circle($size: 16px, $bgColor: #000) {
border-radius: 50%;
width: $size;
height: $size;
font-size: $size / 3;
background-color: $bgColor;
}
.red-circle {
@include circle(30px, #f00);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
產生結果
.red-circle {
border-radius: 50%;
width: 30px;
height: 30px;
font-size: 10px;
background-color: #f00;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# @content
@content
的用途主要是拿來傳遞內容到 Mixin
裡面去的,類似於 vue 的 slot
作法
@mixin bg($text-color, $bg-color) {
background: $bg-color;
color: $text-color;
@content;
}
.bg {
@include bg(#fff, #000) {
border: 1px solid;
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
產生結果
.bg {
background: #000;
color: #fff;
border: 1px solid;
}
1
2
3
4
5
2
3
4
5
# 選擇器的繼承與覆蓋
常用於針對特定瀏覽器去做兼容性的語法
@mixin ie8 {
.ie8 & {
@content;
}
}
.box {
width: 50px;
@include ie8 {
width: 150px;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
產生結果
.box {
width: 50px;
}
.ie8 .box {
width: 150px;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 狀態管理
可以針對如 a
標籤的狀態管理
@mixin link {
//連結樣式
&:link,
&:visited {
@content;
}
}
@mixin link-hover {
//被點擊後的樣式
&:hover,
&:focus,
&:active,
&.active {
@content;
}
}
.box {
height: 50px;
@include link {
color: #fff;
}
@include link-hover {
color: #000;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
產生結果
.box {
height: 50px;
}
.box:link,
.box:visited {
color: #fff;
}
.box:hover,
.box:focus,
.box:active {
color: #000;
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# @content 也可以寫二個以上
例如時常在寫的瀏覽器兼容前綴詞
@mixin keyframes($animation) {
@-webkit-keyframes #{$animation} {
@content;
}
@-moz-keyframes #{$animation} {
@content;
}
@-ms-keyframes #{$animation} {
@content;
}
@-o-keyframes #{$animation} {
@content;
}
@keyframes #{$animation} {
@content;
}
}
@include keyframes(mymove) {
0% {
top: 0px;
}
100% {
top: 200px;
}
}
div {
width: 100px;
height: 100px;
background: red;
position: relative;
animation: mymove 5s infinite;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# RWD 斷點設計
//透過斷點變數統一管理
$pc: 1024px;
$mobile: 767px;
@mixin rwd($width) {
@media only screen and (max-width: $width) {
@content;
}
}
.box {
float: left;
width: 30%;
@include rwd($mobile) {
float: none;
width: 100%;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
產生結果
.box {
float: left;
width: 30%;
}
@media only screen and (max-width: 767px) {
.box {
float: none;
width: 100%;
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 使用 Map 方式
$breakpoints: (
desktop: 960px,
mobile: 568px,
);
@mixin for-mobile {
@media screen and (max-width: map-get($breakpoints, 'mobile')) {
@content;
}
}
@mixin for-desktop {
@media screen and (min-width: map-get($breakpoints, 'desktop')) {
@content;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# BEM 設計模式
在 mixin
當中使用了 @at-root
,所以編譯的 CSS 會一律放到最頂層,這可以解決 BEM 層數太深的問題,也可以在開發時保持良好的模組性。也可以在 mixin
加上一些參數決定是否要套用 @at-root
來保持開發上的彈性。
@mixin block($block_name) {
.#{$block_name} {
@content;
}
}
@mixin element($element_name) {
@at-root &__#{$element_name} {
@content;
}
}
@mixin modifier($modifier_name) {
@at-root &--#{$modifier_name} {
@content;
}
}
@include block(article-entry) {
padding: 20px;
@include element(content) {
font-size: 20px;
}
@include element(footer) {
background-color: #fff;
@include modifier(larger) {
height: 500px;
}
}
}
// compiled
.article-entry {
padding: 20px;
}
.article-entry__content {
font-size: 20px;
}
.article-entry__footer {
background-size: #fff;
}
.article-entry__footer--larger {
height: 500px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 引入 css variable
目前比較新的瀏覽器都已經支援 css variable 了。我們可以將顏色等變數使用 css variable 重新撰寫,並且使用優雅降級來確保在其他瀏覽器也能正常工作。
$colors: (
main: #aaa,
font: #333,
danger: red
);
:root {
@each $key, $color in $colors {
--#{key}: $color;
}
}
@mixin css($prop, $key) {
#{$prop}: map-get($colors, $key);
@if (map-has-key($colors, $key) == false) {
@error "Unknown key `#{$key}`. checkout your `$colors` variable";
}
@supports (--foo: "bar") {
#{$prop}: var(--#{$key});
}
}
.container {
@include css('background-color', "main");
}
// compiled
:root {
--main: #aaa;
--font: #333;
--danger: red;
}
.container {
background-color: #aaa;
@supports (--foo: "bar") {
background-color: var(--main);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 網格系統
仿效 Bootstrap 的設計模式,結合自訂的 mixin,達成簡易的網格系統規劃:
$width: 960px;
$gutter: 15px;
@mixin marginX($margin) {
margin-left: $margin;
margin-right: $margin;
}
@mixin paddingX($padding) {
padding-left: $padding;
padding-right: $padding;
}
// columnNumber: 欄位數量,columnGutter: 欄位間距
@mixin grid($columnNumber, $columnGutter: $gutter) {
flex-basis: ($width - $columnGutter * ($columnNumber - 1)) / $columnNumber;
@include paddingX($columnGutter);
box-sizing: border-box;
}
.container {
width: $width;
margin: 0 auto;
@include paddingX($gutter);
}
.row {
display: flex;
@include marginX($gutter * -1);
}
.productItem {
@include grid(4);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34