Shannon Hochkins
Shannon Hochkins

Reputation: 12175

SCSS reusable function

I have an error in my sass file, I've got no idea what it's not working...

Here's the message I get from calling .class{ col(6);

error scss/components.scss (Line 18: Invalid CSS after "...gin:7px 0; col": expected "{", was "(6);")

Here's the function and variables used to create the function (sorry if it's a bit confusing):

$columnWidth:40;
$numberOfColumns:16;
$gutterWidth: 20;

$fullWidth:($columnWidth * $numberOfColumns) +  ($gutterWidth * $numberOfColumns); 

@function perc($target) {
  @return (($target / $fullWidth) * 100%);
}

@function gw($n, $fluid: false) {
  $calculatedValue: ($n * $columnWidth + ($n - 1) * $gutterWidth);
  @if $fluid == false {  
    @return $calculatedValue + px;  
  } @else { 
    @return perc($calculatedValue);
  }
}

@function col($n, $fluid: false){  
  @return unquote("width: gw($n, $fluid);");
}

All im trying to do, is re use the gw() function, so that I can use it in css to output the number of columns as a width css property, ie grid(4); would output width: 200px;.

the function gw works because it generates my grid css properly, however I want to define a global function to use everywhere. Hence the col() function.

Upvotes: 0

Views: 1697

Answers (2)

cimmanon
cimmanon

Reputation: 68319

Functions can only be used to return simple types (string, color, number, etc.) or lists of simple types. It cannot be used to return a property/value (eg. "color: red"): all you can ever get when you do this is a string or a list of strings (and strings cannot be used this way). Mucking around with lists of strings is more work for you than simply using a mixin.

@function foo() {
    @return color red;
}

.foo {
    $kv: foo();
    #{nth($foo, 1)}: #{nth($foo, 2)}
}

Compare to:

@mixin foo() {
    color: red;
}

.foo {
    @include foo;
}

There's nothing inherently non-reusable about your gw() function (in fact, it is more reusable than the impossible function you're dreaming of): it returns a numeric value that can be used for any property. In fact, using it in place of a mixin or a function that returns a list of strings is the most efficient way of going about what you're looking for:

.foo {
    width: gw(1);
}

Upvotes: -1

Jonas G. Drange
Jonas G. Drange

Reputation: 8845

A mixin is like a function, but does not return anything other than its body, which can be full blown SCSS.

So you can fix this by making col a mixin, like so:

@mixin col($n, $fluid: false){  
  width: gw($n, $fluid);
}

Then you can call:

.class{ @include col(6) };

Which produces:

.class {
  width: 340px; }

Upvotes: 2

Related Questions