ruby-on-rails – failed to @extend “.class”. The selector “.class” was not found

Question:

Application.css

*= require palette
*= require global
*= require_tree .
*= require_self

vendor/assets/stylesheet/pallete.scss

.grey {
  background-color: #9e9e9e;
}

global.scss

html {
  body {
    header {
      @extend .grey;
    }
  }
}

Gives an error message:

"html body header" failed to @extend ".grey".
The selector ".grey" was not found.
Use "@extend .grey! Optional" if the extend should be able to fail.

If the .grey class .grey written in the global.scss file and in the same file to extend, then everything works fine, it will not extend from any other files.

Tried moving the palette file from vendor to app , reordering in application.css , removing *= require_tree . , updated gems, overloaded the server, the computer – the same result.

rake assets:clean
rake assets:precompile

They didn't change anything either.

In a blank application from scratch the same problem.

Ruby and Gem Versions:

  • ruby 2.2.0p0
  • Rails 4.2.5
  • sass (3.4.21)
  • sass-rails (5.0.4)

Answer:

That's right, SCSS files are compiled by Sass one at a time, and then Sprockets (the Rails asset building system) stitches the final styles from them (using the require directives in the comments).

Thus, when global.scss is global.scss , Sass knows nothing about the contents of palette.scss . To find out, you need toimport the corresponding file:

@import 'palette.scss'

… yes, it is very similar to CSS-Marketing @import , Sass its syntax expands gently catching cases where it should be left "as is". This effectively includes the contents of the specified file in place of this directive. That is, the import can be done even inside the rules block, and everything will be loaded inside it. The guide on the link above provides details.


Note that idiomatic Sass imports usually happen with files that have _ at the beginning of the filename (so-called partial ), like _palette.scss , but are imported like this:

@import 'palette'

It should also be understood that the use of code in include files that is rendered in non-empty CSS will result in these blocks appearing several times, if as a result this file is imported several times. To avoid this, you can use a stub selector :

%grey {
  background-color: #9e9e9e;
}

If you render this construct in CSS, you get an empty file. But you can do @extend %grey to get the desired effect.

Scroll to Top