Working With Numbers In Sass

You work with numbers all the time in CSS. 16px. 50%. 0.875em. Unfortunately CSS doesn’t give you a lot of options for manipulating them. There is the calc() function that offers some basic math, but it is limited in what it can do. Sass, on the other hand, offers more ways to work with the number data type.

Numbers
Last week I started a new series about Sass. This one will look at data types, their operators, and additional functions for working with them. I presented an overview and quickly mentioned nulls and booleans. I want to start digging into the rest of the data types, starting today with numbers.

Numbers in Sass

Sass supports both integer and decimal numbers, with and without units. So 10 and 10.5 are valid Sass numbers as are 10px and 10em.

Sass supports the standard arithmetic operators that I’m sure your familiar with. You can add ( + ), subtract ( – ), multiply ( * ), and divide ( / ) numbers as well as calculate a modulus ( % ).

1
2
3
4
5
6
7
8
9
10
11
12
$width: 100%;

h1 {  
 font-size: 16px * 2;  
 margin: 24px - 8px  
} 

.column {  
 width: $width / 3;  
 height: 200px + 500px;  
 border-width: 15 % 2;  
}

The Sass above compiles to:

1
2
3
4
5
6
7
8
9
10
h1 {  
  font-size: 32px;  
  margin: 16px;  
}

.column {  
  width: 33.3333333333%;  
  height: 700px;  
  border-width: 1;  
}

When units are present, Sass preserves the units, which means number operations will only work when the units are the same (or not present). You can add 10px to 20px in Sass, but you can’t add 10px to 3em.

If two numbers with the same units are multiplied the result is square units

1
10px * 10px = 100px squared

Unfortunately squared units aren’t valid CSS so the above leads to an error. Make sure the math you’re doing makes sense in CSS, since that’s where your result will ultimately live.

Comparison Operators

In addition to the equals ( == ) and not equals ( != ) equality operators, Sass supports the relational operators; greater than ( > ), greater than or equals ( >= ), less than ( < ), and less than or equals ( <= ).

I’m guessing I don’t need to spend too much time covering comparison operators, but here are a few examples.

1
2
3
4
5
6
5 == 3     // evaluates to false  
5 != 3     // evaluates to true  
5 > 3   // evaluates to true  
5 >= 3  // evaluates to true  
5 < 3   // evaluates to false  
5 <= 3  // evaluates to false

Comparison operators are mainly used in control directives inside mixins and functions. I’ll talk more about control directives and writing custom functions at the end of this series.

Sass Division

Because CSS allows the / character as a separator (font: 16px/24px for font-size/line-height for example), Sass must also support the character as a separator. That’s how Sass will treat a / by default, however there are three cases where it will be interpreted as division.

  1. If the value, or any part of it, is stored in a variable or returned by a function.
  2. If the value is surrounded by parentheses.
  3. If the value is used as part of another arithmetic expression.
1
2
3
4
5
6
7
8
9
$width: 960px;

p{
 font: 16px/24px;
 width: $width/3;
 padding: round(23.8px)/3;
 height: (800px/2);
 margin: 9px + 6px/2px;
}

compiles to

1
2
3
4
5
6
7
p {  
  font: 16px/24px;  
  width: 320px;  
  padding: 8px  
  height: 400px;  
  margin: 12px;  
}

Interpolation

Sometimes the default variable behavior isn’t what you want. For example you might store font-size and line-height as variables, but later want to use both as plain CSS on the font property as in font-size/line-height.

When this happens you can make use of interpolation ( #{} ), which I talked about in an earlier article about variables.

1
2
3
4
5
6
$font-size: 16px;  
$line-height: 24px;

p {  
  font: #{$font-size}/#{$line-height};  
}

which compiles to:

1
2
3
p {  
  font: 16px/24px;  
}

instead of applying division and resulting in:

1
2
3
p {  
  font: 0.667px;  
}

Parenthesis

As I mentioned last week parentheses can be used to affect the order of operations:

1
2
3
p {  
 width: 10px + (2px * 3);  
}

compiles to

1
2
3
p {  
 width: 16px;  
}

while

1
2
3
p {  
 width: (10px + 2px) * 3;  
}

compiles to

1
2
3
p {  
 width: 36px;  
}

Number Functions

Sass has eight built-in functions for working with numbers. My guess is you can figure out what each one does and how to use it without me, but I’ll give you a quick definition and example for each just in case.

percentage($number) turns a unitless number into a percentage. Here I’m using it to set the width of a column using a variable.

1
2
$columns = 3;  
.col-width { width: percentage(1/$columns); }

I divided the number 1 by the variable $columns in which result in a number between 0 and 1.0. The function multiplies this result by 100 to get the percentage.

The Sass compiles to the following CSS.

1
.col-width { width: 33.3333333333%; }

round($number) rounds a number to the nearest whole number. You can include units with the number if you’d like.

1
2
3
4
5
6
7
p {  
 font-size: round(18.2px);  
}

h2 {  
 font-size: round(1.8em)  
}

which compiles to:

1
2
3
4
5
6
7
p {  
 font-size: 18px;  
}

h1 {  
 font-size: 2em;  
}

If you specifically want to round up or down you can use either ceil($number), which always rounds up or floor($number), which always rounds down.

1
2
3
4
5
6
7
p {  
 font-size: ceil(18.2px);  
}

h2 {  
 font-size: floor(1.8em)  
}

which compiles to:

1
2
3
4
5
6
7
p {  
 font-size: 19px;  
}

h1 {  
 font-size: 1em;  
}

If you need the absolute value of a number you can use abs($number), which as you would expect, returns the absolute value of the number.

1
2
3
4
$gutter: -10px;  
.gutter {  
 width: abs($gutter);  
}

compiles to:

1
2
3
.gutter {  
 width: 10px;  
}

Sass includes two functions to determine the minimum or maximum from a series of numbers, min($numbers…) or max($numbers…). I trust you can figure out which one finds the minimum and which one finds the maximum.

You can use unitless numbers or you can include units as long as all the units being compared are the same.

1
2
3
4
5
6
7
p {  
 font-size: min(18px, 24px, 16px);  
}

h1 {  
 font-size: max(18px, 24px, 16px);  
}

which compiles to:

1
2
3
4
5
6
7
p {  
 font-size: 16px;  
}

h1 {  
 font-size: 24px;  
}

Finally there’s the function random([$limit]), which returns a random number. The $limit is optional. If not included the function will return a number between 0.0 and 1.0. If you include an integer limit, the function returns an integer between 1 and the integer limit you set.

1
2
3
4
5
6
7
p {  
 font-size: random() + px;  
}

h1 {  
 font-size: random(24) + px;  
}

Since the function returns a random or semi-random number, the code above compiles differently with each compile. Here’s one possible result that I received on compiling my Sass.

1
2
3
4
5
6
7
p {  
  font-size: 0.1465153965px;  
}

h1 {  
 font-size: 9px;  
}

You probably noticed in this example that I added px after the random() function. That’s concatenation, but it’s a subject for the next data type, strings.

Closing Thoughts

If you’ve worked with programming languages before, I assume this was a very simple review for working with numbers. If you haven’t done any programming before, I hope you can see that Sass makes it easy to manipulate numbers and it gives you more options to manipulate them than you get with CSS alone.

I find operating on numbers or generating results from the number functions comes in handy at times, especially when you want to maintain proportions in a responsive design. They can save you from having to perform the math involved in dividing one variable by another and when calculating how many pixels a gutter should be when the layout resizes.

And sometimes it just makes your code more understandable to see the numbers in the calculation rather than the result.

Next week I’ll continue with a look at the string data type along with the operators and functions Sass provides for working with them.

Download a free sample from my book, Design Fundamentals.

Leave a Reply

Your email address will not be published. Required fields are marked *