Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directives should allow interpolation #46

Closed
thedjinn opened this issue Feb 26, 2011 · 27 comments
Closed

Directives should allow interpolation #46

thedjinn opened this issue Feb 26, 2011 · 27 comments
Labels
enhancement New feature or request

Comments

@thedjinn
Copy link

I want to create an SCSS mixin which makes me some @-webkit-keyframe sections. I can do the following:

@mixin animate($name) {
    @-webkit-keyframes foo {
        0% { color: red; }
        100% { color: blue; }
     }
}

This works fine. However, as I want the $name variable to be inserted as the animation name, I replace the second line with:

@-webkit-keyframes $name {

Sass doesn't understand this and gives a parse error:

Invalid CSS after "...bkit-keyframes ": expected "}", was "$name {"
@chriseppstein
Copy link

In selectors and normal directives, you need to use interpolation #{ ... } to insert scripted values. E.g.

@-webkit-keyframes #{$name} {

@thedjinn
Copy link
Author

Yes, this was something that popped up on my mind too. However, that doesn't work either! The error now is:

Invalid CSS after "...bkit-keyframes ": expected "}", was "#{$name} {"

I think there is an error in the way the @-webkit-keyframes is parsed. Using the code outside of a mixin (with a global variable) yields another error:

Invalid CSS after "...bkit-keyframes ": expected selector or at-rule, was "#{$name} {"

@chriseppstein
Copy link

hmm. my mistake, I guess we don't interpolate unknown at-rules. I reopened the issue.

@nex3
Copy link
Contributor

nex3 commented Apr 24, 2011

This is something we should support, but I don't think it's important enough to fit into 3.1.

@rbq
Copy link

rbq commented May 31, 2011

To me this seems to be quite important. According to #79 using the media bubbling feature currently requires repeating your selectors over and over.

I'd like to do something like this instead:

@media ($iphone) and ($ipad) {
  ...
}

@media (iphone) {
  ...
}

@media ($ipad) and ($desktop) {
  ...
}

@chriseppstein
Copy link

Ah the issue is that this only works in .sass files. The SCSS parser is choking before interpolation runs.

@jacobrask
Copy link

Just started out with SASS and immediately stumbled upon this. Not sure if I should report a separate bug for:

$mq-wide: "@media (min-width: 1280px)";
#{$mq-wide} {
    // code
}

The error I get is

Invalid CSS after "": expected selector, was "@media (min-wid..."

@yarmand
Copy link

yarmand commented Aug 3, 2011

Just impossible to do properly dynamic responsive without this one implemented.

I use this workaround in mentime :

$global-width: 1200px
. container
  width: $global-width
  ...
@if $skeleton_global_width > 1100
  @media only screen
    @media (min-width: 960px)
      @media (max-width: 1009px)
        . container
          width: 960px

I'd rather do

@media only screen
  @media (min-width: 960px)
    @media (max-width: $global-width - 1)
      . container
        width: 960px

@ChrisNewton
Copy link

Another vote for this one on responsive web design grounds, please.

It is very common to want a decision based on @media screen together with a min-width or max-width to select between layouts. Typically, we would then use lengths based on that same width value to size elements within the layout:

#responsive-page-element {
    width: $default-layout-width;

    @media screen and (min-width: $important-width-value) {
        width: $foo * $important-width-value + $bar - $baz;
    }
}

Often, there will be several such @media blocks for each responsive element, based on a series of widths where the layout changes.

Not being able to interpolate the length in the media query here is a significant problem, forcing repetition of those important width values throughout a SCSS file, or across a whole set of files for a larger site instead of storing all core data like that in a single file and @importing it elsewhere.

It might be considered a different issue depending on how the parser works, but for what it's worth, I agree that it would be very nice to interpolate an entire media query as well:

@media $ipad {
    // ...
}

For me personally this would have a much lower priority, though, because it is far less likely in practice that something like @media screen is going to change during routine development work.

@alexandertrefz
Copy link

The following (to create the different prefixed keyframes for all browsers) is not possible either :/

@mixin animate($prefix) {
    @#{$prefix}keyframes foo {
        0% { color: red; }
        100% { color: blue; }
     }
}

@pyrsmk
Copy link

pyrsmk commented Oct 21, 2011

I agree too, it's a must-have behavior for responsive designs and flexible development...

@ZeeAgency
Copy link

+1
Would love to do something like that...

@for $i from 1 through 4 {
    @media only screen and (max-width: $i * $width) {
        width: $width;
    }

}

@jgarber
Copy link

jgarber commented Jan 11, 2012

+1

I'm trying to do:

@media only screen and (min-width: $mobile-nav-width) 

But I get

Line 39: Invalid CSS after "...nd (min-width: ": expected expression (e.g. 1px, bold), was "$mobile-nav-wid..."

@chriseppstein
Copy link

this is a blocker for building proper animation and media support.

@nathggns
Copy link

Any plan to fix this?

@chriseppstein
Copy link

Yes.

@nathggns
Copy link

How soon? This is really bugging me (I'm trying to make a keyframes mixin).

@chriseppstein
Copy link

It'll be fixed in 3.2. As a work around, you can do this in a .sass file -- this bug only affects the .scss syntax

@nex3 nex3 closed this as completed in 5f86952 Jan 19, 2012
@nex3
Copy link
Contributor

nex3 commented Aug 3, 2012

#429 is tracking interpolation in all unknown directives.

@curtisblackwell
Copy link

I'm on 3.2.1 and I tried 3.3.0.alpha.3, and i still get the bug using

@mixin keyframes($name) {
  @-webkit-keyframes #{$name} {
    @content;
  }
  @-moz-keyframes #{$name} {
    @content;
  }
  @-o-keyframes #{$name} {
    @content;
  }
  @keyframes #{$name} {
    @content;
  }
}

@steelx
Copy link

steelx commented Jul 25, 2013

Is it going to get fixed ?

@Snugug
Copy link

Snugug commented Jul 25, 2013

This has been fixed and has been working for a while. Go to http://sassmeister.com/ and try the following code:

@mixin animation($animation...) {
    @each $prefix in -webkit {
        #{$prefix}-animation: $animation;
    }
    animation: $animation;
}

@mixin keyframe($name) {
    @-webkit-keyframe #{$name} {
        @content;
    }
    @keyframe #{$name} {
        @content;
    }
}

.foo {
    @include animation(foo 30s infininte);
}

@include keyframe(foo) {
    0% {
        background-color: red;
    }
    100% {
        background-color: blue;
    }
}

For those curious, this is the reason I only have -webkit in there. Everywhere else it's unprefixed. Opera 2 versions back has the -o prefix, but opera users tend to be pretty good at upgrading. -moz is totally unneeded.

And, of course, this works with media queries as well. Take a look at Breakpoint's usage of a full media query interpolation.

Finally, for those still curious as to whether or not this is in, well, here's the official changelog about it getting in.

@QuyHP
Copy link

QuyHP commented Apr 5, 2014

I keep receiving the "Invalid CSS after "@": expected identifier, was "#{$vendor}keyfr...")" error on this code:

@mixin keyframe($keyframe-name) {
    $vendors: (-webkit-, -moz-, -o-, -ms-, '');

    @each $vendor in $vendors {
        @#{$vendor}keyframes #{$keyframe-name} { 
            @include keyframe-content($vendor);
        }
    }
}

If I replace with this

#{'@' + $vendor}keyframes #{$keyframe-name} { 

then I get this error "Invalid CSS after "": expected selector, was "@-webkit-keyfra...")"

Is this going to be fixed?

@lolmaus
Copy link

lolmaus commented Apr 6, 2014

  1. You're already using an outside mixin and an inside mixin.
  2. There are a limited number of prefixes to support.

Thus, while hoping for your feature request to be implemented, you can use an if-elseif-elseif-elseif-else construct to create prefixed keyframes.

@nex3
Copy link
Contributor

nex3 commented Apr 11, 2014

@QuyHP: you're looking for #966.

@srekoble
Copy link

Is this bug fixed ? I'm on 3.3.7 and I'm trying to use

@mixin keyframes($animation-name) {
  @-webkit-keyframes $animation-name {
    @content;
  }
  @-moz-keyframes $animation-name {
    @content;
  }
  @-o-keyframes $animation-name {
    @content;
  }
  @keyframes $animation-name {
    @content;
  }
}

and I'm getting the same error:

Invalid CSS after "...bkit-keyframes ": expected "}", was "$animation-name {"

In sassmeister seems to work (codepen also)
http://sassmeister.com/gist/bb3f4dd20a9ea0b737ee

I tried to use both simple $ and intrepolation method #{name} but I still get the same error

@chriseppstein
Copy link

@srekoble I can't reproduce your issue. Must be a very old version of sass you're using this even works in 3.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests