Rounding decimals in Sass
// _decimal.scss | MIT License | gist.github.com/terkel/4373420 | |
// Round a number to specified digits. | |
// | |
// @param {Number} $number A number to round | |
// @param {Number} [$digits:0] Digits to output | |
// @param {String} [$mode:round] (round|ceil|floor) How to round a number | |
// @return {Number} A rounded number | |
// @example | |
// decimal-round(0.333) => 0 | |
// decimal-round(0.333, 1) => 0.3 | |
// decimal-round(0.333, 2) => 0.33 | |
// decimal-round(0.666) => 1 | |
// decimal-round(0.666, 1) => 0.7 | |
// decimal-round(0.666, 2) => 0.67 | |
// | |
@function decimal-round ($number, $digits: 0, $mode: 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 $mode == round { | |
@return round($number * $n) / $n; | |
} @else if $mode == ceil { | |
@return ceil($number * $n) / $n; | |
} @else if $mode == floor { | |
@return floor($number * $n) / $n; | |
} @else { | |
@warn '#{ $mode } is undefined keyword.'; | |
@return $number; | |
} | |
} | |
// Ceil a number to specified digits. | |
// | |
// @param {Number} $number A number to round | |
// @param {Number} [$digits:0] Digits to output | |
// @return {Number} A ceiled number | |
// @example | |
// decimal-ceil(0.333) => 1 | |
// decimal-ceil(0.333, 1) => 0.4 | |
// decimal-ceil(0.333, 2) => 0.34 | |
// decimal-ceil(0.666) => 1 | |
// decimal-ceil(0.666, 1) => 0.7 | |
// decimal-ceil(0.666, 2) => 0.67 | |
// | |
@function decimal-ceil ($number, $digits: 0) { | |
@return decimal-round($number, $digits, ceil); | |
} | |
// Floor a number to specified digits. | |
// | |
// @param {Number} $number A number to round | |
// @param {Number} [$digits:0] Digits to output | |
// @return {Number} A floored number | |
// @example | |
// decimal-floor(0.333) => 0 | |
// decimal-floor(0.333, 1) => 0.3 | |
// decimal-floor(0.333, 2) => 0.33 | |
// decimal-floor(0.666) => 0 | |
// decimal-floor(0.666, 1) => 0.6 | |
// decimal-floor(0.666, 2) => 0.66 | |
// | |
@function decimal-floor ($number, $digits: 0) { | |
@return decimal-round($number, $digits, floor); | |
} |
This comment has been minimized.
This comment has been minimized.
I love your logic! |
This comment has been minimized.
This comment has been minimized.
Thank you. |
This comment has been minimized.
This comment has been minimized.
Thank you, I was about to build one for myself. Your saving me time. |
This comment has been minimized.
This comment has been minimized.
Thank you, great! |
This comment has been minimized.
This comment has been minimized.
If you want 0 digits, it rounds to 2 digits instead. Here's a fix : @function decimal-round ($number, $digits: 0, $mode: 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;
}
@if $digits > 0 {
@for $i from 1 through $digits {
$n: $n * 10;
}
}
@if $mode == round {
@return round($number * $n) / $n;
} @else if $mode == ceil {
@return ceil($number * $n) / $n;
} @else if $mode == floor {
@return floor($number * $n) / $n;
} @else {
@warn '#{ $mode } is undefined keyword.';
@return $number;
}
} |
This comment has been minimized.
This comment has been minimized.
nice job |
This comment has been minimized.
This comment has been minimized.
awesome logic @Terke. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Great implementation @terkel! Here is a more concise implementation that I use in my own projects: @function pow ($value, $pow: 1) {
@return if($pow == 0, 1, $value * pow($value, $pow - 1));
}
@function rounded ($value, $precision: 1) {
$pow10: pow(10, $precision);
@return round($value * $pow10) / $pow10;
}
:root {
--round-width: #{round(200% / 3)}; // 67%
--rounded-width: #{rounded(200% / 3, 6)}; // 66.666667%
}
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Needed a way to floor percentages to specified decimal places instead of just down to the whole number, and this did exactly that for me. Thanks!