1. 程式人生 > >Sass入門和使用總結

Sass入門和使用總結

我們這裡用兩個部分來說明吧。

1.如何學習Scss
2.如何使用Scss

1.如何學習Scss

學習Scss的第一步不是你要知道什麼是Scss的概念啊什麼的,而是找到一個合適的資源從頭開始學習,我在這裡推薦慕課網的資源Sass入門篇,還有Sass進階篇,sass中文官網
大家學習完以後,基本上就什麼會了。

這裡我整理一下它的一些重要的概念。基本上如果你知道這些,基本的使用就可以了。

Sass是什麼?

Sass並不是其他的什麼,而是CSS前處理器,前處理器就是定義了一種新的語言,其基本思想是,用一種專門的程式語言,為CSS增加了一些程式設計的特性,將CSS作為目標生成檔案,然後開發者就只要使用這些語言進行編碼工作。

果然,概念就不是給人看的。用CSS前處理器可以讓你的編碼效率提高十倍。就是這樣...

還有很多其他的CSS前處理器,比如

Sass(SCSS)
LESS
Stylus
Turbine
Swithch CSS
CSS Cacheer
DT CSS

其中最優秀的技師Sass、LESSStylus,在這裡,我們聊一下Sass.

Sass 和 SCSS 有什麼區別?

其實這兩貨說的是一個東東,由於一開始Sass規定的語法格式是嚴格的縮排式語法,不帶大括號和分號,所以造成程式設計師在寫sass的時候有非常大的不習慣,雖然它是最早的前處理器,卻沒有人家LESS用的人多,所以又支援了使用大括號和分號,這就是SCSS

.

1.副檔名不同,Sass 是以“.sass”字尾為副檔名,而 SCSS 是以“.scss”字尾為副檔名

2.語法書寫方式不同,Sass 是以嚴格的縮排式語法規則來書寫,不帶大括號({})和分號(;),而 SCSS 的語法書寫和我們的 CSS 語法書寫方式非常類似。

看程式碼:Sass語法

   $font-stack: Helvetica, sans-serif  //定義變數
   $primary-color: #333 //定義變數
   
   body
     font: 100% $font-stack
     color: $primary-color

Scss語法:

$font-stack: Helvetica, sans-serif;
$primary
-color: #333; body { font: 100% $font-stack; color: $primary-color; }

SASS環境的安裝

Sass的基本特性-基礎

宣告變數
image

上面的圖告訴大家,Sass的變數包括了三個部分:

1. 宣告變數的符號“$”
2.變數名稱
3.賦予變數的值

例如:

brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color : #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;

!default表示的是預設值。

普通變數與預設變數

上面我們知道,如果想要設定預設值,只需要!default在值的後面就可以了。

那麼如果我們想要覆蓋的時候怎麼辦呢,就是在前面申明一個就行。

$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
    line-height: $baseLineHeight; 
}

編譯後:

body{
    line-height:2;
}

巢狀-選擇器巢狀

Sass 的巢狀分為三種:

選擇器巢狀
屬性巢狀
偽類巢狀

下面我們看選擇器巢狀,例如我們有一段這樣的結構:

<header>
<nav>
    <a href=“##”>Home</a>
    <a href=“##”>About</a>
    <a href=“##”>Blog</a>
</nav>
<header>

如果想要選中header中的a標籤,在寫CSS會這樣寫:

nav a {
    calor:red;
}

header nav a {
    color:green;
}

Sass中,就可以使用選擇器巢狀來實現:

nav {
    a {
        color:red;
        
        header & {
            color:green;
        }
    }
}

巢狀-屬性巢狀

Sass提供的屬性巢狀主要是針對CSS有一些屬性字首相同,只是字尾不一樣,比如border-top/border-right還有
margin,padding,font等屬性,假設你的樣式中用到了:

.box{
    border-top:1px solid red;
    border-bottom:1px solid green;
}

Sass中,我們可以這樣寫:

.box{
    border:{
        top:1px solid red;
        bottom:1px solid green;
    }
}

巢狀-偽類巢狀

其實偽類巢狀和屬性巢狀非常類似,只不過他需要藉助&符號一起配合使用。我們就拿經典的“clearfix”為例吧:

.clearfix{
&:before,
&:after {
    content:"";
    display: table;
  }
&:after {
    clear:both;
    overflow: hidden;
  }
}

編譯出來的CSS

clearfix:before, .clearfix:after {
  content: "";
  display: table;
}
.clearfix:after {
  clear: both;
  overflow: hidden;
}
避免選擇器巢狀:
選擇器巢狀最大的問題是將使最終的程式碼難以閱讀。開發者需要花費巨大精力計算不同縮排級別下的選擇器具體的表現效果。
選擇器越具體則宣告語句越冗長,而且對最近選擇器的引用(&)也越頻繁。在某些時候,出現混淆選擇器路徑和探索下一級選擇器的錯誤率很高,這非常不值得。

混合巨集-宣告混合巨集

混合巨集的出現主要是為了解決當樣式變得越來越多,越來越複雜的時候,需要重複使用大段樣式時,而使用變數又無法達到我們的目的,這個時候就要用到了混合巨集。

1.宣告混合巨集

我們通過@mixin來宣告一個混合巨集:

@mixin border-radius{
    -webkit-border-radius:5px;
    border-radius:5px;
}

其中@mixin是混合巨集的關鍵詞,類似於css中的@media,@font-face一樣。border-radius是混合巨集的名稱。大括號裡面是複用的樣式程式碼。

2.帶引數混合巨集

我們可以定義混合巨集時帶有引數:

@mixin border-radius($radius:5px){
    -webkit-border-radius: $radius;
    border-radius: $radius;
}

3.複雜的混合巨集

我們可以在大括號裡面寫上邏輯關係

@mixin box-shadow($shadow...) {
  @if length($shadow) >= 1 {
    @include prefixer(box-shadow, $shadow);
  } @else{
    $shadow:0 0 4px rgba(0,0,0,.3);
    @include prefixer(box-shadow, $shadow);
  }
}

這個box-shadow的混合巨集,帶有多個引數,這個時候可以使用...來代替。
上面的意思是當$shadow的引數數值大於或等於1時,表示有多個陰影值,反之呼叫預設的引數值

混合巨集的呼叫

我們通過關鍵詞@include來呼叫宣告好的混合巨集,然後如果需要傳引數,我們就傳入引數;

@mixin border-radius{
    -webkit-border-radius: 3px;
    border-radius: 3px;
}

使用:

button {
    @include border-radius;
}

混合巨集的引數

1.傳一個不帶值的引數

我們在混合巨集中,可以傳一個不帶任何值的引數:

@mixin border-radius($radius){
    -webkit-border-radius: $radius;
    border-radius: $radius;
}

我們定義了一個不帶任何值的引數$radius,然後我們在呼叫的時候給這個引數傳值:

.box {
    @include border-radius(3px);
}

2.傳一個帶值的引數

@mixin border-radius($radius:5px){
    -webkit-border-radius: $radius;
    border-radius: $radius;
}

在混合巨集宣告的時候,我們給這個引數的添加了一個預設值。5px我們可以傳引數,同樣也可以不傳。

.btn{
    @include border-radus;
    
}

3.混合巨集傳多個引數
混合巨集可以傳多個引數:例如:

@mixin center($width,$height){
  width: $width;
  height: $height;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -($height) / 2;
  margin-left: -($width) / 2;
}

使用的時候一樣

.box-center{
    @include center(500px,300px);
}

這個混合巨集和我們程式設計裡的函式很像啊。

混合巨集的不足

混合巨集的不足的地方就是不能智慧的合併相同的程式碼。它的缺點和它的優點一樣重要,這樣我們才能在合適的地方用合適的程式碼。

@mixin border-radius{
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

.box {
  @include border-radius;
  margin-bottom: 5px;
}

.btn {
  @include border-radius;
}

在程式碼中,.box.btn中都呼叫了定義好的border-radius混合巨集,然後我們看一下編譯出來的CSS

.box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
  margin-bottom: 5px;
}

.btn {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

上面的程式碼可以很明顯的看出,Sass在呼叫相同的混合巨集時,並不能智慧的將相同的樣式程式碼合併在一起。

Scss程式碼的繼承

Scss程式碼的繼承是通過關鍵字@extned來實現的。比如:

.btn{
    border:1px solid #ccc;
    padding:6px 10px;
    font-size:14px;
}

.btn-primary{
    background-color:#f36;
    color:#fff;
    @extend .btn;
}


.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}

就是這樣繼承的,編譯出來後的CSS

.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
}

.btn-second {
  background-clor: orange;
  color: #fff;
}

佔位符 % placeholder

Sass中的佔位符%placeholder功能非常強大,它非常適合去做樣式的基類。因為,如果我們不通過@extend呼叫的時候,不會產生任何程式碼。例如:

%mt5{
    margin-top:5px;
}
%pt5{
    padding-top:5px;
}
.btn{
    @extend %mt5;
    @extend %pt5;
}

.block {
    @extend %mt5;
    
    span {
        @extend %pt5;
    }
}

我們看編譯後的程式碼:

.btn, .block {
  margin-top: 5px;
}

.btn, .block span {
  padding-top: 5px;
}

我們可以看到,通過@extend呼叫的佔位符,編譯出來的程式碼將相同的程式碼合併在一起,這樣讓你的程式碼更加乾淨。

混合巨集 VS 繼承 VS 佔位符

我們這裡總結一下,看圖就好:


image

插值#{}

通過 #{} 插值語句可以在選擇器或屬性名中使用變數:

$name:foo;
$attr:border;
p.#{$name}{
    #{$attr}-color:blue;
}

編譯為:

p.foo{
    border-color:blue;
}

#{}插值語句也可以在屬性值中插入SassScript,大多數情況下,這樣可能還不如使用變數方便,但是使用#{}可以避免Sass執行運算表示式,直接編譯CSS.

p {
  $font-size: 12px;
  $line-height: 30px;
  font: #{$font-size}/#{$line-height};
}

編譯為:

p {
    font:12px /30px;
}

上面基礎的Scss語法就介紹到這裡.

2.如何使用Scss

首先,我們需要安裝依賴包

//在專案下,執行下列命令列
npm install --save-dev sass-loader
//因為sass-loader依賴於node-sass,所以還要安裝node-sass
npm install --save-dev node-sass

css-loaderstyle-loader也是必須的依賴包:

css-loader使你能夠使用類似@import 和 url(…)的方法實現 require()的功能;
style-loader將所有的計算後的樣式加入頁面中;

下面是webpack.config.js檔案的部分配置:

var ExtractTextPlugin = require('extract-text-webpack-plugin');//css樣式從js檔案中分離出來,需要通過命令列安裝 extract-text-webpack-plugin依賴包
module.exports = {
    ....
    module: {
        loaders: [
            //解析.css檔案
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract("style", 'css')
            },
            //解析.vue檔案
            {
                test: /\.vue$/,
                loader: 'vue'
            }, 
            //解析.scss檔案,對於用 import 或 require 引入的sass檔案進行載入,以及<style lang="sass">...</style>宣告的內部樣式進行載入
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract("style", 'css!sass') //這裡用了樣式分離出來的外掛,如果不想分離出來,可以直接這樣寫 loader:'style!css!sass'
            }
        ]
    },
    //.vue檔案的配置,以下是為了在.vue檔案中使用ES6語法(必須安裝babel相關的依賴包),以及把使用css或sass語法的樣式提取出來,如果不需要可以忽略
    vue: {
        loaders: {
            js: 'babel', 
            css: ExtractTextPlugin.extract("css"),
            sass: ExtractTextPlugin.extract("css!sass")            
        },
    },
    plugins: [
        new ExtractTextPlugin("style.css") //提取出來的樣式放在style.css檔案中
    ]
    ....
}

使用的時候直接import就可以了,引入外部樣式,下面兩種寫法都可以用:

import '../../css/test.scss'
require('../../css/test2.scss');

我們在react js中就可以這樣寫:
.vue檔案中使用:

<style lang="sass">
     //sass語法樣式
</style>

這裡分享一個我自己寫的base_layout.Scss

顏色和大小 base.scss

/**
 * 字型和顏色,基礎佈局的base檔案
 */
//字型大小
$remindTitleSize:20px;
$navigationSize:18px;
$contentSize:17px;
$buttonSize:16px;
$tabFontSize:15px;
$minorSize:14px;
$smalltitleSize:13px;
$smallerSize:12px;
$assistSize:11px;

//顏色
$white:#fff;
$assistColor:#c1c1c1;
$minorColor:#8e8e8e;
$contentColor:#5e5e5e;
$remindColor:#ee5765;
$buttonColor:#7d9ef0;
$backgroundColor:#f0f0f0;
$lineColor:#e8e8e8;
$headerTextColor:#5c5c5c;
$titleColor:#333333;
$circleColor:#FFF9c6;


樣式表:base_layout.scss:

//基礎佈局檔案
@import "base";

%flex{
  flex: 1;
  -webkit-flex: 1;
}

.base {
  display: flex;
  display: -webkit-flex;
}

//橫向佈局
.base_row {
  @extend .base;
  flex-direction: row; -webkit-flex-direction: row;
}

//豎向佈局
.base_column{
  @extend .base;
  flex-direction: column; -webkit-flex-direction: column;
}

@mixin justify-content($layout:center){
  justify-content: $layout;
  -webkit-justify-content: $layout;
}

@mixin align-items($layout:center){
  align-items: $layout;
  -webkit-align-items: $layout;
}

@mixin get_font_size($fontSize:14px){
  font-size: $fontSize;
}

//豎向居中對齊
.base_column_justify_center {
  @extend .base_column;
  @include justify-content(center);
}

//橫向居中對齊
.base_row_justify_center {
  @extend .base_row;
  @include justify-content(center);
}

//豎向垂直居中齊
.base_column_align_center {
  @extend .base_column;
  @include align-items(center);
}

//橫向垂直居中對齊
.base_row_align_center {
  @extend .base_row;
  @include align-items(center);
}

//居中
.base_center {
  @extend .base;
  @include justify-content(center);
  @include align-items(center);
}

.base_row_justify_space-between{
  @extend .base_row;
  @include justify-content(space-between);
}

.base_row_title_layout{
  @extend .base_row_align_center;
  @include justify-content(space-between);
}

//頁面container根佈局
.page_container {
  flex: 1;
  -webkit-flex: 1;
  flex-direction: column; -webkit-flex-direction: column;
  display: flex;
  display: -webkit-flex;
  background: $backgroundColor;
  font-size: 15px;
}

.page_context {
  @extend .base_column;
  @extend %flex;
  overflow: scroll;
  overflow-scrolling: touch;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 10px;
  overflow-x: hidden;
}

//如果有需要,自己新增...

我們可以把一些常用個佈局封裝到base_layout.scss中,當使用的時候自己組裝,使用,繼承,擴充套件...