Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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);
}
@zachhanding

This comment has been minimized.

Copy link

zachhanding commented Nov 20, 2015

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!

@PurpleBracket

This comment has been minimized.

Copy link

PurpleBracket commented Feb 9, 2016

I love your logic!

@stevenvachon

This comment has been minimized.

Copy link

stevenvachon commented Feb 18, 2016

Thank you.

@iRouge

This comment has been minimized.

Copy link

iRouge commented Mar 11, 2016

Thank you, I was about to build one for myself. Your saving me time.

@thomasfrobieter

This comment has been minimized.

Copy link

thomasfrobieter commented Jun 3, 2016

Thank you, great!

@jslegers

This comment has been minimized.

Copy link

jslegers commented Oct 7, 2016

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;
    }
}
@cmevawala

This comment has been minimized.

Copy link

cmevawala commented Dec 8, 2016

nice job

@Subhojit1992

This comment has been minimized.

Copy link

Subhojit1992 commented Jul 20, 2017

awesome logic @Terke.

@SassNinja

This comment has been minimized.

Copy link

SassNinja commented Apr 30, 2018

Good catch @jslegers!

Your condition is needed

@if $digits > 0 {
    @for $i from 1 through $digits {
        $n: $n * 10;
    }
}

because without it @include decimal-round(1.666, 0) returns 1.67 instead of 2.

@terkel would you mind to update the code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.