清理插值
Natalie Weizenbaum 於 2015 年 12 月 9 日發佈
插值——使用 #{...} 加入變數和其他程式碼片段的能力——是 Sass 最方便的全能功能之一。您幾乎可以在任何需要插入變數、函數呼叫或其他表達式的地方使用它。在大多數情況下,它只是將值插入到周圍的文字中。它簡單易懂,而且很有用,這正是我們想要的功能。
遺憾的是,這只在*大多數情況下*是正確的。由於複雜的歷史原因,有一個地方插值會變得有點失控:在表達式內部但引號外部。大多數情況下,這是合理的;如果您寫 display: -#{$prefix}-box,您將得到預期的結果。但是,如果在插值旁邊使用了任何運算符(例如 +),您就會開始得到奇怪的輸出。例如,$name + #{$counter + 1} 可能會返回一個包含文字 name + 3 的未加引號的字串。
這是一個非常奇怪的行為。為什麼 + 在這裡的行為與在其他地方不同?為什麼當 $name 正常求值時,它會被視為純文字?這種行為令人困惑、不一致,而且不是特別有用,這*非常不*是我們想要的功能特性。那麼它們一開始為什麼會存在呢?
複雜的歷史原因複雜的歷史原因 的永久連結
如果您不關心歷史課,請跳到美麗新世界。
在很久很久以前,當縮排語法是唯一的語法時,Sass 區分了「靜態」和「動態」屬性。靜態屬性基本上是純粹的 CSS;它是使用 property: value 宣告的,並且該值按原樣使用,無需任何進一步處理。如果您想使用變數或函數,則必須使用動態屬性,該屬性使用 property= value 宣告。您會看到很多像這樣的樣式表
.border
border-width: 4px
border-style: solid
border-color= !background_color
此外,在很久以前,變數使用 ! 而不是 $,並且不能包含連字號。那個時代有點糟糕。但正是在這種情況下,我們第一次添加了插值。我們希望允許具有多個值的屬性(例如 border)部分動態化,因此我們決定效仿 Ruby 的做法,允許使用 #{} 來插入值。很快,樣式表開始變成這樣
.border
border: 4px solid #{!background_color}
這樣好多了!有一段時間,一切都風平浪靜。
然後 SCSS 出現了然後 SCSS 出現了的永久連結
最終,很明顯,使用者非常希望他們的樣式表看起來像 CSS,因此我們坐下來開始研究在 Sass 3 中成為 SCSS 的語法。作為這項工作的一部分,我們決定完全取消靜態和動態屬性之間的區別。讓所有屬性以相同的方式工作顯然對使用者來說非常棒,但這意味著我們必須想辦法以最小的痛苦來合併兩種語法。
這項工作大部分都很直接,因為舊的表達式語法幾乎都是無效的 CSS 或最終會輸出 CSS 值的內容。但插值語法卻很棘手。向後相容性對我們來說非常重要,所以我們希望確保所有在 Sass 2 中使用插值語法的地方,或者 *理論上可以使用* 的地方,都能在 Sass 3 中繼續運作,即使它們周圍的程式碼現在都已經被完整 解析。
我們的解決方案是將 #{} 周圍基本上任何不顯然屬於純 CSS 表達式的東西都轉換成字串。這樣一來,希望人們遇到的任何奇怪的邊緣情況都能在升級後繼續運作。這導致了我上面描述的奇怪行為,但在當時,我們的首要任務是讓使用者盡可能輕鬆地遷移到 Sass 3。我們認為這種奇怪的行為是值得的,於是就發布 了。
美麗新世界美麗新世界 永久連結
時光飛逝,來到今天。我們現在開始著手開發下一個主要版本 Sass 4,而且(我衷心希望)多年來沒有人再寫過 Sass 2 的樣式表了。主要版本發布是清理這些歷史遺留問題的大好機會,在 問題追蹤器上廣泛討論 後,我們決定做出 改變。
像這樣破壞向後相容性的變更主要有三個步驟。第一步是設計新的語法,這在這裡相當容易,因為基本上就是「按照大家原本以為的運作方式去做」。我們只需要把這個一般概念具體 化。
我們最終將 #{} 的語法框架定義為識別碼的一部分。當您撰寫 -#{$prefix}-box 時,Sass 會將其解析為一個單一識別碼,包含 "-",後接 $prefix 的值,再接 "-box"。即使您單獨撰寫 #{$font},它也會被解析為僅包含 $font 值的識別碼。這樣一來,插值語法在運算子周圍就不會有比識別碼本身更奇怪的 行為。
一旦我們有了設計,第二步就是棄用舊的行為。棄用的核心是找出何時顯示警告,這在這裡相當困難。我們不希望在即使涉及運算子也能繼續運作的情況下發出警告,例如,12px/#{$line-height} 在新舊版本中都會顯示正確的結果(雖然原因略有不同),但 12px+#{$line-height} 則 不會。
我不會詳述我們是如何讓棄用功能在此運作的;這就是 GitHub 問題 的作用。只能說它涉及許多特殊情況,包括一些根據值的 *使用方式* 而不是 *撰寫方式* 來顯示棄用警告的情況。不過,我對最終的結果相當滿意;我認為它會捕捉到實際應用中 99% 會 出錯的情況。
另一個令人興奮的額外好處是能夠自動更新程式碼。在引入破壞向後相容性的變更時,這並非總是有效,但在這種情況下,我們能夠讓 sass-convert 將已棄用的插值語法用法轉換為 Sass 4 相容的程式碼。它有一些偽陰性結果——它只會轉換它可以證明不相容的情況——但這足以讓使用者大幅 前進。
一旦棄用設定完成,最後一步就是移至main 分支(最終將成為 Sass 4),移除所有舊行為,並實作新的行為。而這真是太棒了。刪除糟糕的程式碼並用乾淨的程式碼取代,就像在大太陽底下徒步穿越塵土一天後沖個澡一樣。在這個功能上工作了數週後,我很高興看到它的另一端。
查看查看永久連結
今天發佈的 Sass 3.4.20 是第一個包含舊語法棄用警告的版本。如果您想檢查樣式表中是否有任何已棄用的插值潛伏其中,只需執行 gem install sass 並重新編譯您的樣式表。如果您確實找到了一些,請嘗試執行 sass-convert --recursive --in-place . 自動修復一大堆。
如果您想試用新語法,今天也發佈了 4.0.0.alpha.1。您可以使用 gem install sass --prerelease 取得它。但請注意:它是 alpha 軟體,因此未來可能會有所變動。我們通常會盡力保持我們的預發佈版本相當穩定,但也可能會遇到錯誤。
如果您確實發現了錯誤,請在問題追蹤器上提交。即使只是像錯字這樣的小問題,我們也想知道。如果我們棄用了某些應該有效的東西,我們尤其想知道。如果您有任何問題,請隨時在@SassCSS 發推文或在郵件論壇上發佈。