Pass Function or Mixin by Reference in SASS

Pass function or mixin by reference in SASS

Functions and mixins are not first-class in Sass, meaning you can't pass them around as arguments like you can with variables.

Sass 3.2 and older

The closest you can get is with the @content directive (Sass 3.2+).

@mixin foo {
a {
@content;
}
}

@include bob {
b: foo(c); // this replaces `@content` in the foo mixin
}

The only caveat is that the @content can't see what's inside your mixin. In other words, if c was only defined inside the bob mixin, it essentially wouldn't exist because it isn't considered in scope.

Sass 3.3 and newer

Starting with 3.3, you can use the call() function, but it is only for use with functions, not mixins. This requires passing string containing the name of the function as the first argument.

@function foo($value) {
@return $value;
}

@mixin bob($fn: null) {
a {
b: call($fn, c);
}
}

@include bob('foo');

Unable to pass function as argument to a mixin

Functions and mixins are not first-class in Sass, meaning they cannot be passed as arguments to other functions or mixins.

In Sass 3.3, there is a new function called call() which will give you the behavior you're looking for:

@mixin hover($action, $color, $amount) {
color: call($action, $color, $amount);
}

How can I pass a tag in as a scss mixin argument?

@mixin themeParent ($child) {
&--blue #{$child} {
color: blue;
}
}

outputs: .section--blue a { color: blue; }


If you want more specificity, just add another &:

@mixin themeParent ($child) {
&#{&}--blue #{$child} {
color: blue;
}
}

outputs: .section.section--blue a { color: blue; }


If you want more scability, just iterate over colors you want:

@mixin themeParent ($child) {
$colors: red, blue, green;
@each $color in $colors {
&#{&}--#{$color} #{$child} {
color: $color;
}
}
}

How to pass a mixin as a parameter of another mixin in SASS

You can't add two mixins together the way you'd like. So you just have to make the rem mixin do what you want it to do. So I wrote new code to handle that for you.

@function parseInt($n) {
@return $n / ($n * 0 + 1);
}

@mixin rem($property, $values, $prefix: false) {
$px: ();
$rem: ();

@each $value in $values {

@if $value == 0 or $value == auto or unit($value) == "%" {
$px: append($px, $value);
$rem: append($rem, $value);
} @else {
$unit: unit($value);
$val: parseInt($value);

@if $unit == "px" {
$px: append($px, $value);
$rem: append($rem, ($val / 16 + rem));
}

@if $unit == "rem" {
$px: append($px, ($val * 16 + px));
$rem: append($rem, $value);
}
}
}

@if $px == $rem {
#{$property}: $px;
} @else if $prefix == true {
#{-moz- + $property}: $px;
#{-moz- +$property}: $rem;
#{-webkit- +$property}: $px;
#{-webkit- +$property}: $rem;
#{$property}: $px;
#{$property}: $rem;
} @else {
#{$property}: $px;
#{$property}: $rem;
}
}

Now all you have to do add prefixes to any property is add the value true to the end of the mixin like so...

@include rem(border-radius, 10px, true);

Otherwise if you don't want any prefixs on property like fon-size or something you just don't add a last value like so...

@include rem(font-size, 10px);

I have a working demo here...

*Also on a side note I modified this mixin to handle percentages too.

How to pass multiple args to a Sass Mixin: a list and named variable

You must put the arbitrary arguments at the end of the mixin's arguments list (See the doc)

Try this instead: It uses named arguments in the @include arguments list and options arguments (doc) in the @mixin definition

@mixin fast-transition($ieTransition: false, $properties: "all") {
transition-duration: 0.5s;
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
transition-property: $properties;

@if not($ieTransition) {
:global(.browser-ie) & {
transition: none;
}
}
}

to use it do this

.el-all {
// use all for transition properties and no transition for IE
@include fast-transition();
)
// or
.el-no-ie {
// use $properties for transition properties and no transition for IE
@include fast-transition($properties: 'background-color, color");
)
// or
.el-ie {
// use $properties for transition properties and transition for IE
@include fast-transition($properties: 'background-color, color", $ieTransition: true);
)

See this demonstration https://codepen.io/HerrSerker/pen/dyXEvWK?editors=1100

SASS - Pass $variable to @content from within a @mixin

I don't know if it is the best method, but you could create a global variable, change it at every loop and use it. Something like this:

$color-1: #333;
$color-2: #0073BD;
$myvariable:0;


$numbers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;

$orientations: left, right, top, bottom;

$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
);

@mixin breakpoint($breakpoint) {
$breakpoint: map-get($breakpoints, $breakpoint);
@media (min-width: $breakpoint) {
@content;
}
}

@mixin breakpoints($get-numbers: false) {
@content;
$breakpoints: map-keys($breakpoints);
@each $breakpoint in $breakpoints {
@include breakpoint($breakpoint) {
@if $get-numbers == true {
@each $number in $numbers {
&-#{$number}-#{$breakpoint} {
$myvariable: $number !global;
@content;
}
}
} @else {
&-#{$breakpoint} {
@content;
}
}
}
}
}

.u-margin {
@include breakpoints(true) {
content: "Test to get the #{$myvariable} variable";
margin:$myvariable * 1rem;
// How can I get the $number variable here?
//margin: $number * 1rem;
}
}

Passing css property:value as sass mixin argument

Sass does not allow the use of arbitrary strings in place of the property/value syntax.

For most mixins, the @content directive is your best bet for passing in styling information:

@mixin iphone_rules {
@media screen and (max-height: 460px){
@content;
}
}

.mySelector {
@include iphone_rules {
margin-left:10px;
padding:0px;
}
}

Otherwise, styling information can be passed in as a mapping (or list of lists for Sass 3.2 and older):

@mixin iphone_rules($styles: ()) {
@media screen and (max-height: 460px){
@each $p, $v in $styles {
#{$p}: $v;
}
}
}

.mySelector {
margin-left:10px;
padding:0px;

@include iphone_rules(('margin-left': 20px, 'padding': 2px));
}

Convert Scss to Sass mixin

You can use sass-convert to convert your file from scss to sass

your code in sass is

@function calculateRem($size)
$remSize: $size / 16px

@return $remSize * 1rem

=font-size($size)
font-size: $size
font-size: calculateRem($size)

Reference
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#syntax



Related Topics



Leave a reply



Submit