1

I Created conditional SCSS function for return single or multiple font urls.

And my compiled css looking without errors. So i seems the function is working well.

But when press F5 to debug, in the console giving an error (in nodejs app)

error: error reading values after

After the error my site is looking bad. So i opened css file in my site using developer tools, in the css file looking like this

error reading values after
1
Error: error reading values after

It seems css file doesn't compiled. But locally i opened it, then looking well

@font-face {
    font-family: "Sansation_Regular";
    src: url("../fonts/Sansation_Regular.ttf"), url("../fonts/Sansation_Regular.eot"), url("../fonts/Sansation_Regular.woff"), url("../fonts/Sansation_Regular.svg");
    font-weight: normal;
    font-style: normal;
}

If my function have problems help to solve.

Here My SCSS Function

@function urls($url, $multiple) {

    $result: ();

    // base url 
    $fontsBaseURL: '../fonts/';

    @if $multiple == true {

        $ext: "url(" + $fontsBaseURL + $url + ".ttf)" + ",",
              "url(" + $fontsBaseURL + $url + ".eot)" + ",",
              "url(" + $fontsBaseURL + $url + ".woff)" + ",",
              "url(" + $fontsBaseURL + $url + ".svg)";

        @each $item in $ext {
            $result: append($result, $item);
        }

        @return $result;
    } @else {
        @return url($fontsBaseURL + $url + .ttf);
    }
}

And Helper @mixin Function

@mixin Font($family, $src-name, $multiple) {
    $url: urls($src-name, $multiple);

    font-family: $family;   
    src: $url;
    font-weight: normal;
    font-style: normal;
}

Here i called Function

@font-face {
    @include Font("Sansation_Regular", "Sansation_Regular", true);
}
0xdw
  • 3,755
  • 2
  • 25
  • 40
  • I am voting to close this as a typographical error. You've already demonstrated how to do this when declaring your $ext variable, the return inside of your else needs to be done the same way. – cimmanon Dec 23 '15 at 14:57
  • 2
    @shennan This isn't a "string concatenation" issue, it's an "I forgot that I that I need to quote strings that contain certain characters" issue. Using the plus operator on 2 strings will concatenate them, to say "that's not how you do it" is nonsense. – cimmanon Dec 23 '15 at 15:03
  • 1
    @cimmanon I think this is still classed as a string concatenation issue, in the sense that, in your own words, "certain characters" need to be concatenated in certain ways. And I don't think that "forgetting" something qualifies for a downvote. We are here to help the unknown ***and*** the forgotten. – shennan Dec 23 '15 at 15:06
  • @shennan You should have voted to close this as a duplicate of http://stackoverflow.com/questions/8608498/have-a-variable-in-images-path-in-sass – cimmanon Dec 23 '15 at 15:29
  • @cimmanon Is that why you voted to close on "off topic, because..."? Why not just vote to close as a duplicate yourself? Your assertion in your original comment that the `$ext` variable was declared properly was wrong. Your last comment is damage limitation IMO. – shennan Dec 23 '15 at 15:32

1 Answers1

4

Try changing your Sass Function to this:

@function urls($url, $multiple) {

    $result: ();

    // base url 
    $fontsBaseURL: '../fonts/';

    @if $multiple == true {

        @each $item in ('.ttf', '.eot', 'woff', '.svg') {

            $result: append($result, url('#{$fontsBaseURL}#{$url}#{$item}'), 'comma');
        }

        @return $result;
    } @else {
        @return url('#{$fontsBaseURL}#{$url}.tff');
    }
}

Detailed Explanation:

Remember that certain string concatenations are best done by wrapping the variable in #{} in Sass. Take a property value like url('path/to/image.png');. If we were to do the following:

body {
  $base: 'path/to/';
  $img: 'image.png';
  background-image: "url('" + $base + $img + "');"
}

The output would be:

body {
  background-image: "url('path/to/image.png');";
}

Which is technically wrong, as it is interpreted as a string as opposed to a CSS property value. To make this right, we might just attempt to declare the value without quotes, and use our variable concatenations as normal:

body {
  $base: 'path/to/';
  $img: 'image.png';
  background-image: url('$base + $img');
}

This is again wrong, because our variables are printed literally in the Sass output:

body {
  background-image: url("$base + $img");
}

What we really need, is a way of concatenating strings and expressions interchangeably. This is where the #{} is useful. Here is how you would achieve the above:

body {
  $base: 'path/to/';
  $img: 'image.png';
  background-image: url('#{$base}#{$img}');
}

Output:

p {
  background-image: url("path/to/image.png");
}

As an aside, you were also appending multiple font formats unnecessarily. Simply using a list in the declaration of the @each loop would have sufficed.

shennan
  • 10,798
  • 5
  • 44
  • 79