Passing CSS Property:Value as SASS Mixin Argument

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));
}

SASS: Returning set of different CSS properties from a mixin or function

I found a logic for this problem using mixins.

I have created a Mixin that accepts all the params passed as a list, hence declaration ends in ...
This solution also covers optional CSS properties which may not be included in all the classes but majority of them.

styles.scss

.blog-content {
// for .destination
@include text-properties("destination", "EpicRide", normal, 65px, $standard-black, none, 2.8px, '', '');
// for .intro-title
@include text-properties("intro-title", "Montserrat", 500, 14px, $standard-black, uppercase, 2.8px, 5px 5% 0, '');
// for .place
@include text-properties("place", "Montserrat", 500, 14px, $standard-black, uppercase, 2.8px, inherit, '');
// for .description
@include text-properties("description", "Lora", 400, 16px, $standard-light, none, 0, 0 5%, 20px);
}

_variables.scss

@mixin text-properties($args... ) {  // args has a list of arguments
$class: nth($args, 1); // nth is used to extract 'nth' argument's value
$font-family: nth($args, 2);
$font-weight: nth($args, 3);
$font-size: nth($args, 4);
$color: nth($args, 5);
$text-transform: nth($args, 6);
$letter-spacing: nth($args, 7);
$padding: nth($args, 8);
$margin-top: nth($args, 9);

.#{$class} { // create class dynamically. Mention the variable name inside #{} to fetch it's value
font-family: $font-family;
font-weight: $font-weight;
font-size: $font-size;
color: $color;
text-transform: $text-transform;
letter-spacing: $letter-spacing;
@if $padding != '' { // condition to ensure property is added only if valid param is passed.
padding: $padding;
}
@if $margin-top != '' {
margin-top: $margin-top;
}
}
}

Resultant CSS

.blog-content .destination {
font-family: "EpicRide";
font-weight: normal;
font-size: 65px;
color: rgba(0, 0, 0, 0.9);
text-transform: none;
letter-spacing: 2.8px;
}
.blog-content .intro-title {
font-family: "Montserrat";
font-weight: 500;
font-size: 14px;
color: rgba(0, 0, 0, 0.9);
text-transform: uppercase;
letter-spacing: 2.8px;
padding: 5px 5% 0;
}
.blog-content .place {
font-family: "Montserrat";
font-weight: 500;
font-size: 14px;
color: rgba(0, 0, 0, 0.9);
text-transform: uppercase;
letter-spacing: 2.8px;
padding: inherit;
}
.blog-content .description {
font-family: "Lora";
font-weight: 400;
font-size: 16px;
color: rgb(var(--LightColorRGB));
text-transform: none;
letter-spacing: 0;
padding: 0 5%;
margin-top: 20px;
}

This solution has one limitation though, an increase in the number of CSS properties would increase the mixin code.

I hope this will solve your issue. Suggestions/Comments are welcomed to improve this logic.

CSS property as SASS mixin value

If you want to use variables as property names you need to use string interpolation - #{$var}.

So this should work:

[class*="shift"] {
$sft-o: 10px;
@mixin shift_stp($val) {
&[class*="_sml"]{ #{$val}: $sft-o; }
&[class*="_mid"]{ #{$val}: $sft-o * 2; }
&[class*="_big"]{ #{$val}: $sft-o * 3; }
}
&[class*="_m"]{
@include shift_stp(margin);
}
&[class*="_p"]{
@include shift_stp(padding);
}
}

DEMO

Just a note: for your attribute selectors ... *="_m" will also apply to the ones that have _mid in them (see here) ... so maybe you should rethink this a little.

Pass variable from SASS mixin to CSS Value

It might not be the best solution. But it'll solve your problem.
Try with the below code.

@mixin rotate( $name ) {
animation-name: $name;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: infinite;

@keyframes #{ $name } {
100% {
transform: #{ $name }#{"("}360deg#{")"};
}
}
}

.rotate-x {
@include rotate( $name: rotateX );
}

Using variables for CSS properties in Sass

You need to use interpolation (eg. #{$var}) on your variable in order for Sass to treat it as a CSS property. Without it, you're just performing variable assignment.

@mixin w_fluid($property_name, $w_element, $w_parent:16) {
#{$property_name}: percentage(($w_element / $w_parent));
}

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

Pass variable to sass mixin to contain multiple properties

One would typically solve this problem by using default values on a mixin and only specifying the exact values you wish to modify:

$default-hLength: -3px !default;
$default-vLength: 0 !default;
$default-blur: 0 !default;
$default-spread: null !default;
$default-colour: null !default;
$default-type: null !default;

@mixin box-shadow($hLength: $default-hLength, $vLength: $default-vLength, $blur: $default-blur, $spread: $default-spread, $colour: $default-colour, $type: $default-type){
-webkit-box-shadow: $type $hLength $vLength $blur $spread $colour;
-moz-box-shadow: $type $hLength $vLength $blur $spread $colour;
box-shadow: $type $hLength $vLength $blur $spread $colour;
}

li {

&.channel1 {
@include box-shadow($colour: $channel1, $type: inset);
}

&.channel2 {
@include box-shadow($colour: $channel2, $type: inset);
}
}

Alternately, you can store portions of your arguments as a list and expand them when calling your mixin:

li {
$vals1: -3px 0 0 0;
$vals3: -3px 0 0 0 black inset;
&.channel1 {
// option 1
@include box-shadow($vals1..., $colour: $channel1, $type: inset);
// option 2
@include box-shadow(join($vals1, ($channel1, inset))...);
// option 3
@include box-shadow(set-nth($vals3, 5, $channel1)...);
}

&.channel2 {
// option 1
@include box-shadow($vals1..., $colour: $channel2, $type: inset);
// option 2
@include box-shadow(join($vals1, ($channel2, inset))...);
// option 3
@include box-shadow(set-nth($vals3, 5, $channel2)...);
}
}

However, you're never going to be satisfied with a mixin like that because it only assumes that you're going to have a single box-shadow, but the property allows for multiples.

It would be by far simpler for you in the long run if you could loop through the values you want and call a more robust mixin:

@mixin box-shadow($values...) {
-webkit-box-shadow: $values;
-moz-box-shadow: $values;
box-shadow: $values;
}

li {
$colours: $channel1, $channel2, $channel3, $channel4;

@for $i from 1 through length($colours) {
&.channel#{$i} {
@include box-shadow(inset -3px 0 0 0 nth($colours, $i));
}
}
}


Related Topics



Leave a reply



Submit