Skip to content

Instantly share code, notes, and snippets.

@ja-k-e
Last active August 29, 2015 14:21
Show Gist options
  • Save ja-k-e/66a01ffc712d594fbe34 to your computer and use it in GitHub Desktop.
Save ja-k-e/66a01ffc712d594fbe34 to your computer and use it in GitHub Desktop.
Commafy Numbers in Sass

Commafy Numbers in Sass

Turns Sass integers and decimals into commafied strings for those of us that like putting CSS in the DOM. Basically, it makes a comma-separated list containing sliced sets of three numbers, converts the list to a string, and then removes spaces in the string. Would need to do a two-step replace on commas and decimals to get 1.000,20 format.

A Pen by Jake Albaugh on CodePen.

License.

// string replace method
// http://hugogiraudel.com/2014/01/13/sass-string-replacement-function/
// http://sassmeister.com/gist/1b4f2da5527830088e4d
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
// reverse a list order
// http://hugogiraudel.com/2013/08/08/advanced-sass-list-functions/
@function reverse($list, $recursive: false) {
$result: ();
@for $i from length($list)*-1 through -1 {
@if type-of(nth($list, abs($i))) == list and $recursive {
$result: append($result, reverse(nth($list, abs($i)), $recursive));
}
@else {
$result: append($result, nth($list, abs($i)), comma);
}
}
@return $result;
}
// the main commafy method
// this one is mine
@function commafy($number) {
// negative value awareness
// initially set $negative state to false
$negative: false;
// if negative number, update $negative and make $number positive
@if $number < 0 { $negative: true; $number: $number * -1; }
// decimal value awareness
// get decimal value or 0
$decimal: $number - floor($number);
// replace no decimal's 0 with nothing
@if $decimal == 0 {
$decimal: "";
// or remove initial 0 from decimal string ("0.123" => ".123")
} @else {
$decimal: str-replace(inspect($decimal),"0.", ".");
}
// round down decimal to integer for primary commafication ("123.45" => "123")
$number: floor($number);
// create an empty list to hold our temp three-int-sliced list
$temp_list: ();
// empty comma string to become returned string
$commafied_string: "";
// finally, the main course.
// convert our integer into string for manipulation
$number_str: inspect($number);
// we only need commas if the integer string length is greater than 3
// "100" = nope, "1000" = yep
@if str-length($number_str) > 3 {
// get the length of the string
// will be at least 4
$str_length: str-length($number_str);
// groups of three after potential < 3 # of chars
// "200" in "1200", "000" in "12000", "120" and "000" in "120000"
@for $i from 1 through floor($str_length / 3) {
// start_at value for slice begins third to last, not 1
$slice_start: $str_length - ($i * 3) + 1;
// end_at value for slice is two after start_at value
// slice_start + 2 = 3 numbers selected
$slice_end: $slice_start + 2;
// append our group of three integers to the temp list
$temp_list: append($temp_list, str-slice($number_str, $slice_start, $slice_end), comma);
}
// get first group of 1-2 numbers if length not an even multiple of three
// "1" in "1200", "12" in "12000", not "120" in "120000"
// if not evenly divisible by 3
@if $str_length % 3 != 0 {
// modulo remainder for initial
// 4 % 3 = 1, 5 % 3 = 2
$remaining: $str_length % 3;
// starting from the beginning of the string this time
$slice_start: 1;
// going 1 or 2 forward
// $slice_start + (0 or 1)
$slice_end: $slice_start + $remaining - 1;
// append our group or 1 or 2 numbers to the temp list
$temp_list: append($temp_list, str-slice($number_str, $slice_start, $slice_end), comma);
}
// reverse the list because our commas start from the end of the string
// at this point the list for "1000" is "000, 1"
$temp_list: reverse($temp_list);
// at this point the list for "1000" is "1, 000"
// removing spaces from list as string
// reversed list "1, 000, 000" needs to be string "1,000,000"
// converting $temp_list to string with "inspect"
// replacing with custom "str-replace" (@function above)
$commafied_string: str-replace(inspect($temp_list), " ", "");
} @else {
// the number is 0-999. no commas needed, just return the string
$commafied_string: inspect($number_str);
}
// if negative number, add minus
@if $negative == true { $commafied_string: "-" + $commafied_string; }
// return commafied string plus potential decimal string
@return $commafied_string + $decimal;
}
// number map
$numbers: (
// integers
1: 1, 2: 12, 3: 123, 4: 1234, 5: 12345,
// negative integers
6: -123456, 7: -1234567,
// decimals (Sass rounds decimals after 5 deep)
8: 1.1, 9: 10.12, 10: 100.123,
// negative decimals
11: -1000.1234, 12: -10000.12345
);
// making demo look pretty-ish. ignore below.
@import url(http://fonts.googleapis.com/css?family=Roboto+Condensed:300);
body {
background: #222;
font-family: "Roboto Condensed", sans-serif;
font-weight: 300;
}
body::before,
body::after {
display: block;
width: 50%;
min-width: 620px;
margin: 24px auto;
color: white;
text-align: center;
}
body::before {
content: "Commafy Numbers in Sass";
font-size: 2.4em;
color: #FFBB00;
}
body::after {
$string: "";
// loop over each item in $numbers add value plus new line
@for $i from 1 through length($numbers) { $string: $string + commafy(map-get($numbers,$i)) + "\a" }
content: $string;
color: #666;
white-space: pre;
font-size: 2em;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment