How to Create a Calc Mixin to Pass as an Expression to Generate Tags

How can I create a calc mixin to pass as an expression to generate tags?

It would be a basic mixin with an argument, thankfully the expressions are not browser-specific within the supported scope:

@mixin calc($property, $expression) {
#{$property}: -webkit-calc(#{$expression});
#{$property}: calc(#{$expression});
}

.test {
@include calc(width, "25% - 1em");
}

Will render as

.test {
width: -webkit-calc(25% - 1em);
width: calc(25% - 1em);
}

You may want to include a "default" value for when calc is not supported.

How can I pass an expression to a calc() mixin that uses Sass variables

You'll need to use string interpolation on the value you're passing to the mixin:

.foo {
@include calc(width, #{"30% - #{$line * 2}"});
}

Output:

.foo {
width: -moz-calc(30% - 24px);
width: -o-calc(30% - 24px);
width: -webkit-calc(30% - 24px);
width: calc(30% - 24px);
}

sass mixin + it-self as consecutive tag?

You can write your mixin with an & + & selector:

@mixin bloc-article() {
// …

& + & {
border-top: 1px solid red;
}
}

Which compiles from:

.article {
@include bloc-article();
}

to:

.article + .article {
border-top: 1px solid red;
}

Here, the Sass parent selector is the $this you are looking for.

From the docs:

The parent selector, &, is a special selector invented by Sass that’s used in nested selectors to refer to the outer selector. It makes it possible to re-use the outer selector in more complex ways, like adding a pseudo-class or adding a selector before the parent.

Sass Variable in CSS calc() function

Interpolate:

body
height: calc(100% - #{$body_padding})

For this case, border-box would also suffice:

body
box-sizing: border-box
height: 100%
padding-top: $body_padding

How to make a calculator function that uses the operator as an input?

You might try using a dictionary to map strings (operators) to function objects:

from operator import add, sub, mul, floordiv

operations = {
"+": add,
"-": sub,
"*": mul,
"/": floordiv
}

a = float(input("Enter first number: "))

while (op := input("Enter operator: ")) not in operations: pass

# 'operation' is one of the four functions - the one 'op' mapped to.
operation = operations[op]

b = float(input("Enter second number: "))

# perform whatever operation 'op' mapped to.
result = operation(a, b)

print(f"{a} {op} {b} = {result}")

In this case, add, sub, mul and floordiv are the function objects, each of which take two parameters, and return a number.

Doing math on variable argument Sass mixins

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

Calculator function based on passed in arguments

You can do something like this:

function calc(par1, par2, par3) {

var number1 = par1;

var operator;

var number2;

if (typeof par2 === 'string') {

operator = par2;

} else {

number2 = par2;

operator = par3;

}

if (typeof operator === "undefined") {

return "wrong data provided"

} else {

if (operator == "+") {

return number1 + (number2 || 0);

} else if (operator == "-") {

return number1 - (number2 || 0);

} else if (operator == "*") {

return number1 * (typeof number2 === 'undefined' ? 1 : 0);

} else if (operator == "/") {

return number1 / (typeof number2 === 'undefined' ? 1 : 0);

}

}

}

console.log(calc(50, '+'));

console.log(calc(50, '*'));

console.log(calc(50, 20, '+'));

console.log(calc(50, undefined, '*'));

console.log(calc(50, 10));

Making a Sass mixin with optional arguments

A DRY'r Way of Doing It

And, generally, a neat trick to remove the quotes.

@mixin box-shadow($top, $left, $blur, $color, $inset:"") {
-webkit-box-shadow: $top $left $blur $color #{$inset};
-moz-box-shadow: $top $left $blur $color #{$inset};
box-shadow: $top $left $blur $color #{$inset};
}

SASS Version 3+, you can use unquote():

@mixin box-shadow($top, $left, $blur, $color, $inset:"") {
-webkit-box-shadow: $top $left $blur $color unquote($inset);
-moz-box-shadow: $top $left $blur $color unquote($inset);
box-shadow: $top $left $blur $color unquote($inset);
}

Picked this up over here: pass a list to a mixin as a single argument with SASS



Related Topics



Leave a reply



Submit