Sass sass:math:除法、進位與單位處理
sass:math 是最常被載入的內建模組,只要專案裡有除法,就一定會用到它。
scss
@use "sass:math";math.div:正式的除法
scss
math.div(100%, 3) // 33.3333333333%
math.div(16px, 2) // 8px
math.div(16px, 16px) // 1(單位互相抵消)斜線除法已被 棄用:
scss
.a { width: $w / 2; } // ⚠️ 警告
.b { width: math.div($w, 2); } // ✅原因是斜線在 CSS 裡本來就是分隔符:
css
font: 12px/1.5 sans-serif;
grid-area: 1 / 2 / 3 / 4;Sass 無法可靠分辨你要哪一種,所以用函式明確表達。
單位會抵消
scss
math.div(16px, 16px) // 1,不帶單位
math.div(16px, 2) // 8px
math.div(2, 16px) // 0.125/px ← 很少是你想要的想保留單位就讓 除數不帶單位。相同單位相除得到純比例,這通常正是換算 rem 時要的:
scss
@function rem($px, $base: 16px) {
@return math.div($px, $base) * 1rem;
}進位與取整
scss
math.round(4.6) // 5,四捨五入
math.ceil(4.1) // 5,無條件進位
math.floor(4.9) // 4,無條件捨去
math.abs(-4px) // 4px柵格寬度取到小數點後幾位時很實用:
scss
@function round-to($n, $digits: 2) {
$factor: math.pow(10, $digits);
@return math.div(math.round($n * $factor), $factor);
}
.col { width: round-to(math.percentage(math.div(1, 3)), 4); } // 33.3333%percentage:轉百分比
scss
math.percentage(math.div(1, 3)) // 33.3333333333%
math.percentage(0.5) // 50%輸入必須不帶單位
math.percentage(16px) 會報錯。先用 math.div() 算出無單位的比例再轉。
比大小
scss
math.min(10px, 20px, 5px) // 5px
math.max(10px, 20px) // 20px
math.clamp(8px, 20px, 16px) // 16px,夾在上下限之間math.clamp 不是 CSS 的 clamp()
math.clamp() 在編譯期算出一個固定值;CSS 的 clamp() 留在樣式裡由瀏覽器依實際視窗計算。做流體字級要用後者:
scss
.hero { font-size: clamp(1.5rem, 5vw, 3rem); }單位的檢查與處理
scss
math.is-unitless(16) // true
math.is-unitless(16px) // false
math.unit(16px) // "px"
math.compatible(16px, 2em) // false,不可換算寫工具函式時用它擋掉錯誤輸入:
scss
@function rem($px, $base: 16px) {
@if math.is-unitless($px) {
$px: $px * 1px; // 允許只寫數字
}
@return math.div($px, $base) * 1rem;
}次方、平方根與常數
scss
math.pow(2, 10) // 1024
math.sqrt(16) // 4
math.hypot(3, 4) // 5
$pi: math.$pi; // 3.1415926536
$e: math.$e;模組化的字級刻度常用到次方:
scss
$ratio: 1.25;
@for $i from 1 through 5 {
.h#{$i} { font-size: math.pow($ratio, 6 - $i) * 1rem; }
}三角函式
scss
math.sin(math.$pi * 0.5) // 1
math.cos(0) // 1
math.atan2(1, 1) // 45deg環狀排列的元素、扇形選單這類版面會用到。
與 CSS calc() 的分工
sass:math | calc() | |
|---|---|---|
| 何時算 | 編譯期 | 瀏覽器執行時 |
| 混用 px 與 % | 不行 | 可以 |
| 吃得到 自訂屬性 | 不行 | 可以 |
scss
.main {
padding: math.div($gap, 2); // 編譯期
width: calc(100% - #{$gap * 2}); // 執行期
}規則見 運算子。
常見問題
為什麼除法要用 math.div 而不是斜線?
因為斜線在 CSS 裡是分隔符,出現在 font 簡寫與 grid-area 這些地方,Sass 無法判斷你要的是除法還是分隔。改用函式就沒有歧義,斜線除法已被正式棄用。
除法之後單位跑掉了怎麼辦?
兩個相同單位的數相除會互相抵消,得到不帶單位的數字,這通常正是你要的比例。想保留單位就讓除數不帶單位,例如把長度除以純數字。
怎麼把小數轉成百分比?
用 math.percentage(),它把不帶單位的數字乘以一百並加上百分號。注意輸入必須是無單位的,先用 math.div() 算出比例再轉換。
math.clamp 和 CSS 的 clamp() 一樣嗎?
不一樣。math.clamp() 在編譯期就算出一個固定值,CSS 的 clamp() 則留在樣式裡由瀏覽器依實際視窗計算。要做流體字級請用 CSS 的那個。