CSS PREprocessors

Rounding Numbers

by

Having precise numbers is crucial when working with percentage-based grid because browsers round numbers differently. If you encounter sizing issues in your grid that might be due to the low number of decimal places in the output CSS.

Round, ceil, and floor functions

The round/ceil/floor functions round a number (with or without units) to the closest/upper/lower integer.

.round-number {
  fn-round: round(1.618em);
  fn-floor: floor(1.618em);
  fn-ceil: ceil(1.618em);
}
.round-number {
  fn-round: round(1.618em);
  fn-floor: floor(1.618em);
  fn-ceil: ceil(1.618em);
}
.round-number
  fn-round: round(1.618em)
  fn-floor: floor(1.618em)
  fn-ceil: ceil(1.618em)
.round-number
  fn-round: round(1.618em)
  fn-floor: floor(1.618em)
  fn-ceil: ceil(1.618em)
.round-number {
  fn-round: resolve(round(1.618))em;
  fn-floor: resolve(floor(1.618))em;
  fn-ceil: resolve(ceil(1.618))em;
}
.round-number {
  fn-round: 2em;
  fn-floor: 1em;
  fn-ceil: 2em;
}

Custom case by case precision

Some preprocessors accept a second argument to the round function family to specify precision, Sass however, requires a custom function to achieve the same functionality (Sass snippet adapted from Hugo Giraugel's).

.precision-round {
  @number: 3.14159265359px;
  border-radius: round(@number, 1);
  border-radius: round(@number, 2);
  border-radius: round(@number, 3);
  border-radius: round(@number, 4);
}
@function pow($x, $n) {
  $ret: 1;

  @if $n >= 0 {
    @for $i from 1 through $n {
      $ret: $ret * $x;
    }
  } @else {
    @for $i from $n to 0 {
      $ret: $ret / $x;
    }
  }
  @return $ret;
}

@function precision-round($float, $digits) {
  $sass-precision: 5;

  @if $digits > $sass-precision {
    @warn "Sass sets default precision to #{$sass-precision} digits, and there is no way to change that for now."
    + "The returned number will have #{$sass-precision} digits, even if you asked for `#{$digits}`."
    + "See github.com/sass/sass/issues/1122 for further informations.";
  }

  $pow: pow(10, $digits);

  @return round($float * $pow) / $pow;
}

.precision-round {
  $number: 3.14159265359px;
  border-radius: precision-round($number, 1);
  border-radius: precision-round($number, 2);
  border-radius: precision-round($number, 3);
  border-radius: precision-round($number, 4);
}
@function pow($x, $n)
  $ret: 1

  @if $n >= 0
    @for $i from 1 through $n
      $ret: $ret * $x
  @else
    @for $i from $n to 0
      $ret: $ret / $x

  @return $ret

@function precision-round($float, $digits)
  $sass-precision: 5

  @if $digits > $sass-precision
    @warn "Sass sets default precision to #{$sass-precision} digits, and there is no way to change that for now." + "The returned number will have #{$sass-precision} digits, even if you asked for `#{$digits}`." + "See github.com/sass/sass/issues/1122 for further informations."

  $pow: pow(10, $digits)

  @return round($float * $pow) / $pow

.precision-round
  $number: 3.14159265359px
  border-radius: precision-round($number, 1)
  border-radius: precision-round($number, 2)
  border-radius: precision-round($number, 3)
  border-radius: precision-round($number, 4)
.precision-round
  $number = 3.14159265359px
  border-radius: round($number, 1)
  border-radius: round($number, 2)
  border-radius: round($number, 3)
  border-radius: round($number, 4)
.precision-round {
  $number: 3.14159265359;
  border-radius: resolve(round($number, 1))px;
  border-radius: resolve(round($number, 2))px;
  border-radius: resolve(round($number, 3))px;
  border-radius: resolve(round($number, 4))px;
}
.precision-round {
  border-radius: 3.1px;
  border-radius: 3.14px;
  border-radius: 3.142px;
  border-radius: 3.1416px;
}

Global precision after math operations

For non-integer numbers the different preprocessors put different number of digits after the decimal point (e.g. 0.33333 for Sass vs 0.333333333333333 for Stylus). Only Sass allows a custom global precision value to be set.

Global Precision
Less SCSS/Sass Stylus
Rounding precision (decimal places) 8 (1 / 3 = 0.33333333) 5 (1 / 3 = 0.33333) 15 (1 / 3 = 0.333333333333333)
Ability to set custom global precision No Yes, with the precision option No

Interactive

Leave a comment below or suggest improvements on GitHub.