整理下sass的常用語法
目錄
- 1、變數
- 2、嵌套語法
- 3、繼承
- 4、注釋
- 5、根選擇器@at-root
- 6、運算
- 7、匯入(import)
- 8、控制陳述句
- 9、混入(mixin)
- 10、自定義函式
- 參考文獻
1、變數
sass中可以使用變數,變數名以$開頭:
$c: #fff;
body {
color: $c;
}
/* 編譯成css */
body {
color: #fff;
}
注意變數宣告遵循實作了塊級作用域,如果在選擇器內宣告的變數,只能在選擇器內部使用:
// 正確案例
body {
width: 100%;
height: 100%;
$c: red;
#app {
color: $c;
}
}
/* 編譯成css */
body {
width: 100%;
height: 100%;
}
body #app {
color: red;
}
// 錯誤案例
body {
width: 100%;
height: 100%;
$c: red;
}
.box {
color: $c;
}
// 錯誤 Error: Undefined variable: "$c"
如果要在選擇器內宣告全域變數,需要使用!global
body {
width: 100%;
height: 100%;
$c: red !global;
}
.box {
color: $c;
}
/* 編譯成css */
body {
width: 100%;
height: 100%;
}
.box {
color: red;
}
變數除了在屬性值內使用,也可用于屬性名或者注釋中,但是需要使用#{}包裹:
$c: color;
#app {
background-#{color}: red;
}
/* 編譯成css */
#app {
background-color: red;
}
$lang: css;
/* 編譯成#{$lang} */
/* 編譯成css */
2、嵌套語法
sass中可以將子標簽嵌套在父標簽中,避免了使用父子選擇器時重復書寫父標簽:
$c: #fff;
body {
color: $c;
#app {
width: 100%;
height: 100%;
}
}
/* 編譯成css */
body {
color: #fff;
}
body #app {
width: 100%;
height: 100%;
}
如果要在嵌套語法中使用父級選擇器,使用&即可,它會被替換成父級選擇器,常用于:hover、::before等:
a {
&:hover {
color: red;
}
}
/* 編譯成css */
a:hover {
color: red;
}
3、繼承
使用@extend可以繼承樣式:
body {
.flex {
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
}
.container {
@extend .flex;
width: 100%;
height: 100%;
color: #000;
}
}
/* 編譯成css */
body .flex, body .container {
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
}
body .container {
width: 100%;
height: 100%;
color: #000;
}
如果要繼承多個樣式,可以使用多次@extend,也可以使用逗號分隔:
body {
#app {
width: 100%;
height: 100%;
}
.container {
color: pink;
}
.box {
@extend #app, .container;
}
}
/* 編譯成css */
body #app, body .box {
width: 100%;
height: 100%;
}
body .container, body .box {
color: pink;
}
注意:使用媒體回應時,只能繼承@media內的樣式,不能繼承外部樣式,因為這樣會編譯出很多不必要的樣式,因此sass編譯時會報錯
正確做法:
@media screen {
body {
width: 100%;
}
#app {
@extend body;
}
}
/* 編譯成css */
@media screen {
body, #app {
width: 100%;
}
}
錯誤做法:
body {
width: 100%;
}
@media screen {
#app {
@extend body;
}
}
// 報錯 You may not @extend an outer selector from within @media.
// You may only @extend selectors within the same directive.
有時候我們只是想提取一個公共樣式,但是并不想它作為選擇器出現在編譯后的css中,這時可以使用占位符,占位符用%開頭:
// 案例1
%center {
width: 200px;
height: 200px;
margin: 0 auto;
}
#app {
@extend %center;
color: #000;
}
/* 編譯成css */
#app {
width: 200px;
height: 200px;
margin: 0 auto;
}
#app {
color: #000;
}
// 案例2
body %center {
width: 200px;
height: 200px;
margin: 0 auto;
}
#app {
@extend %center;
color: #000;
}
/* 編譯成css */
body #app {
width: 200px;
height: 200px;
margin: 0 auto;
}
#app {
color: #000;
}
4、注釋
sass提供了三種注釋,分別是//、/**/、/*!*/,第一種注釋在編譯后會被去掉,后兩種不會,且第三種在壓縮后仍會保留,通常用于表示著作權資訊,
/* 編譯成css */
// 我會被去掉
/*! 壓縮后我也在 */
body {
width: 100%;
height: 100%;
}
/* 編譯成css */
/*! 壓縮后我也在 */
body {
width: 100%;
height: 100%;
}
5、根選擇器@at-root
實際不應該叫根選擇器(css中有個叫根選擇器的::root),而是將被@at-root包裹的樣式放在最頂層,
body {
width: 100%;
height: 100%;
#app {
color: red;
}
@at-root {
.container {
background-color: #fff;
}
}
}
/* 編譯成css */
body {
width: 100%;
height: 100%;
}
body #app {
color: red;
}
.container {
background-color: #fff;
}
使用@at-root的好處是無論嵌套多深,都可以直接在@at-root中書寫頂層樣式,
6、運算
sass中可以使用運算,配合變數可以大幅度避免需要手動計算的情況:
$w: 100px;
$h: 300px;
$bw: 1px;
body {
width: $w + 100px;
height: $h - 100px;
border-bottom-width: $bw * 1;
border-top-width: $bw / 1;
}
/* 編譯成css */
body {
width: 200px;
height: 200px;
border-bottom-width: 1px;
border-top-width: 1px;
}
注意以下情況/會被解釋成除法:
- 如果值,或值的一部分,是變數或者函式的回傳值
- 如果值被圓括號包裹
- 如果值是算數運算式的一部分
p {
font: 10px/8px; // 普通的css,不會被轉化
$width: 1000px;
width: $width/2; // 使用了變數,會被轉化
width: round(1.5) / 2; // 使用了函式,會被轉化
height: (500px/2); // 使用了括號,會被轉化
margin-left: 5px + 8px/2px; // 使用了加號,會被轉化
}
/* 編譯成css */
p {
font: 10px/8px;
width: 500px;
width: 1;
height: 250px;
margin-left: 9px;
}
如果要確保/被解釋為除法,使用括號包裹即可,如果不想讓/被解釋成除法,可以使用#{}包裹:
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
/* 編譯成css */
p {
font: 12px/30px;
}
使用+可以拼接字串,字串是否帶引號以左邊為準:
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
/* 編譯成css */
p:before {
content: "Foo Bar";
font-family: sans-serif;
}
如果字串帶引號,則可以使用#{}插入動態的值:
p:before {
content: "I ate #{5 + 10} pies!";
}
/* 編譯成css */
p:before {
content: "I ate 15 pies!";
}
和JavaScript一樣,使用圓括號可以改變運算順序:
p {
height: 1em + 2em * 3;
width: (1em + 2em) * 3;
}
/* 編譯成css */
p {
height: 7em;
width: 9em;
}
除了四則運算以外,還可以使用關系判斷陳述句:>、<、>=、<=、==、!=,其中前四個只能用于數值,后兩個可用于任意型別,它們都回傳布林值,常用于判斷陳述句,
sass中的資料型別如下:
- 數字,
1, 2, 13, 10px - 字串,有引號字串與無引號字串,
"foo", 'bar', baz - 顏色,
blue, #04a3f9, rgba(255,0,0,0.5) - 布爾型,
true, false - 空值,
null - 陣列 (list),用空格或逗號作分隔符,
1.5em 1em 0 2em, Helvetica, Arial, sans-serif - maps, 相當于 JavaScript 的 object,
(key1: value1, key2: value2)
7、匯入(import)
sass提供了匯入功能,使用@import即可:
@import "common.scss";
需要注意的是,如果沒有提供后綴名,sass會嘗試按照后綴名scss和sass查找檔案,以下情況sass不會進行決議,而是原樣匯入:
- 指定了檔案擴展名為
css - 檔案路徑以
http://開頭 - 使用的是css的匯入語法
@import url(路徑) @import包含媒體查詢
@import "normalize.css";
@import "http://foo.com/bar";
@import url(common.css);
@import "foo" screen;
/* 編譯成css */
@import "normalize.css";
@import "http://foo.com/bar";
@import url(common.css);
@import "foo" screen;
8、控制陳述句
在sass中提供了一些條件判斷陳述句和回圈陳述句:@if、@else-if、@else、@for、@each、@while
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
/* 編譯成css */
p {
color: green;
}
@for的使用有兩種格式,一種是@for 變數名 from 開始 through 結束、@for 變數名 from 開始 to 結束,它們的區別在于第一種范圍是包含開始和結束,而第二種不包括結束,用數學中的開區間和閉區間來表示就是[開始, 結束]和[開始, 結束)的區別:
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
@for $i from 1 to 3 {
.item-#{$i} { height: 2em * $i; }
}
/* 編譯成css */
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
.item-1 {
height: 2em;
}
.item-2 {
height: 4em;
}
@for只能表示數值范圍,如果要回圈非數值,需要使用@each,它可以遍歷list:
@each $var in top, bottom, left, right {
body {
border-#{$var}-width: 1px;
}
}
/* 編譯成css */
body {
border-top-width: 1px;
}
body {
border-bottom-width: 1px;
}
body {
border-left-width: 1px;
}
body {
border-right-width: 1px;
}
注意list既可以用,分隔,也可以使用空格分隔,將其理解為陣列即可,因此也存在二維的list
@each $animal, $color, $cursor in (puma, black, default),
(sea-slug, blue, pointer),
(egret, white, move) {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
border: 2px solid $color;
cursor: $cursor;
}
}
/* 編譯成css */
.puma-icon {
background-image: url("/images/puma.png");
border: 2px solid black;
cursor: default;
}
.sea-slug-icon {
background-image: url("/images/sea-slug.png");
border: 2px solid blue;
cursor: pointer;
}
.egret-icon {
background-image: url("/images/egret.png");
border: 2px solid white;
cursor: move;
}
上面的用法有點類似JavaScript中同時使用回圈和解構:
const list = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for (const [a, b, c] of list) {
console.log(a, b, c)
}
// 輸出
// 1, 2, 3
// 4, 5, 6
// 7, 8, 9
除了可以遍歷list,each還可以遍歷map:
@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
#{$header} {
font-size: $size;
}
}
/* 編譯成css */
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.2em;
}
sass里面的 map 類似于JavaScript中的物件:
const map = { a: 1, b: 2, c: 3 }
for (const [key, value] of Object.entries(map)) {
console.log(key, value)
}
// 輸出
// a 1
// b 2
// c 3
最后是while回圈,和JavaScript類似:
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
/* 編譯成css */
.item-6 {
width: 12em;
}
.item-4 {
width: 8em;
}
.item-2 {
width: 4em;
}
9、混入(mixin)
mixin通常用于抽離公共樣式到獨立的檔案中,類似于JavaScript中常見的將工具方法抽離到utils檔案夾中一樣,用法類似于函式宣告,只是使用時需要借助@include:
@mixin clearfix {
display: inline-block;
&:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
* html & { height: 1px }
}
.box {
@include clearfix;
}
/* 編譯成css */
.box {
display: inline-block;
}
.box:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
* html .box {
height: 1px;
}
也可以給mixin傳參:
@mixin set-border($w, $c) {
border: solid $w $c;
}
.box {
@include set-border(1px, pink);
}
/* 編譯成css */
.box {
border: solid 1px pink;
}
也可以給mixin設定默認值:
@mixin set-border($dir: top, $w: 1px, $c: pink) {
border-#{$dir}: solid $w $c;
}
.box1 {
@include set-border(); // 不傳引數時括號也可省略
}
.box2 {
@include set-border(bottom, 2px, purple);
}
/* 編譯成css */
.box1 {
border-top: solid 1px pink;
}
.box2 {
border-bottom: solid 2px purple;
}
當不確定引數數量時,可以使用...:
@mixin box-shadow($shadows...) {
-moz-box-shadow: $shadows;
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
}
.shadows {
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
/* 編譯成css */
.shadows {
-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
-webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}
mixin也可以接受一個串列list,配合...,可以一次傳入多個引數:
@mixin colors($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$values: #ff0000, #00ff00, #0000ff;
.primary {
@include colors($values...);
}
/* 編譯成css */
.primary {
color: #ff0000;
background-color: #00ff00;
border-color: #0000ff;
}
有時候也需要從外部傳入一段代碼到mixin,傳入的樣式代碼可以通過@content得到,這種用法類似于vue中的默認插槽:
@mixin apply-to-ie6-only {
* html {
@content;
}
}
@include apply-to-ie6-only {
#logo {
background-image: url(/logo.gif);
}
}
/* 編譯成css */
* html #logo {
background-image: url(/logo.gif);
}
10、自定義函式
雖然mixin已經足夠強大,但有時我們不需要指定屬性名而只是單純的想要回傳屬性值,此時可以通過自定義函式,它和mixin類似,不同點在于它必須有回傳值,使用@return回傳,自定義函式使用@function宣告:
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar {
width: grid-width(5);
}
/* 編譯成css */
#sidebar {
width: 240px;
}
參考文獻
sass官方檔案
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/388356.html
標籤:其他
