Sass の数値で出力されるのは小数点以下 5 桁までで、6 桁めが四捨五入される (Sass 3.2 の デフォルト設定 の場合)。つまり、0.333333...
は 0.33333
に、0.666666...
は 0.66667
に丸められる。でもたとえば 16px/12px
の結果として 1.33333
ではなく 1.34
がほしい、というような場面もある。数値を丸める関数として round()
、ceil()
、floor()
が用意されてるけど、いずれも小数部分を丸めて整数を返すもので、任意の桁を操作するということはできない。というわけで、小数点以下の桁数と丸めを制御する round-decimal()
、ceil-decimal()
、floor-decimal()
という関数を作ってみた。
// Round (四捨五入)
@function round-decimal ($number, $digits: 0) {
@return to-fixed($number, $digits, 'round');
}
// Ceil (切り上げ)
@function ceil-decimal ($number, $digits: 0) {
@return to-fixed($number, $digits, 'ceil');
}
// Floor (切り捨て)
@function floor-decimal ($number, $digits: 0) {
@return to-fixed($number, $digits, 'floor');
}
@function to-fixed ($number, $digits: 0, $round: 'round') {
$n: 1;
// $number must be a number
@if type-of($number) != number {
@warn '#{ $number } is not a number.';
@return $number;
}
// $digits must be a unitless number
@if type-of($digits) != number {
@warn '#{ $digits } is not a number.';
@return $number;
} @else if not unitless($digits) {
@warn '#{ $digits } has a unit.';
@return $number;
}
@for $i from 1 through $digits {
$n: $n * 10;
}
@if $round == 'round' {
@return round($number * $n) / $n;
} @else if $round == 'ceil' {
@return ceil($number * $n) / $n;
} @else if $round == 'floor' {
@return floor($number * $n) / $n;
} @else {
@warn '#{ $round } is undefined keyword.';
@return $number;
}
}
// round-decimal(0.333) => 0
// round-decimal(0.333, 1) => 0.3
// round-decimal(0.333, 2) => 0.33
// round-decimal(0.666) => 1
// round-decimal(0.666, 1) => 0.7
// round-decimal(0.666, 2) => 0.67
// ceil-decimal(0.333) => 1
// ceil-decimal(0.333, 1) => 0.4
// ceil-decimal(0.333, 2) => 0.34
// ceil-decimal(0.666) => 1
// ceil-decimal(0.666, 1) => 0.7
// ceil-decimal(0.666, 2) => 0.67
// floor-decimal(0.333) => 0
// floor-decimal(0.333, 1) => 0.3
// floor-decimal(0.333, 2) => 0.33
// floor-decimal(0.666) => 0
// floor-decimal(0.666, 1) => 0.6
// floor-decimal(0.666, 2) => 0.66
いずれも引数は丸めたい数値と小数点以下の桁数 (デフォルトは 0
)で、関数の実体は to-fixed()
という、JavaScript の toFixed()
をイメージした関数 (ちょっと違うけど)。たとえば ceil-decimal(0.3333, 2)
なら、
@return ceil(0.3333 * 100) / 100
ということになるので、33.33 を切り上げた整数 34 の 1/100、つまり 0.34
が返る。
Gist にも上げときました。関数名が適切かどうかの添削を誰か。
Changes
January 12, 2013 – ソースコード中、to-fixed()
関数のエラー処理と条件分岐を修正