Libsass: New CSS filter functions conflict with built-in Sass functions

Created on 16 Aug 2013  ·  26Comments  ·  Source: sass/libsass

The following code:

foo {
  -webkit-filter: grayscale(100%);
}

Results in the following with sass 3.2.10:

foo {
  -webkit-filter: grayscale(100%); }

But the following with libsass master (at 4dd61de67aa0284cd8da1e8f13e2f6b63b990041 currently):

/private/tmp/test/grayscale.scss:2: error: argument `$color` of `grayscale($color)` must be a color
Backtrace:
    /private/tmp/test/grayscale.scss:2, in function `grayscale`
    /private/tmp/test/grayscale.scss:2

This seems to be a conflict with the built-in grayscale function.

Bug - Confirmed Dev - Test Written

Most helpful comment

Another workaround: instead of filter: invert() use filter: #{"invert()"}. You can put whatever you want within the quotes and it will be output verbatim.

All 26 comments

Yes, I just hit this too.

Hitting this as well.

:+1:

Any news on this one?

I'm currently working on @extend, but I'll try to get to this one before the holidays!

Having this issue too.

:+1:

Confirming that darken() and saturate() are also affected. Is there a workaround?

Found a workaround, you can use this function in the meantime. It should be a drop-in solution:

@function grayscale($value) {
  @return #{ "grayscale(" + $value + ")" };
}

You can vendor prefix it, too, if you’d like:

@mixin filter($properties) {
  // Your vendor prefixing stuff here, I am using Bourbon:
  @include prefixer(filter, $properties, webkit moz spec);
}

Then, you can just write:

@include filter(grayscale(100%));

Just putting this here for reference:
https://developer.mozilla.org/en-US/docs/Web/CSS/filter

@kennethormandy Have you found a work around for the SASS functions which take two parameters?

@function darken($color, $amount) {
  @return #{ "darken(" + $color + "," + $amount ")" };
}

.selector {
    border: 1px solid darken(#f0f1f4, 3);
}

Outputs:

border: 1px solid darken(#f0f1f4,3"");

…but really it shouldn’t even be outputting darken—it should be a new color value entirely.

Wow, I had no idea darken() didn’t work. @akhleung, is that a regression? Sorry, I was testing the problem and recreated the issue, ha. @restlessdesign, if you get rid of your custom function, darken() works already. So just write:

.selector {
    border: 1px solid darken(#f0f1f4, 3);
}

and you’ll get

.selector {
  border:1px solid #e7e9ee;
}

I think you might (understandably) be mixing up Sass’ functions with CSS Filters. The example I gave will only work because it’s a CSS Filter. If you’re looking to use Sass’ darken or saturate, that should work already, per the Sass docs. If you want to use the CSS Filter saturate, you’re on the right track basing it off of my greyscale() function. There is CSS darken() filter, so you’re actually just over-writing libsass’ built-in darken function right now.

My mistake. I was nesting methods, and called adjust_hue instead of adjust-hue, which cascaded into darken(). Brutal, but I love that LibSass will actually report errors or give invalid output instead of silently ignoring calls! Sorry for the false alarm.

+1
Although the workaround works fine (thank you @kennethormandy) it would be nice if it were fixed.

Is there any news on this one? Would be really nice to not obfuscate the code with the workaround provided above, although it works.

Looking for a solution as-well =)

+1

+1

+1

Thanks @kennethormandy for workaround

+1. By the way: Thanks @kennethormandy for the solution.

Just opened (and closed) an issue about this as well. It would be nice to get this cleaned up as there is a fundamental shift of CSS to start using more and more function like syntax with overlap.

Yeah @kennethormandy, thanks for the workaround idea, but when you do that, then you kill the actual grayscale() function and that sucks! I am hoping that a real fix to this comes soon.

Another workaround: instead of filter: invert() use filter: #{"invert()"}. You can put whatever you want within the quotes and it will be output verbatim.

Alright, let me see if we can get this in 3.0.

Thank you @tamlyn! I've been using Scout.app, which is apparently still on an old version of Sass, so your workaround is a fast, simple solution that actually works.

@function filters($filter, $value) {
@return #{$filter}#{"(" + $value + ")"}
}

$prefixes:
"-webkit-",
"-moz-",
"-ms-",
"-o-",
null;

@mixin prefixer($property, $value) {
@each $prefix in $prefixes {
#{$prefix}#{$property}: $value;
}
}

@restlessdesign Hi folks, I know this it very late but, I just had this issue and my workaround was to quote the filter function and then use unquote() on it.

So I wrote:
* { filter: unquote("filter-function(values)") }

And the output works.

Was this page helpful?
0 / 5 - 0 ratings