8 SASS mixins you must have in your toolbox

1. 字型單位 rem 設定並支援舊時代瀏覽器

單位設定 rem 相似於 em,但其大小並不是依據父元素的值,而是根據 html 標籤的字體大小設定。它擁有 em 相同的好處且不可再擔心混合使用時的問題,因為它只相對於 html 元素來調整大小。但不幸的是IE8 以前的瀏覽器並不支援這個設定。但我們仍可使用這個 mixin 改用 pixel 設定來向後兼容。

1
2
3
4
5
6
7
8
9
@function calculateRem($size) {
$remSize: $size / 16px;
@return $remSize * 1rem;
}

@mixin font-size($size) {
font-size: $size;
font-size: calculateRem($size);
}

使用

1
2
3
p {
@include font-size(14px)
}

輸出

1
2
3
4
p {
font-size: 14px; //Will be overridden if browser supports rem
font-size: 0.8rem;
}

2. 螢幕斷點

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@mixin bp-large {
@media only screen and (max-width: 60em) {
@content;
}
}

@mixin bp-medium {
@media only screen and (max-width: 40em) {
@content;
}
}

@mixin bp-small {
@media only screen and (max-width: 30em) {
@content;
}
}

使用

1
2
3
4
5
6
7
8
9
10
.sidebar {
width: 60%;
float: left;
margin: 0 2% 0 0;
@include bp-small {
width: 100%;
float: none;
margin: 0;
}
}

輸出

1
2
3
4
5
6
7
8
.sidebar {
width: 60%;
float: left;
margin: 0 2% 0 0;
@media only screen and (max-width: 30){
.sidebar{width: 100%; float: none; margin: 0;}
}
}

3. SVG 背景圖與向後支援 png 和 retina

這個 mixin 需搭配 Modernizr 和花費一些力氣為你的網站產生多種規格的圖像,但最終仍是值得的。

你會需要一個 .svg 檔案用來作為預設的背景圖。你也將需要一般的 .png 檔以備遇到不支援 SVG 的瀏覽器時使用。最後,你需要產生一個兩倍大的 .png 圖檔以作為遇到 retina 螢幕時使用。

因此,所需檔案如下:

  • pattern.svg
  • pattern.png
  • pattern@2x.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$image-path: '../img' !default;
$fallback-extension: 'png' !default;
$retina-suffix: '@2x';
@mixin background-image($name, $size:false){
background-image: url(#{$image-path}/#{$name}.svg);
@if($size){
background-size: $size;
}
.no-svg &{
background-image: url(#{$image-path}/#{$name}.#{$fallback-extension});

@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
background-image: url(#{$image-path}/#{$name}#{$retina-suffix}.#{$fallback-extension});
}
}
}

使用

1
2
3
body {
@include background-image('pattern');
}

4. 影格動畫

CSS 的 animationkeyframes 需要定義不同的前綴 (prefix) 來支援不同類型的瀏覽器

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
@mixin keyframes($animation-name) {
@-webkit-keyframes #{$animation-name} {
@content;
}
@-moz-keyframes #{$animation-name} {
@content;
}
@-ms-keyframes #{$animation-name} {
@content;
}
@-o-keyframes #{$animation-name} {
@content;
}
@keyframes #{$animation-name} {
@content;
}
}

@mixin animation($str) {
-webkit-animation: #{$str};
-moz-animation: #{$str};
-ms-animation: #{$str};
-o-animation: #{$str};
animation: #{$str};
}

使用

1
2
3
4
5
6
7
8
9
10
11
@include keyframes(slide-down) {
0% { opacity: 1; }
90% { opacity: 0; }
}

.element {
width: 100px;
height: 100px;
background: black;
@include animation('slide-down 5s 3');
}

5. 漸變動畫

如同上一點,CSS 的 transition 也需要不同的 prefix 支援不同類型的瀏覽器。

1
2
3
4
5
6
7
@mixin transition($args...) {
-webkit-transition: $args;
-moz-transition: $args;
-ms-transition: $args;
-o-transition: $args;
transition: $args;
}

使用

1
2
3
4
5
6
7
a {
color: gray;
@include transition(color .3s ease);
&:hover {
color: black;
}
}

6. 跨瀏覽器的透明設定

此 mixin 可以支援到 Internet Explorer 5

1
2
3
4
5
@mixin opacity($opacity) {
opacity: $opacity;
$opacity-ie: $opacity * 100;
filter: alpha(opacity=$opacity-ie); //IE8
}

使用

1
2
3
.faded-text {
@include opacity(0.8);
}

7. Clearfix

1
2
3
4
5
6
7
8
9
10
%clearfix {
*zoom: 1;
&:before, &:after {
content: " ";
display: table;
}
&:after {
clear: both;
}
}

使用

1
2
3
.container-with-floated-children {
@extend %clearfix;
}

8. 隱藏元素

當你用 display: none 來隱藏一個元素時,Screen Reader 不會為使用者將其內容讀出來。但有時候我們會為了視障人士的易用性(Accessible)隱藏某些元素,並希望 Screen Reader 讀出來。

在這個範例中,我們使用 SASS placeholder selector來減少重覆的輸出結果。

1
2
3
4
5
6
7
8
9
10
%visuallyhidden {
margin: -1px;
padding: 0;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
clip: rect(0, 0, 0, 0);
position: absolute;
}

使用

1
2
3
4
<button class="mobile-navigation-trigger">
<b class="visually-hidden">Open the navigation</b>
<img src="img/mobile-navigation-icon.svg">
</button
1
2
3
.visually-hidden {
@extend %visuallyhidden;
}