--- tags: Sass --- # Sass筆記 ![](https://i.imgur.com/Nszdw61.png) :::spoiler 文章目錄 [toc] ::: ## 介紹 * `Sass` 是 `CSS` 預處理器`(CSS Preprocessor)`的一種 > 預處理器是讓開發者撰寫一些類似 `CSS` 語法的指令,再轉為瀏覽器能懂的 `CSS` * `SASS / SCSS` 檔案需編譯為 `CSS` 檔 * `Sass` 支持所有現代瀏覽器,並且與 `CSS3` 兼容。 * 節省許多時間,因為減少了 `CSS` 的重複 ## SASS vs. SCSS `Sass` 和 `SCSS` 是兩種不同的 `Sass` 語法格式 ### SCSS(Sassy CSS) 使用`.scss`文件擴展名稱,使用常規的 `CSS` 語法和大括號來結構化代碼,需加上 `{}` `;`。 ```sass= /* .scss file */ $bgcolor: blue; /* use variables */ body { background-color: $bgcolor; } .container { width: 100%; } ``` ### SASS(Indented Sass) 使用`.sass`文件擴展名稱,使用縮排而不是括號,取消`{}` `;`,它不完全符合 `CSS` 語法,但編寫起來更快。 :::warning 此寫法請注意縮排 ::: ```sass= /* .sass file */ $bgcolor: blue body background-color: $bgcolor .container width: 100% ``` ### css output 以上兩種寫法皆輸出 ```css= /* .css file */ body { background-color: blue; } .container { width: 100%; } ``` ## 變數`Variables` `Sass` 允許使用者宣告變數並賦值,這些變數可以在樣式表中重複使用,方便開發者管理和維護樣式。 Sass ```sass= $deefBlue: #032f3e #main-nav{ background: $deefBlue; } ``` Css ```css= #main-nav{ background: #032f3e; } ``` ## 巢狀寫法`Nesting Styles` `Sass` 支持將樣式規則嵌套,這使得開發者可以更加清晰地了解樣式規則的關係,同時也能減少重複代碼的量。 Sass ```sass= #main-nav{ ul{ width: 100%; } } ``` Css ```css= #main-nav ul{ width: 100%; } ``` ## @Mixins 和 @Include `Sass` 提供了 `Mixin` 的功能,這可以讓開發者定義可重複使用的樣式片段,以減少代碼的重複性。 1. 用`@mixin`定義 1. 用`@include`使用 ```sass= // create mixin @mixin banner{ width: 100%; position: relative; color: white; .banner-content{ position: absolute; } } // use mixin .lead-banner{ @include banner; } ``` ## @content `@content` 是 `Sass` 中的一個關鍵字,用於在 `@mixin` 或 `@function` 規則中引入外部內容。具體來說,`@content` 可以在 `@mixin` 或 `@function` 中的某個位置插入外部代碼塊,以生成動態的 `CSS`。 ### 範例 在這個例子中,我們定義了一個`@mixin media()`,它根據輸入的裝置類型,定義對應的 `CSS` 裝置查詢。然後在每個 `@media` 區塊中,使用 `@content` 區塊引入 `@mixin` 被調用時的內容。 ```sass= @mixin media($media) { @if $media == 'tablet' { @media (min-width: 768px) and (max-width: 991px) { @content; } } @else if $media == 'desktop' { @media (min-width: 992px) { @content; } } } .element { width: 100px; @include media('tablet') { width: 50%; } @include media('desktop') { width: 75%; } } ``` 在編譯後的 `CSS` 中,可以看到 `Sass` 的 `@content` 區塊被嵌入到對應的 `@media` 區塊中,並且在不同的裝置查詢下,`.element` 元素的寬度被設定為不同的值。 ```css= .element { width: 100px; } @media (min-width: 768px) and (max-width: 991px) { .element { width: 50%; } } @media (min-width: 992px) { .element { width: 75%; } } ``` ## 匯入檔案`Import File` 導入其他`Sass`檔案 `/scss/variables.scss` ```sass= $deefBlue: #032f3e $deefRed: #960000 ``` `/scss/style.scss` ```sass= @import 'variables'; ``` ## @use 與 `@import` 指令相比,`@use` 指令更加優秀,因為它可以避免代碼重複和命名衝突。 :::info 以這種方式加載的任何樣式都將在編譯的CSS輸出中只包含一次,無論這些樣式被加載了多少次 ::: ### 基本範例 默認情況下,模塊的命名空間就是你導入的檔案名稱,沒有文件擴展名稱。 Sass ```sass= // src/_corners.scss $radius: 3px; @mixin rounded { border-radius: $radius; } // style.scss @use "src/corners"; .button { @include corners.rounded; padding: 5px + corners.$radius; } ``` css ```css= .button { border-radius: 3px; padding: 8px; } ``` ### 加上命名空間 你可能想要選擇一個不同的命名空間,可能原先名稱太長,想要使用一個較短的名稱 Sass ```sass= // src/_corners.scss $radius: 3px; @mixin rounded { border-radius: $radius; } // style.scss @use "src/corners" as c; .button { @include c.rounded; padding: 5px + c.$radius; } ``` css ```css= .button { border-radius: 3px; padding: 8px; } ``` 甚至可以加載沒有命名空間的模塊 `@use "<url>" as *`。不過,我們建議您只對您編寫的樣式表執行此操作,否則,導入的新成員可能會與原先樣式名稱相同,導致衝突。 Sass ```sass= // src/_corners.scss $radius: 3px; @mixin rounded { border-radius: $radius; } // style.scss @use "src/corners" as *; .button { @include rounded; padding: 5px + $radius; } ``` css ```css= .button { border-radius: 3px; padding: 8px; } ``` ### 私有成員 你可能不希望你定義的所有變數都可以在 `scss` 之外使用,只要在變數的前面加上 `-` 或 `_`前綴,來讓它們變成私有成員。 以下範例會報錯 ```sass= // src/_corners.scss $_radius: 3px; @mixin rounded { border-radius: $_radius; } // style.scss @use "src/corners" as c; // This is an error! $_radius isn't visible outside of `_corners.scss`. .button { @include c.rounded; padding: 5px + c.$_radius; // error } ``` ## @forward 當必須在多個 `scss` 中重複使用一組樣式表時,我們可以將所有樣式表合併到一個入口點,使用 `@forward` 並在其他 `scss` 中 `@use` 在使用。 以下是一個使用 `@forward` 的 `Sass` 範例: ```sass= // src/_list.scss @mixin list-reset { margin: 0; padding: 0; list-style: none; } // bootstrap.scss @forward "src/list"; // styles.scss @use "bootstrap"; li { @include bootstrap.list-reset; } ``` css ```sass= li { margin: 0; padding: 0; list-style: none; } ``` ## 運算 `Sass` 允許使用者在樣式表中進行算數運算、邏輯運算和字串操作等運算。 ### 算術運算 在下面範例中,我們使用了算術運算符號 `/` 來計算 `$margin` 的值,這個值將用於設定 `.element` 元素的 `margin-left` 屬性。 Sass ```sass= $width: 300px; $padding: 20px; $margin: $width / 2 - $padding; .element { width: $width; padding: $padding; margin-left: $margin; } ``` css ```css= .element { width: 300px; padding: 20px; margin-left: 130px; } ``` ### 比較運算 在下面範例中,我們使用了比較運算符號 `==` 來比較 `$primary-color` 和 `$secondary-color` 的值是否相等。如果相等,就設定文字顏色為紅色,否則設定為藍色。 Sass ```sass= $primary-color: #007bff; $secondary-color: #6c757d; .element { color: if($primary-color == $secondary-color, #ff0000, #0000ff); } ``` css ```css= .element { color: #0000ff; } ``` ### 字符串運算 在下面範例中,我們使用了字符串運算符號 `+` 來結合多個字符串,同時也使用了 `unquote()` 函數將引號添加到字串周圍,以保持 `CSS` 規則的正確性 Sass ```sass= $font-family: Helvetica Neue, Helvetica, Arial, sans-serif; .element { font-family: unquote('"') + $font-family + unquote('"'); } ``` css ```css= .element { font-family: "Helvetica Neue, Helvetica, Arial, sans-serif"; } ``` ## 函數 `Sass` 允許使用者定義和調用函數,這可以簡化樣式表的編寫,使其更加靈活和易於維護。 ### 自定義函數 使用`@function`定義函數並使用`@return`回傳 在這個例子中,我們使用了 `Sass` 的 `@function` 規則定義一個函數 `calculate-rem()`,該函數將像素值轉換為 `rem` 單位。然後我們使用這個函數將 .`element` 元素的 `font-size` 屬性設定為 `1.5rem`。 Sass ```sass= @function calculate-rem($size) { @return $size / 16px; } .element { font-size: calculate-rem(24px) + rem; } ``` css ```css= .element { font-size: 1.5rem; } ``` ### 內建函數 [更多模塊請參考Sass Built-In Modules](https://sass-lang.com/documentation/modules) #### darken() 函數 在這個例子中,我們使用了 `Sass` 內置的 `darken()` 函數,將 `$primary-color` 變暗 20%,並將結果應用到 `.element` 元素的 `color` 屬性中。 Sass ```sass= $primary-color: #007bff; .element { color: darken($primary-color, 20%); } ``` css ```css= .element { color: #004a99; } ``` #### lighten() 函數 在這個例子中,我們使用了 `Sass` 內置的 `lighten()` 函數,將 `$secondary-color` 變亮 `15%`,並將結果應用到 `.element` 元素的 `background-color` 屬性中。 ```sass= $secondary-color: #6c757d; .element { background-color: lighten($secondary-color, 15%); } ``` css ```css= .element { background-color: #939ba2; } ``` #### if() 函數 在這個例子中,我們使用了 `Sass` 內置的 `if()` 函數,根據 `$screen-size` 的值,將 `.element` 元素的 `width` 屬性設定為 `100%` 或 `50%`。 Sass ```sass= $screen-size: 768px; .element { width: if($screen-size >= 768px, 100%, 50%); } ``` css ```css= .element { width: 100%; } ``` ## 繼承 `Sass` 允許使用者通過 `@extend` 指令實現樣式規則的繼承,這可以讓代碼更加簡潔和易於維護。 以下為 `Sass` 中使用繼承的範例: 在這個範例中,我們定義了一個 `%button` 的 `placeholder` 選擇器,用於保存一些通用的按鈕樣式。然後在 `.button-primary` 和 `.button-danger` 類別中,使用 `@extend` 關鍵字繼承 `%button` 選擇器的樣式,並且覆蓋 `background-color` 屬性,以實現不同類型的按鈕樣式。 ```sass= %button { display: inline-block; padding: 10px 20px; font-size: 16px; color: #fff; background-color: #333; border: none; border-radius: 5px; text-decoration: none; cursor: pointer; } .button-primary { @extend %button; background-color: #007bff; } .button-danger { @extend %button; background-color: #dc3545; } ``` 編譯後的 `CSS` 代碼如下: 可以看到,編譯後的 `CSS` 中,`.button-primary` 和 `.button-danger` 類別都繼承了 `%button` 選擇器的樣式,同時根據自己的需要修改了 b`ackground-color` 屬性的值,實現了不同類型的按鈕樣式。這樣,我們就可以通過 `Sass` 的繼承機制,實現代碼的重用和簡化。 ```css= .button-primary, .button-danger { display: inline-block; padding: 10px 20px; font-size: 16px; color: #fff; background-color: #333; border: none; border-radius: 5px; text-decoration: none; cursor: pointer; } .button-primary { background-color: #007bff; } .button-danger { background-color: #dc3545; } ``` ## @debug查看變量或表達式的值 在 `Sass` 中,`@debug` 是一個用於輸出調試信息的指令。它可以將一些調試信息輸出到控制台,方便開發人員進行調試和錯誤排查。 查看以下範例,當編譯 `Sass` 代碼時,這三個調試信息將被輸出到控制台。 :::warning 使用 `@debug` 時需要注意,只有在開發過程中才應該使用它,不應該在生產環境中使用。因為它會將調試信息輸出到控制台,影響代碼的執行效率。 ::: ```sass= $font-size: 16px; $line-height: 1.5; $font-color: #333; body { font-size: $font-size; line-height: $line-height; color: $font-color; @debug "Font size: #{$font-size}"; @debug "Line height: #{$line-height}"; @debug "Font color: #{$font-color}"; } ``` ## @error錯誤排查 在 `Sass` 中,`@error` 是一個用於輸出錯誤信息的指令。當 `Sass` 遇到某些錯誤時,可以使用 `@error` 指令輸出錯誤信息,一旦錯誤被打印出來,`Sass` 就停止編譯樣式表並告訴任何正在運行它的系統發生了錯誤。 在這個範例中,當 `Sass` 編譯這個代碼時,如果 `$font-size` 的值小於 `12px`,就會觸發 `@error`,輸出一條錯誤信息到控制台,並且終止 `Sass` 編譯。這可以幫助開發人員快速發現代碼中的錯誤。 :::spoiler 詳細資訊 :::info 在實際開發中,建議在 `@if` 或 `@each` 等指令中使用 `@error`,以及在代碼庫或模塊中定義一些較為嚴格的規則,以提高代碼的可讀性和可維護性。 ::: ```sass= $font-size: 16px; body { @if $font-size < 12px { @error "The font size is too small!"; } font-size: $font-size; } ``` ## 學習資源 [Learn Sass | Codecademy](https://www.codecademy.com/learn/learn-sass) [Sass Tutorial - W3Schools](https://www.w3schools.com/sass/) [官網](https://sass-lang.com/)