1

I am trying to use bootstrap in rails using the gem 'bootstrap-sass' with the following setting in initializers

Below is the code in my application.css and common.css below that is a screenshot of my asset structure:

#app/assets/stylesheets/application.css.scss
 *= require_self
 *= require ./store/_common
 *= require font-awesome



#app/assets/stylesheets/store/_common.css.scss
// import the CSS framework
@import "bootstrap-sprockets";
@import "bootstrap-custom";
@import "footer";
@import "header";
..
..

The problem is that, even though I've already imported the bootstrap files in my common.css still I have to manually import them in every file, in which I want to use the bootstrap variables or mixins. e.g. in _footer.css.scss I am trying to use the variable $gray-lighter or extend the .thumbnail class and getting an error

Undefined variable: "$gray-lighter".

As soon as I add the line @import "bootstrap-variables-custom"; on top of this file, the error withers away.

I tried changing the application.css as follows, while removing the first two imports from common.css but it didn't work:

 *= require_self
 *= require _bootstrap-sprockets
 *= require _bootstrap-custom
 *= require store/_common
 *= require font-awesome

enter image description here

UPDATE:- My current structure is as follows, with this structure I do not have to include bootstrap-custom in every file which is included in common.css but in every other file like taxons_show.css it is required. I tried moving this bootstrap-custom import to application.css, but it didn't work:

Rails.application.config.assets.precompile += %w( dashboard/* dashboard.css dashboard.js store/taxons*)

#app/assets/stylesheets/application.css.scss
 *= require_self
 *= require ./store/_common
 *= require font-awesome


#app/assets/stylesheets/store/_common.css.scss
// import the CSS framework
@import "bootstrap-custom";
@import "footer";
@import "header";
.....
....


#app/assets/stylesheets/store/taxons_show.css.scss
@import "bootstrap-custom";

#product-listings {
  padding: 30px;
  display: flex;
  flex-wrap: wrap;
  .product_card {
    margin-bottom: 50px;
    border: none;
    @extend .thumbnail;
    h3 {
      color: $gray;
      margin-top: 10px;
      font-size: 1.5em;
    }
    .price {
      color: $gray;
      font-size: 1.7em;
    }
  }
}
Vipin Verma
  • 5,330
  • 11
  • 50
  • 92
  • One thing: This file should be an .erb not .scss => application.css.erb. – Elvn Apr 30 '16 at 17:31
  • Any reason? Got the same error even after changing it to erb – Vipin Verma Apr 30 '16 at 17:34
  • Yep. http://guides.rubyonrails.org/asset_pipeline.html "2.3.1 CSS and ERB The asset pipeline automatically evaluates ERB. This means if you add an erb extension to a CSS asset (for example, application.css.erb), then helpers like asset_path are available in your CSS rules:..." – Elvn Apr 30 '16 at 18:02
  • This being the key point "The asset pipeline automatically evaluates ERB." – Elvn Apr 30 '16 at 18:03
  • no need to use erb here, erb is for using ruby code inside the css, he is trying to use scss precompiler for css – Alexis Apr 30 '16 at 18:45
  • You still have files here that don't have underscores at the beginning of their names. – cimmanon Apr 30 '16 at 19:58
  • @cimmanon please elaborate – Vipin Verma Apr 30 '16 at 20:24
  • The question I closed this as a duplicate of explains it. – cimmanon Apr 30 '16 at 20:26
  • well I can't rename app/assets/stylesheets/store/taxons_show.css.scss to begin with an underscore. it is included only if the show action of the taxons controller is invoked. and it should be used this way – Vipin Verma May 01 '16 at 11:08

1 Answers1

1

Hi i'm gonna put an example organization for your project and then try to explain why i did every change i made, also i'm gonna be assuming that you are working on the last version of rails, some changes might not work in previous versions, so...

#app/assets/stylesheets/application.scss
/*
*= require_self
*/
@import "bootstrap-custom";
@import "font-awesome";
@import "store/common";

first rails accepts just scss extension now, same thing for coffee, so we are gonna use this notation, is important because we need to use imports instead of requires, requires are a css thing i belive, with imports that are from scss would know that it needs to pre render those files to css, for example, if you use a variables file and then require another bootstrap files, internally you will have a css compilations of variables and a css compilation of the bootstrap file, witch nether of those will have communication, supposedly the notation says that by pre named your files with "_" it should know that those are pieces of file, so in theory you could imports those as scss files and compile it before, but from my last project i have troubles with this and just be able to do it from 1 lvl, meaning that i can call a file from a subfile, do you follow me?, hope so... so i usually go for import my bootstrap-custom at the top, in that position because bootstrap is pretty big and many times it would override another libraries that i'm using at the moment.

Next our bootstrap-custom file

@import "bootstrap-sprockets";
@import "bootstrap/bootstrap-variables";
@import "bootstrap";

//for example
html{
    //need it for sticky footer
    position: relative;
    min-height: 100%;
    body{
        padding-top: $navbar-height + 30px;
        padding-bottom: 350px;
    }
}

Ok, sprockets, always came first, is all the basic dependencies, then i personally like to have a copy of bootstrap-variables and modify my customizations as much as i can from here, many of these work in conjunction so you will have many modifications for free if you do it from here, also i think is more clear, and then any change that i need as scss code below, you need to keep in mind that any change in variables will work with the next import, "bootstrap", these are like ||= assignments, meaning that if no value is given before they would take the default one, so import those before bootstrap.

Usually the problems with bootstrap are multiple imports of the same file or imports of precompiled pieces of the scss generating no interaction between files, think about witch files should be scss and witch ones should be css(generally files that are precompiled libraries).

Finally

Rails.application.config.assets.precompile += %w( )

This place is for files that live out of your application files, so since you are using *=require_self, you don't need to imported again, you could always use other files, but that's another history, so you should be adding files like png, gif, fonts, etc, or generalizations of thoses *.png, but if your files are correctly structured, rails should let you know witch exactly files you need and if you are seen too many there is probably an error around there.

Sorry about the basic english and hope that this helps, regards!

Alexis
  • 4,836
  • 2
  • 21
  • 27
  • "first rails accepts just scss extension now" -- Not so much. Are you talking about Rails 5?. – Elvn Apr 30 '16 at 18:04
  • 4.2.4 for sure, maybe 4.2, don't really remember when was implemented – Alexis Apr 30 '16 at 18:06
  • Not so. Using 4.2.4. See http://guides.rubyonrails.org/asset_pipeline.html -- explicit description section 2.3.1. – Elvn Apr 30 '16 at 18:08
  • I am not sure about if I did it wrong. I did as per your suggestion, it almost worked for me, except that I am not able to use the bootstrap glyphicons, which i was able to earlier. here is a gist of the `_bootstrap-custom.scss` file https://gist.github.com/vipin8169/d004f1784b750d13e23168b66c782624 – Vipin Verma Apr 30 '16 at 18:27
  • uff... i don't have access to an enviroment here, but go to bootstrap_variables_custom and the first line should be "$bootstrap-sass-asset-helper: false !default;" change it to "$bootstrap-sass-asset-helper: true;" let me know if it was that – Alexis Apr 30 '16 at 18:33
  • and for the guides, i check what you say, and i couldn't find where i got that information, but i remember that was official, it was on the change log of one the releases and i adopted right away that time on my projects, i used it in production, without any extra workaround, i'm positive about it, but is just my word for now, so just go with the standard one – Alexis Apr 30 '16 at 18:37
  • can't solve this problem :( – Vipin Verma Apr 30 '16 at 19:36
  • @Alexis can you please again look at the question above. i've updated it – Vipin Verma Apr 30 '16 at 19:45
  • can I have your email id? can chat about this? – Vipin Verma May 01 '16 at 11:18
  • use @import to bring store/_common(like in the first part of the example), if you use require you are bringing a css file who doesn't know anything about scss or how to deal with the other bootstrap files in the below part of the tree – Alexis May 02 '16 at 10:04