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
How to Customize the HTML5 Input Range Type Looks Using CSS
Bootstrap - Removing Padding or Margin When Screen Size Is Smaller
In Outlook HTML Email, Float Does Not Work
Css: Background Image Does Not Fill When Scrolling
How to Add Multiple CSS Gradient as a Multiple Background
Background-Attachment Fixed with Transform Not Working in Firefox
Using Static Files with the Django Virtual Server
Change New Google Recaptcha (V2) Width
Overflow: Overlay Doesn't Work in Firefox
How to Rotate Text Left 90 Degree and Cell Size Is Adjusted According to Text in HTML
How to Align Spans or Divs Horizontally
Two CSS Files Defining Same Class
Slashes ('/') in CSS Values When Using Less (E.G. in 'Font' Shorthand)
How to Apply Child:Hover But Not Parent:Hover
Does a Background-Attachment of Fixed Work in iOS5
Are "Top" and "To Top" the Same Direction for Linear Gradients