Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doing math on variable argument Sass mixins

Tags:

css

sass

mixins

I like to use rem units with pixel fallbacks for my CSS sizing and am trying to make mixins to help with that. For font-size, this is easy:

@mixin font-size($size) {   font-size: $size + px;   font-size: ($size / 10) + rem; } 

But for padding, margin, etc. the mixin needs to accept variable arguments, which is possible per the Sass documentation http://sass-lang.com/documentation/file.SASS_REFERENCE.html#variable_arguments

However, with the following mixin, instead of dividing by 10, the mixin is just adding a slash between the numbers. That is, this:

@mixin padding($padding...) {     padding: $padding + px;     padding: ($padding / 10) + rem; } .class {     @include padding(24); } 

Outputs this:

.class {     padding: 24px;     padding: 24/10rem; } 

Instead of this, like I would expect:

.class {     padding: 24px;     padding: 2.4rem; } 

Is there a way to make sure Sass recognizes the variables as numbers and thus uses the division operator on them correctly?

Also, after testing this more, I realized the concatenation only takes place on the last variable.

like image 815
Doug Hamlin Avatar asked Oct 17 '13 02:10

Doug Hamlin


People also ask

How do you pass variables in mixin SCSS?

Variable argument is used to pass any number of arguments to mixin. It contains keyword arguments passed to the function or mixin. Keyword arguments passed to the mixin can be accessed using keywords($args) function which return values mapped to String.

Can you do math in Sass?

SASS allows for mathematical operations such as addition, subtraction, multiplication and division.

Which arguments are used to include arguments in the mixins in Sass?

The keyword arguments are used to include in mixins. It specifies that the named arguments can be passed in any order and the default value of arguments can be omitted.

What is the difference between mixin and variable?

I have been doing some googling and I currently understand the difference being that a variable stores a single line of information whereas, a mixin stores multiple lines of variables.


2 Answers

Try this:

padding: #{$padding / 10}rem; 

Concatenating in SASS/SCSS uses ruby syntax, and you were mixing a mathematical equation followed by a concatenation, which is a variable type mix, so it's not suprising to me that it didn't work.

Expressions and variables included within #{here} are assesed as if seperate to the rest of the line, and thus don't typecast the rest of the line. Also comes in handy if your output is getting quoted when you didn't expect (as does the unquote() function)

like image 168
Owen C. Jones Avatar answered Sep 21 '22 15:09

Owen C. Jones


It seems what I really needed to use here was a list rather than a variable argument in order to manipulate each value separately.

I first tried doing this with the @each directive, but couldn't figure out how to use it inside a declaration. This throws an error:

@mixin padding($padding) {    padding: @each $value in $padding { $value + px };    padding: @each $value in $padding { ($value / 10) + rem }; } 

So I ended up writing something much more verbose that handles each of the four possible cases separately (i.e. you pass 1, 2, 3 or 4 arguments). That looks like this and works as I wanted:

@mixin padding($padding) {     @if length($padding) == 1 {         padding: $padding+px;         padding: $padding/10+rem;     }     @if length($padding) == 2 {         padding: nth($padding, 1)+px nth($padding, 2)+px;         padding: nth($padding, 1)*0.1+rem nth($padding, 2)*0.1+rem;     }     @if length($padding) == 3 {         padding: nth($padding, 1)+px nth($padding, 2)+px nth($padding, 3)+px;         padding: nth($padding, 1)*0.1+rem nth($padding, 2)*0.1+rem nth($padding, 3)*0.1+rem;     }     @if length($padding) == 4 {         padding: nth($padding, 1)+px nth($padding, 2)+px nth($padding, 3)+px nth($padding, 4)+px;         padding: nth($padding, 1)*0.1+rem nth($padding, 2)*0.1+rem nth($padding, 3)*0.1+rem nth($padding, 4)*0.1+rem;     } } 

I made collection of rem mixins including this one as a Gist here https://gist.github.com/doughamlin/7103259

like image 34
Doug Hamlin Avatar answered Sep 20 '22 15:09

Doug Hamlin