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.
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.
SASS allows for mathematical operations such as addition, subtraction, multiplication and division.
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.
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.
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)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With