Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selector not found when @extending bootstrap

I'm starting my first rails project. In this project I will be using Bootstrap and SASS. I want to avoid (for the most part) putting style-related classes into my HTML, as explained in this post:

Using Sass To Semantically @extend Bootstrap

I have included bootstrap-sass in my project using Bower and following the instructions here:

https://github.com/twbs/bootstrap-sass#bower-with-rails

Now bootstrap itself is working, since I can use its classes in my HTML and everything renders just fine. But if I try to extend one of my classes with a Bootstrap class, for example:

.myClass
  @extend .text-muted

Then I get the following error:

".myClass" failed to @extend ".text-muted".
The selector ".text-muted" was not found.
Use "@extend .text-muted !optional" if the extend should be able to fail.

I guess it might have something to do with my Sass files being loaded before Bootstrap but I don't know what to do.

The following is the content of my application.css.sass file, in which some things are *= required and others are @imported (I'm not sure whether this is how things should be done).

/*
 *= require components-font-awesome
 *= require_self
 *= require_tree .
 */
$icon-font-path: "bootstrap-sass/assets/fonts/bootstrap/"
@import "bootstrap-sass/assets/stylesheets/bootstrap-sprockets"
@import "bootstrap-sass/assets/stylesheets/bootstrap"

How can I solve this problem?

like image 374
abl Avatar asked Jul 05 '15 16:07

abl


2 Answers

The Bootstrap-Sass doc suggests to remove the requires from your application.sass, as you "will not be able to access the Bootstrap mixins or variables."

You should remove

*= require_tree .

and make sure to @import all relevant files (you seem to do that already).

require_tree will automatically include all stylesheets below your app/assets/stylesheet/ folder and will certainly provoke some duplication or even a wrong load order. instead gain control by importing the files 'manually' in the desired order.

Now @extend either inside the application.sass or in a different partial that you @import after the bootstrap files and you should be good to go.

like image 134
The F Avatar answered Oct 19 '22 18:10

The F


Rails 5 and Rails 6 Answer for failed to @extend and Undefined variable from SassC::SyntaxError

TL;DR: Rails 5 and 6 use a app/assets/config/manifest.js file that by default processes all the .scss files in the root folder app/assets/stylesheets, whereas Rails 4 only targeted files imported in application.scss. To fix these errors in Rails 5 & 6, either:

  1. Move your SCSS files from the stylesheets directory to a subdirectory of stylesheets, since .scss files in subdirectories are not processed by default.
  2. Modify the manifest.js file to only process entry files, such as application.scss.

Link to relevant documentation in Sprockets.

Extended explanation

To reproduce this error, run: bin/rails assets:precompile in the terminal. You will receive an error message such as:

SassC::SyntaxError: Error: ".badge-title" failed to @extend ".text-center".
       The selector ".text-center" was not found.
       Use "@extend .text-center !optional" if the extend should be able to fail.
        on line 47:11 of app/assets/stylesheets/badges.scss

My application.scss:

@import "bootstrap-sprockets";
@import "badges";
// All bootstrap overrides go above
@import "bootstrap";

Note: badges.scss expected the CSS .text-center to be defined within the first @import statement above, however Sprockets 5+ is processing all the files in the stylesheets directory, even if the file name has a leading underscore.

To fix:

  1. I moved stylesheets/badges.scss to stylesheets/components/badges.scss
  2. Modified line 2 in my application.scss file to, @import "components/badges.scss

Hope this helps someone!

like image 3
Matt Avatar answered Oct 19 '22 19:10

Matt