【Sass/SCSS 官方英文文檔翻譯整理】SCSS 完整自學中文版教程01_Sass基本介紹

drylint 2021-09-18 08:39:59 阅读数:92

sass scss 官方 英文 文文

Sass 基本介紹

[toc]

如果對本文有任何問題,建議,或者在前端技術體系方面有任何問題,可以添加我的微信: drylint , 我會盡可能為你解答,也會拉你進入前端技術進階交流群,大家一起進步~

Sass 是 CSS 的超集,支持所有 css 語法,並在其基礎上擴展。

Sass 支持像 css 一樣的大括號語法,文件擴展名為 .scss ,以及另一種使用縮進的語法,文件擴展名為 .sass

教程主要采取完全兼容 css 的 SCSS 語法。

注釋(Comments)

支持兩種注釋,分別是:

  • 單行注釋 // 注釋文字
  • 多行注釋 /* 注釋文字 */

單行注釋(Single-line comments)

編譯的時候會直接被忽略,不會編譯到 CSS 中,所以也叫做“隱式注釋”(silent comments)。

// 注釋內容

多行注釋(Multi-line comments)

編譯時會將注釋編譯到 css 中,所以也叫做“顯式注釋”(loud comment)

// 這一行注釋不會出現在編譯的 css 中
/* 這一行會出現在編譯的 css 中,除非是在壓縮模式下則不會 */
/* 注釋中還可以包含插值:
* 1 + 1 = #{1 + 1} */
/*! 這行注釋即使在壓縮模式下也會編譯到 css 中 */
p /* 多行注釋可以寫在任何
* 允許空白出現的地方 */ .sans {
font-size: 16px;
}

編譯後的 css:

/* 這一行會出現在編譯的 css 中,除非是在壓縮模式下則不會 */
/* 注釋中還可以包含插值:
* 1 + 1 = 2 */
/*! 這行注釋即使在壓縮模式下也會編譯到 css 中 */
p .sans {
font-size: 16px;
}

SassDoc

文檔注釋,類似於 jsdoc 。使用三斜線 /// 聲明。

/// Computes an exponent.
///
/// @param {number} $base
/// The number to multiply by itself.
/// @param {integer (unitless)} $exponent
/// The number of `$base`s to multiply together.
/// @return {number} `$base` to the power of `$exponent`.
@function pow($base, $exponent) {
$result: 1;
@for $_ from 1 through $exponent {
$result: $result * $base;
}
@return $result;
}

特殊的函數(Special Functions)

  • url()
  • xxx

url()

url() 函數在CSS中很常用,但是它的語法與其他函數不同,它可以接受帶引號的 url ,也可以接受不帶引號的 url。因為未加引號的 URL 不是有效的 SassScript 錶達式,所以 Sass 需要特殊的邏輯來解析它。

如果 url() 的參數是一個有效的無引號的 url ,Sass 會原樣解析它,當然,插值也是可以用的。

如果參數不是一個有效的無引用的 url ,例如,如果它包含變量或函數調用,它將被解析為普通的 CSS 函數調用。

$roboto-font-path: "../fonts/roboto";
@font-face {
// This is parsed as a normal function call that takes a quoted string.
src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2");
}
@font-face {
// This is parsed as a normal function call that takes an arithmetic
// expression.
src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2");
}
@font-face {
// This is parsed as an interpolated special function.
src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2");
}

編譯後的 css :

@font-face {
src: url("../fonts/roboto/Roboto-Thin.woff2") format("woff2");
}
@font-face {
src: url("../fonts/roboto/Roboto-Light.woff2") format("woff2");
}
@font-face {
src: url(../fonts/roboto/Roboto-Regular.woff2) format("woff2");
}

calc()element()

calc()element() 函數是在 CSS 規範中定義的。因為 calc() 的數學錶達式與 Sass 的算法沖突,而 element() 的id可以被解析為顏色,所以它們需要特殊的解析。

Sass 允許任何文本出現在這些函數調用中,包括嵌套的圓括號。

除了可以使用插值來注入動態值會被編譯處理。其他任何東西都不會被解釋為 SassScript 錶達式進行計算,而是原樣輸出。

progid:...()expression() 弃用

expression() 和以 progid: 開頭的函數是使用非標准語法的 Internet Explorer 遺留特性。盡管最近的瀏覽器已經不再支持它們,但是 Sass 繼續解析它們以實現向後兼容。

min()max()

CSS在 CSS Values and Units Level 4 中增加了對 min()max() 函數的支持,Safari 很快就采用了它們來支持 iPhoneX 。

但是 Sass 在很久以前就已經有了自己的 min()max() 函數,為了向後兼容所有現有的樣式錶。這就需要額外的句法技巧來實現。

如果一個 min()max() 函數調用是有效的純 CSS ,它將被編譯為普通的 CSS 的 min()max() 函數調用。

"純CSS "包括嵌套調用 calc()env()var()min() ,或 max() ,以及插值。

但是,只要調用的時候包含了 SassScript 特性(如變量或函數調用),它就會被認為是對 Sass 自帶的 min()max() 函數的調用。

變量

在 Sass 中,聲明變量必須以 $ 開頭。

$red: #f00;
div {
color: $red;
}

編譯後的 css :

div {
color: #f00;
}

Sass 變量和 css 變量的區別:

  • Sass 變量會被編譯成真實的值然後輸出為 css ,也就是僅僅存在於開發階段。
  • CSS 變量對於不同的元素可以有不同的值,但是 Sass 變量一次只有一個值。
  • Sass 變量是不可逆的,這意味著如果您使用了一個變量,然後在後面更改了它的值,那麼之前的使用將依然保持不變。CSS 變量是聲明性的,這意味著如果在後面更改了值,它將影響前面的使用和以後的使用。

注意:和所有的 Sass 標識符一樣,Sass 變量將連字符 - 和下劃線 _ 視為相同的字符。這意味著 $font-size$font_size 都指向同一個變量。這是 Sass 早期的曆史遺留,當時它只允許在標識符名稱中使用下劃線。後來, Sass 增加了對連字符的支持,以匹配 CSS 的語法,sass 將這兩個字符視為等效處理,以便於使遷移更加容易。

默認值

比如開發一個庫,用戶可以選擇是否傳遞自定義的值,如果沒有傳遞則使用默認值。

為了實現這一點,Sass 提供了 !default 標志。只有當變量沒有定義或者它的值為 null 時,才會給該變量賦值。否則,將使用默認的值。

配置模塊變量

!default 定義的變量,可以在使用 @use 規則加載模塊時配置。

在模塊中聲明變量,並定義默認值:

// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;
code {
border-radius: $border-radius;
box-shadow: $box-shadow;
}

在引用模塊時,選擇要自定義值的變量,忽略的變量則使用默認值:

// index.scss
@use 'library' with (
$black: #222,
$border-radius: 0.1rem
);

內置變量

內置模塊定義的變量是無法被修改的。

比如,下面代碼視圖修改內置變量,但不會成功:

@use "sass:math" as math;
// This assignment will fail.
math.$pi: 0;

作用域

在 css 文件頂層聲明的變量是全局變量,聲明後可以在模塊中的任何地方被訪問。

在塊({})中聲明的變量是局部變量,只能在聲明它們的塊內訪問。

// 全局變量
$red: #f00;
div {
// 局部變量
$black: #000;
color: $red;
}
p {
// 在這裏引用局部變量編譯時會報錯
color: $black;
}

當局部變量和全局變量重名時,不會覆蓋全局變量,而是同時存在,在哪個作用域訪問的就是哪個變量。

$red: #f00;
div {
$red: #f55;
color: $red;
}
p {
color: $red;
}

編譯後的 css :

div {
color: #f55;
}
p {
color: #f00;
}

如果想用一個局部變量去覆蓋全局變量,也就是在塊中修改全局變量的值,可以使用 !global 來完成:

$red: #f00;
div {
// !global 將修改全局變量的值,而不是在塊中新建一個局部作用域
$red: #f55 !global;
color: $red;
}
p {
color: $red;
}
div {
color: #f55;
}
p {
color: #f55;
}

注意:如果使用 !global 的變量不是一個全局變量,則編譯時會報錯。

在流程控制語句(@if/@each/@for/@while 等)中聲明的變量有一個自己的特殊作用域,它不會創建新變量去覆蓋同級作用域中的同名變量,而是簡單地進行原變量的賦值修改操作。

$dark-theme: true;
$red: #e55;
$black: #333;
@if $dark-theme {
$red: #f00;
$black: #000;
}
.button {
background-color: $red;
color: $black;
}

編譯後的 css :

.button {
background-color: #f00;
color: #000;
}

在流程控制語句中,賦值給已經存在的變量則是修改操作,如果是不存在的變量則會創建一個新的變量,但這個新的變量也只能在這個流程控制語句的作用域中使用。

檢測變量是否存在

Sass 核心庫提供了兩個用於處理變量的高級函數。meta.variable-exists() 函數返回給定名稱的變量是否在當前作用域中存在, meta.global-variable-exists() 函數做同樣的事情,但僅用於全局作用域。

@debug meta.variable-exists("var1"); // false
$var1: value;
@debug meta.variable-exists("var1"); // true
h1 {
// $var2 is local.
$var2: value;
@debug meta.variable-exists("var2"); // true
}
@debug meta.global-variable-exists("var1"); // false
$var1: value;
@debug meta.global-variable-exists("var1"); // true
h1 {
// $var2 is local.
$var2: value;
@debug meta.global-variable-exists("var2"); // false
}

用戶有時可能會希望使用插值來定義基於另一個變量的變量名。Sass 不允許這樣做,因為它使得我們很難一眼就知道哪些變量在哪裏定義。但是,您可以做的是定義一個從名稱到值的 map,然後您可以使用變量訪問該映射。

@use "sass:map";
$theme-colors: (
"success": #28a745,
"info": #17a2b8,
"warning": #ffc107,
);
.alert {
// Instead of $theme-color-#{warning}
background-color: map.get($theme-colors, "warning");
}

編譯後的 css :

.alert {
background-color: #ffc107;
}

插值(Interpolation)

插值幾乎可以在 Sass 樣式錶的任何地方使用,以將 SassScript 錶達式的結果嵌入到 CSS 塊中。

#{} 中放置一個錶達式即可,比如可以用在:

  • 選擇器
  • 屬性名
  • 自定義屬性值
  • CSS 的 @ 語句中
  • @extends
  • CSS @imports
  • 字符串
  • 特殊函數
  • CSS 函數名
  • 保留注釋(Loud comments ) /* ... */

下面展示部分用法,在選擇器,屬性,繼承,注釋語句中使用插值:

$selector: "hello";
$color: "color";
/* selector: #{$selector} */
.#{$selector} {
background-#{$color}: #f00;
}
.#{$selector}-2 {
@extend .#{$selector};
border-#{$color}: #f00;
}
/* selector: hello */
.hello,
.hello-2 {
background-color: #f00;
}
.hello-2 {
border-color: #f00;
}

在 SassScript 中,可以使用插值錶達式將 SassScript 注入到未加引號的字符串中。這在動態生成名稱(例如動畫)或使用斜杠分隔值時特別有用。

注意: SassScript 中的插值永遠返回一個未加引號的字符串,在上面的例子中已經看到了。

插值對於將值注入到字符串中很有用,但除此之外,在 SassScript 錶達式中很少需要插值。

比如,使用變量完全不需要這樣寫: color: #{$red} ,而是可以直接使用變量: color: $red

注意:不應該使用插值插入數字。因為插值總是返回未加引號的字符串,返回值並不能進一步用於計算,這也同時避免了違反 Sass 內置的的安全保護規則,以確保能够正確使用單比特。

Sass 有强大的單比特運算,你可以使用它來代替。例如,與其寫 #{$width}px ,不如寫 $width * 1px,或者更好的是,以px開頭聲明$width變量。這樣,$width 已經有單比特,你將得到一個很好的錯誤消息,而不是編譯偽造的CSS。

還有,雖然可以使用插值將帶引號的字符串轉換為不帶引號的字符串,但使用 string.unquote() 函數會更清楚。所以應該用 string.unquote($string) 來代替 #{$string}

@語句(At-Rules)

Sass 在 CSS 之上添加了新的 @ 語句 :

  • @mixin@include 用於複用大的塊級樣式
  • @function 聲明自定義函數,用於 SassScript 錶達式中
  • @extend 用於在一個選擇器中繼承另一個選擇器的樣式
  • @at-root 將代碼塊內部的樣式編譯到 css 最外層(相當於頂級作用域)
  • @error 故意使編譯失敗而中斷,並拋出錯誤信息
  • @warn 拋出一條錯誤信息但不使編譯程序失敗而中斷
  • @debug 拋出一條用於 debug 調試的消息
  • @if, @each, @for, @while 流程控制語句

@mixin and @include

@mixin 用於定義要複用的樣式塊,@include 用於調用這些樣式塊。

因曆史遺留原因,mixin 的名字和 Sass 標識符一樣,連字符(hyphens) - 和下劃線(underscores)_ 被視為完全相同。

定義 mixin 的語法:

// 不需要傳參數時,複用固定的樣式代碼
@mixin <name> {
// ...
}
// 或
// 需要使用時傳遞參數,動態複用樣式代碼
@mixin name(arg1, arg2, ..., argN) {
// ...
}

使用 mixin 的語法:

@include <name>;
// 或
@include <name>(arg1, arg2, ...)

使用示例:

// a.scss
@mixin input {
padding: 10px;
color: #333;
}
@mixin button ($color, $fontSize) {
color: $color;
font-size: $fontSize;
}
@use "a";
.input {
@include a.input;
}
.button {
@include a.button(#333, 20px);
}

編譯後的 css :

.input {
padding: 10px;
color: #333;
}
.button {
color: #333;
font-size: 20px;
}

通常情况下,如果一個 mixin 定義時有多少個參數,那麼在調用時必須傳遞相同數量的參數,除非是定義 mixin 時使用了參數默認值。

mixin 參數默認值

定義一個參數默認值就像定義一個變量一樣,參數名後加一個冒號,然後就可以寫默認值了。

@mixin button ($color, $fontSize: 16px) {
color: $color;
font-size: $fontSize;
}
.button {
@include button(#f00);
}

編譯後的 css :

.button {
color: #f00;
font-size: 16px;
}

默認參數值可以是任意 Sass 錶達式,甚至是它前面的參數。

@mixin font ($size, $weight: if($size >= 24px, 600, 400)) {
font-size: $size;
font-weight: $weight;
}
.div1 {
@include font(16px);
}
.div2 {
@include font(24px);
}

編譯後的 css :

.div1 {
font-size: 16px;
font-weight: 400;
}
.div2 {
font-size: 24px;
font-weight: 600;
}

關鍵詞傳參

默認情况下,調用 mixin 時傳遞的參數順序必須和定義時的參數一一對應。

如果傳遞參數時指定參數關鍵詞,則可以不按照定義的順序來傳參。

@mixin font ($weight, $size) {
font-size: $size;
font-weight: $weight;
}
.div1 {
@include font($size: 16px, $weight: 500);
}

編譯後的 css :

.div1 {
font-size: 16px;
font-weight: 500;
}

注意,如果要傳遞不帶關鍵詞的參數,則它必須出現在關鍵詞參數之前。

任意數量的參數

如果 mixin 的最後一個參數名以 ... 結尾,那麼這個參數就可以接收傳遞過來的任意數量的參數,這個參數的值則會是一個列錶。

@mixin order($height, $selectors...) {
@for $i from 0 to length($selectors) {
#{nth($selectors, $i + 1)} {
position: absolute;
height: $height;
margin-top: $i * $height;
}
}
}
@include order(150px, "input.name", "input.address", "input.zip");

編譯後的 css :

input.name {
position: absolute;
height: 150px;
margin-top: 0;
}
input.address {
position: absolute;
height: 150px;
margin-top: 150px;
}
input.zip {
position: absolute;
height: 150px;
margin-top: 300px;
}

帶有關鍵字的任意參數

如果調用 mixin 帶了關鍵字,那麼任意參數需要使用 meta.keywords() 來處理,處理後將返回一個 map 類型的數據。

如果沒有將任意參數傳遞給 meta.keywords() 函數,那麼這個任意參數列錶就不允許接收帶有關鍵詞的參數,編譯程序會報錯。

@use "sass:meta";
@mixin syntax-colors($args...) {
@debug meta.keywords($args);
// (string: #080, comment: #800, variable: #60b)
@each $name, $color in meta.keywords($args) {
pre span.stx-#{$name} {
color: $color;
}
}
}
@include syntax-colors(
$string: #080,
$comment: #800,
$variable: #60b,
)
pre span.stx-string {
color: #080;
}
pre span.stx-comment {
color: #800;
}
pre span.stx-variable {
color: #60b;
}

傳遞任意參數

接收的任意參數可以是一個列錶(list),那麼,也可以把一個列錶作為任意參數傳遞,同樣只需要在後面加上 ... 即可。

$font: 16px, 600, #f00;
@include font($font...);

同樣,也可以把一個 map 作為任意參數傳遞:

@mixin font ($size, $weight) {
font-size: $size;
font-weight: $weight;
}
$font: (
weight: 600,
size: 16px,
);
.div1 {
@include font($font...);
}

編譯後的 css :

.div1 {
font-size: 16px;
font-weight: 600;
}

@content 樣式塊

除了接受參數之外,mixin 還可以接受整個樣式塊,稱為內容塊。

在 mixin 中,在樣式塊中寫一個 @content 來聲明這個比特置接受一個內容塊,傳遞一個樣式塊給 mixin,這個樣式塊的內容將會用來替換 @content

@mixin font ($size, $weight) {
font-size: $size;
font-weight: $weight;
@content;
}
$font: (
weight: 600,
size: 16px,
);
.div1 {
@include font($font...) {
font-family: sans-serif;
}
}

編譯後的 css :

.div1 {
font-size: 16px;
font-weight: 600;
font-family: sans-serif;
}

可以書寫多個 @content; ,這樣將會編譯生成多個接收到的樣式塊。

傳遞的樣式塊是有作用域限制的,只能訪問樣式塊所處的比特置的變量,而不能去訪問 mixin 定義的作用域的變量。

如果要讓樣式塊使用 mixin 定義的作用域的變量,則需要通過 @content() 傳遞給樣式塊。

使用 `@content 時傳參

傳參使用 @content(arg1, arg2, ...) ,接收使用 @include <name> using ($arg1, $arg2, ...)

@mixin font ($size, $weight) {
font-size: $size;
font-weight: $weight;
@content(#f00, $size * 2);
}
$font: (
weight: 600,
size: 16px,
);
.div1 {
@include font($font...) using ($color, $margin) {
font-family: sans-serif;
color: $color;
margin: $margin;
}
}

編譯後的 css :

.div1 {
font-size: 16px;
font-weight: 600;
font-family: sans-serif;
color: #f00;
margin: 32px;
}

@content() 同樣可以傳遞 listmap 類型的參數,用法和前面一樣。

縮進語法的 mixin

縮進語法的 Sass 可以使用 = 來定義一個mixin,然後使用 + 來使用一個 mixin,但很不直觀,不建議使用。

@at-root

通常用於嵌套的選擇器中,在選擇器前寫下 @at-root 語句,用於將該選擇器編譯到樣式錶的最外層,而不是嵌套所在的比特置。

.div1 {
color: #f00;
.div2 {
color: #0f0;
// 將 .div3 編譯到最外層
@at-root .div3 {
color: #00f;
}
}
}

編譯後的 css :

.div1 {
color: #f00;
}
.div1 .div2 {
color: #0f0;
}
.div3 {
color: #00f;
}

結合 mixin 來使用:

@use "sass:selector";
@mixin unify-parent($child) {
@at-root #{selector.unify(&, $child)} {
font-size: 16px;
@content;
}
}
.wrapper .field {
@include unify-parent("input") {
color: #f00;
}
@include unify-parent("select") {
color: #0f0;
}
}

編譯後的 css :

.wrapper input.field {
font-size: 16px;
color: #f00;
}
.wrapper select.field {
font-size: 16px;
color: #0f0;
}

@at-root 還有另一種寫法 @at-root { ... }

.div1 {
font-size: 16px;
@at-root {
.div2 {
color: #f00;
}
.div3 {
color: #0f0;
}
}
}

編譯後的 css :

.div1 {
font-size: 16px;
}
.div2 {
color: #f00;
}
.div3 {
color: #0f0;
}

解决樣式之外的東西

默認情况下, @at-root 只會解决普通樣式規則, 其他像是 @media@supports 等將會被丟掉。

使用 @at-root (with: <rules...>) { ... }@at-root (without: <rules...>) 來告訴 Sass 在編譯的時候是否包括一些指定的規則。

除了合法的 @語句的名稱,如 @media 中的 media,還有兩個特殊的值可以在查詢中使用:

  • rule 指的是樣式規則。例如,@at-root (with: rule) 不保留 @ 語句,但保留樣式規則。
  • all 指所有 @語句 和 style 規則。
@media screen and (min-width: 900px) {
.page {
width: 100px;
@at-root (with: media) {
/* @at-root (with: media) */
.div1 {
font-size: 16px;
}
}
@at-root (without: media) {
.div2 {
/* @at-root (without: media) */
color: #111;
}
}
@at-root (with: rule) {
.div3 {
/* @at-root (with: rule) */
color: #111;
}
}
@at-root (without: rule) {
.div4 {
/* @at-root (without: rule) */
color: #111;
}
}
@at-root (with: all) {
.div5 {
/* @at-root (with: all) */
color: #111;
}
}
@at-root (without: all) {
.div6 {
/* @at-root (without: all) */
color: #111;
}
}
}
}

編譯後的 css :

@media screen and (min-width: 900px) {
.page {
width: 100px;
}
/* @at-root (with: media) */
.div1 {
font-size: 16px;
}
}
.page .div2 {
/* @at-root (without: media) */
color: #111;
}
.page .div3 {
/* @at-root (with: rule) */
color: #111;
}
@media screen and (min-width: 900px) {
.div4 {
/* @at-root (without: rule) */
color: #111;
}
}
@media screen and (min-width: 900px) {
.page .div5 {
/* @at-root (with: all) */
color: #111;
}
}
.div6 {
/* @at-root (without: all) */
color: #111;
}
版权声明:本文为[drylint]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918083958728p.html