scss快速入門

在使用scss以前,咱們要知道Sass、Scss有什麼不一樣?

SCSS 是 Sass 3 引入新的語法,其語法徹底兼容 CSS3,而且繼承了 Sass 的強大功能。也就是說,任何標準的 CSS3 樣式表都是具備相同語義的有效的 SCSS 文件,官方解釋css

傳統的css文件缺失變量等概念,致使須要書寫的重複的代碼不少。我寫JS的習慣是碰見重複的代碼就要思考是否能夠抽出來寫成一個可複用的方法,但css中不存在變量函數等概念,這時我發現的一個css的預編譯利器——scss。html

scss具備簡單易上手等特色,下面開始編寫第一個scss文件。前端

準備工做

寫在最前面:有小夥伴可能不太會部署前端環境,這裏我將代碼上傳到github中,有須要的小夥伴能夠把代碼下載下來對照着看SCSS代碼與編譯後的CSS代碼。vue

scss須要通過編譯爲css才能被瀏覽器識別,我這裏只作一個小demo因此不上vue-cli,直接使用webpack進行編譯。node

首先安裝css-loader、style-loader、node-sass、sass-loader。webpack

npm install css-loader style-loader --save-dev
npm install node-sass sass-loader --save-dev
複製代碼

而後在webpack.config.js配置文件中添加對應的loader,完整的配置圖以下。git

const path = require("path");
const {VueLoaderPlugin} = require('vue-loader');
module.exports = {
    entry: './webapp/App.js',
    output: {
        filename: 'App.js',
        path: path.resolve(__dirname, './dist')
    },
	module: {
		rules: [
            {
                test: /\.scss/,
                use: ['style-loader', 'css-loader','sass-loader']
            },
			{
				test: /\.vue$/,
				use: 'vue-loader'
			}
		]
	},
	plugins: [
		new VueLoaderPlugin()
	],
	mode: "production"
}

複製代碼

建立一個App.scss文件,接着在入口文件中引入。github

import './App.scss';
複製代碼

後面咱們將在App.scss中編寫scss代碼。web

正式開始

1.使用變量

SCSS中的變量以$開頭。vue-cli

$border-color:#aaa; //聲明變量
.container {
$border-width:1px;
    border:$border-width solid $border-color; //使用變量
}
複製代碼

上述例子中定義了兩個變量,其中$border-color在大括號以外稱爲全局變量,顧名思義任何地方均可以使用,$border-width是在.container以內聲明的,是一個局部變量,只有.container內部才能使用。

編譯後的CSS

.container {
    border:1px solid #aaa; //使用變量
}
複製代碼

咱們能夠把SCSS看作一個模板引擎,編譯的過程當中用變量的值去替代變量所佔據的位置。

tips:SCSS中變量名使用中劃線或下劃線都是指向同一變量的,上文中定義了一個變量$border-color,這時再定義一個變量$border_color:#ccc,他們指向同一個變量,.container的值會被第二次定義的變量覆蓋。

$border-color:#aaa; //聲明變量
$border_color:#ccc;
.container {
    $border-width:1px;
    border:$border-width solid $border-color; //使用變量
}
編譯後的CSS
.container {
    border:1px solid #ccc; //使用變量
}
複製代碼

這個例子中咱們要知道

(1)變量名使用中劃線或下劃線都是指向同一變量的。

(2)後定義的變量聲明會被忽略,但賦值會被執行,這一點和ES5中var聲明變量是同樣的。

2.嵌套規則

咱們先來看一個例子。

/*css*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
}

.container ul:after {
    display:block;
    content:"";
    clear:both;
}

.container ul li {
    float:left;
}

.container ul li>a {
    display:inline-block;
    padding:6px 12px;
}
複製代碼

這是一個讓列表元素橫向排列的例子,咱們在這個例子中寫了不少重複的代碼,.container寫了不少遍,下面我將用SCSS簡寫上面的例子。

2.1嵌套選擇器

/*scss*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
    
    li {
        float:left;
    }
    
    li>a {
        display:inline-block;
        padding:6px 12px;
    }
}

.container ul:after {
    display:block;
    content:"";
    clear:both;
}
複製代碼

這裏咱們能夠將公共的父元素提取出來。

2.2嵌套中的父級選擇器

SCSS提供了一個選擇器能夠選中當前元素的父元素,使用&表示,下面用父級選擇器繼續簡化代碼。

/*scss*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
    
    li {
        float:left;
    }
    
    li>a {
        display:inline-block;
        padding:6px 12px;
    }
    
    &:after {
        display:block;
        content:"";
        clear:both;
    }
}
複製代碼

父級選擇器中須要注意,只能在嵌套內部使用父級選擇器,不然SCSS找不到父級元素會直接報錯。 在各類僞類選擇器中,父級選擇器是十分經常使用的。

2.3嵌套組合選擇器

在嵌套規則中能夠寫任何css代碼,包括羣組選擇器(,),子代選擇器(>),同層相鄰組合選擇器(+)、同層全體組合選擇器(~)等等,下面繼續將自帶選擇器簡化掉。

/*scss*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
    
    li {
        float:left;
        
        >a {
            display:inline-block;
            padding:6px 12px;
        }
    }
    
    &:after {
        display:block;
        content:"";
        clear:both;
    }
}
複製代碼

子代選擇器能夠寫在外層選擇器右邊(以下述例子)也能夠寫在內層選擇器左邊(如上述例子)。

li >{ 
    a {
        display:inline-block;
        padding:6px 12px;
    }
}
複製代碼

寫在外層選擇器右邊時要特別注意,他會做用於全部嵌套的選擇器上,儘可能不要採用這類寫法,我認爲擴展性不強,也容易出錯。

2.4嵌套屬性

先看一個例子

/*css*/
li {
    border:1px solid #aaa;
    border-left:0;
    border-right:0;
}
複製代碼

這個例子中咱們只須要兩條邊框,使用SCSS重寫一遍。

/*scss*/
li {
    border:1px solid #aaa {
        left:0;
        right:0;
    }
}
複製代碼

scss識別一個屬性以分號結尾時則判斷爲一個屬性,以大括號結尾時則判斷爲一個嵌套屬性,規則是將外部的屬性以及內部的屬性經過中劃線鏈接起來造成一個新的屬性。

3.導入SCSS文件

大型項目中css文件每每不止一個,css提供了@import命令在css內部引入另外一個css文件,瀏覽器只有在執行到@import語句後纔會去加載對應的css文件,致使頁面性能變差,故基本不使用。SCSS中的@import命令跟原生的不太同樣,後續會講解到。

3.1導入變量的優先級問題-變量默認值

/*App1.scss*/
$border-color:#aaa; //聲明變量
@import App2.scss;  //引入另外一個SCSS文件
.container {
    border:1px solid $border-color; //使用變量
}
/*App2.scss*/
$border-color:#ccc; //聲明變量

/*生成的css文件*/
.container {
    border:1px solid #ccc; //使用變量
}
複製代碼

這可能並非咱們想要的,有時候咱們但願引入的某些樣式不更改原有的樣式,這時咱們可使用變量默認值。

/*App1.scss*/
$border-color:#aaa; //聲明變量
@import App2.scss;  //引入另外一個SCSS文件
.container {
    border:1px solid $border-color; //使用變量
}
/*App2.scss*/
$border-color:#ccc !default; //聲明變量

/*生成的css文件*/
.container {
    border:1px solid #aaa; //使用變量
}
複製代碼

導入的文件App2.scss只在文件中不存在$border-color時起做用,若App1.scss中已經存在了$border-color變量,則App2.scss中的$border-color不生效。

!default只能使用與變量中。

3.2嵌套導入

上一個例子中咱們是在全局中導入的App2.scss,如今咱們在爲App2.scss添加一些內容,並在局部中導入。

/*App1.scss*/
$border-color:#aaa; //聲明變量
.container {
    @import App2.scss;  //引入另外一個SCSS文件
    border:1px solid $border-color; //使用變量
}
/*App2.scss*/
$border-color:#ccc !default; //聲明變量
p {
    margin:0;
}

/*生成的css文件*/
.container {
    border:1px solid #aaa; //使用變量
}
.container p {
    margin:0;
}
複製代碼

能夠看得出來,就是將App2.scss中的全部內容直接寫入到App1.scss的.container選擇器中。

3.3 使用原生@import

前面咱們說到基本不使用原生@import,但某些狀況下咱們不得不使用原生@import時了,SCSS也爲咱們處理了這種狀況,直接導入css文件便可。

@import 'App.css';
複製代碼

4.註釋

SCSS中的註釋有兩種

(1)/*註釋*/:這種註釋會被保留到編譯後的css文件中。

(2)//註釋:這種註釋不會被保留到編譯後生成的css文件中。

5.混合器(函數)

5.1聲明一個函數

使用@mixin指令聲明一個函數,看一下本身的css文件,有重複的代碼片斷均可以考慮使用混合器將他們提取出來複用。

@mixin border-radius{
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    color:red;
}
複製代碼

混合器做用域內的屬性都是return的值,除此以外,還能夠爲函數傳參數。

@mixin get-border-radius($border-radius,$color){
    -moz-border-radius: $border-radius;
    -webkit-border-radius: $border-radius;
    border-radius: $border-radius;
    color:$color;
}
複製代碼

也能夠設置混合器的默認值。

@mixin get-border-radius($border-radius:5px,$color:red){
    -moz-border-radius: $border-radius;
    -webkit-border-radius: $border-radius;
    border-radius: $border-radius;
    color:$color;
}
複製代碼

5.2使用函數

使用函數的關鍵字爲@include

.container {
    border:1px solid #aaa;
    @include get-border-radius;         //不傳參則爲默認值5px
    @include get-border-radius(10px,blue);   //傳參
}
/*多個參數時,傳參指定參數的名字,能夠不用考慮傳入的順序*/
.container {
    border:1px solid #aaa;
    @include get-border-radius;         //不傳參則爲默認值5px
    @include get-border-radius($color:blue,$border-radius:10px);   //傳參
}
複製代碼

咱們可能會想到,直接將混合器寫成一個class不就好了,可是寫成一個class的時候是須要在html文件中使用的,而使用混合器並不須要在html文件中使用class既可達到複用的效果。

tips:混合器中能夠寫一切scss代碼。

6.繼承

繼承是面嚮對象語言的一大特色,能夠大大下降代碼量。

6.1定義被繼承的樣式

%border-style {
  border:1px solid #aaa;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}
複製代碼

使用%定義一個被繼承的樣式,相似靜態語言中的抽象類,他自己不起做用,只用於被其餘人繼承。

6.2繼承樣式

經過關鍵字@extend便可完成繼承。

.container {
	@extend %border-style;
}
複製代碼

上述例子中看不出混合器與繼承之間的區別,那麼下一個例子能夠看出繼承與混合器之間的區別。

.container {
	@extend %border-style;
	color:red;
}
.container1 {   //繼承另外一個選擇器
	@extend .container;
}
複製代碼

7.小結

經過本文的介紹,相信你們已經對SCSS有了必定的認知,可是光看是學不會的,我建議各位小夥伴要有強上的精神,先強行使用到目前正在作的項目中,熟悉一段時間,天然能夠寫出優質的SCSS代碼。

8.其餘

8.1操做符

SCSS提供了標準的算術運算符,例如+、-、*、/、%。

/*SCSS*/
width: 600px / 960px * 100%;
/*編譯後的CSS*/
width: 62.5%;
複製代碼

除此以外SCSS還有不少功能,各位小夥伴能夠先將目前的知識運用熟練再去學習也不遲。

9.交流

若是這篇文章幫到你了,以爲不錯的話來點個Star吧。 github.com/lizijie123

相關文章
相關標籤/搜索