Rails - required asset files, #import and global scope variables - ruby-on-rails-3

I have a bunch of separate files where I hold my variables which are used project-wide. Since variables wont persist through different scss files throughtout the project I have to import them right after the beggining of my application.css.scss file:
#import "filename.css.scss"
/*
*= require jquery-ui
*/
Now everything that I import via #import gets imported right away without any problem. Everything that I try to import via the sprockets just gets ignored; so if I import each and every SCSS file by hand using #import directive, it all gets imported nicely - which means that files can be accessed by an app. Any idea what can be wrong?
I am using rails v 3.2.6, sprockets 2.1.3.

After spending some time browsing web and reading sprockets docs I found out the following:
Sprockets parse only the beginning of file (until it reaches the end of first comment block), so:
#import "filename.css.scss"
/*
*= require jquery-ui
*/
This will import filename.css.scss but will ignore the *= require jquery-ui directive.
/*
*= require jquery-ui
*/
#import "filename.css.scss"
This will work just fine and load jquery-ui and then import filename.css.scss.
Hope this will help someone in the future.

Related

Foundation Variables Undefined

I'm a little embarrassed I can't seem to figure this out. I'm getting an error whenever I refer to a foundation variable in my scss sheets, for example.
Undefined variable: "$primary-color". (in /my/path/to/mysheet.scss)
Here's my app.scss
/*
*= require_self
*= require_tree ./a_folder
*/
#import "foundation/foundation-global";
#import "foundation/_settings";
#import "foundation";
I suspected it's because the imports are after the requires. But when I reverse the order, all my stylesheets are missing.
What am I doing wrong?
I met same situation in Bootstrap. If using require, all variables can't be used on custom scss files.
The solution is to use #import but no require at all.
I suggest you to remove all require, and #import your custom css files manually in application.css.scss. #import will also work for asset pipeline, so nothing to worry at all, just type some words more.

How to use LESS in twitter Bootstrap

I am trying to use LESS variables in Twitter Bootstrap but cant seem to get them to render in my application.css file
So when i setup bootstrap i installed
rails generate bootstrap:install --less
Which gave me my
bootstrap_and_overrides.css.less
So my understanding is that in this file i can set my LESS variables like so
#white:#FFFFFF;
and then in my css file i can just call them like so
color: #white;
In my bootstrap.less file i call these
#import "twitter/bootstrap/bootstrap";
#import "twitter/bootstrap/responsive";
#import "twitter/bootstrap/variables.less";
and in my application.css file i call the bootstrap file
*= require bootstrap_and_overrides
Gemfile
gem 'less-rails'
This doesnt work and my variables are not being applied
Can anyone see anything that i am doing wrong?
any help appreciated
Thanks
... I can set my LESS variables like so
#white:#FFFFFF;
and then in my css file i can just call them like so color: #white;
Hi, I'm not so familiar with using LESS inside Rails, so apologies if I'm off here.
I can only use less variables inside a file which will be compiled. So for example I can set
#white:#FFFFFF in a variables.less file
perhaps in a custom.less file I have
.light{
color:#white;
}
After I've compiled everything I can use the class .light in my CSS
So to address your quote above, you can set your less variables like
#white:#ffffff
and then you can use that variable in another less file which will be compiled, but not directly in a CSS file.

How do I make my LESS variables available for all CSS files in Rails?

What I have:
In Rails 3.2.2, I have the following stylesheets:
app/assets/stylesheets
|
|-- application.css
|-- bootstrap_and_overrides.css.less
|
|-- annotations.css.less
|-- maps.css.less.erb
`-- users.css.less.erb
The two first ones are more or less system-default. The other ones are where I define my custom styles.
So, application.css, as usual, includes all the other files:
*= require_self
*= require_tree .
And bootstrap_and_overrides.css.less, of course, includes Twitter Bootstrap as well as some other custom defined LESS variables.
#import "twitter/bootstrap/bootstrap";
#import "twitter/bootstrap/responsive";
// other stuff
#brown_text: #332820;
What doesn't work:
Now, in annotations.css.less, I'd like to use #brown_text, but it gives me:
variable #brown_text is undefined
I figure this is because there's no reference from annotations.css.less to the "master" file where the variable would be defined. And it seems that annotations.css.less is compiled first – note that I'm currently in development environment.
So, how can I use my custom LESS variables then, and make them available in other stylesheet files? My current "fix" is to just move all my custom styles into bootstrap_and_overrides.css.less.erb, which doesn't seem very clean at all.
What also doesn't work:
Just importing the LESS files isn't possible, because they use Rails' asset path helpers. And importing an ERB file is also not possible, since the #import statement won't find the file, because it expects a .less suffix.
You don't need to use ERB for asset path helpers – they're actually baked into the less-rails gem, which you can reference here: https://github.com/metaskills/less-rails/#helpers
You should be able to just use asset-path or asset-url anywhere you've used ERB to refer to the assets pipeline.
Given this, the best way to go would be to:
Convert application.css to application.css.less
Delete all the Sprockets directives
#import each individual file in the directory.
Remove the .erb extension from any files that have it, and change ERB asset helpers to less-rails asset helpers.
Make sure annotations.css.less is imported after bootstrap_and_overrides – this is why it's usually not a good idea to use require_tree ., since you can't control the order in which the files are loaded. The way you have it now, annotations.css.less would be loaded before bootstrap_and_overrides – before the variable you want to use even exists.
Hope that helps!
The way twitter-bootstrap-rails is compiling things, you will need to import your other LESS stylesheets into the overrides file. So for an additional file, annotations.less:
#import "twitter/bootstrap/bootstrap";
#import "twitter/bootstrap/responsive";
//other LESS styles
#import "annotations"
For more, look into less-rails, which this gem uses underneath.

Rails 3: Access to twitter bootstrap variables + mixins without importing it

I'm using Rails 3 for the first time (especially asset pipelining and less-rails-bootstrap), so I might be missing some really basic concept here. I've tried two approaches for including the Twitter bootstrap CSS into my project and both have problems.
Approach #1: app/assets/stylesheets/application.css has require twitter/bootstrap. This includes the bootstrap css file using a separate link/href tag, which is good. However, the problem is that in my custom CSS file, say app/stylesheets/mystyles.css I am unable to access variables+mixins defined in less within the bootstrap code, like #gray, .box-shadow, etc.
Approach #2: Put #import 'twitter/bootstrap' at the top of app/assets/stylesheets/mystyles.css. This allows me to access variables+mixins defined in less (within the bootstrap code), which is good. However, the problem is that it pulls in the entire bootstrap CSS at the top of mystyles.css increasing the filesize. If there are a bunch of different stylesheets that #import twitter/ bootstrap it would cause a lot of duplication.
What's the recommended approach for handling this situation?
Your answer is sufficient if you want to exclusively use the default twitter bootstrap variables. If you find yourself wanting to override the variables and have them applied to BOTH twitter bootstrap's styles AND your own styles, you'll need to do separate out your variables into its own myvariables.less file and have that file included with twitter bootstrap instead of in the manifest.
Example
application.css:
/*
* Notice we aren't including twitter/bootstrap/bootstrap in here
*= require bootstrap_and_overrides
*= require mystyles
*/
bootstrap_and_overrides.less:
# Bootstrap with both bootstrap's variables, and your own
#import "twitter/bootstrap/bootstrap";
#import "myvariables";
mystyles.less:
# Your styles with both bootstrap's variables, and your own
#import "myvariables";
h1 {
// Use
color: #textColor;
}
myvariables.less:
#import "twitter/bootstrap/variables";
#textColor: green;
I figured out a possible way to do this without leading to (too much) repetition of CSS code.
application.css
/*
*= require twitter/bootstrap
*= require mystyles
*/
mystyles.css
#import "twitter/bootstrap/variables.less";
#import "twitter/bootstrap/mixins.less";
/* My styles come here, which use variables & mixins defined in twitter bootstrap code */

Why does rails 3.1 and 3.2.0.rc2 create an application.css instead of an scss?

When a rails app is created with rails 3.1 or 3.2.0.rc2 it by default creates an app/assets/stylesheets/application.css file, however each controller/model created there after creates an app/assets/stylesheets/<controller or model name>.scss.
Why isn't an application.scss created by default?
How do you properly incorporate an application.scss and get rid of the application.css entirely?
I would just rename it to application.scss and then you can import in your other .scss files like this:
// Inside application.scss
// HTML Reset
#import "reset.scss";
// Users CSS
#import "users.scss";
When you compile the SCSS, it will generate the application.css for you from all of the other imported files or CSS within that file.
application.css just plays like a house keeper, it represents the correct order of other .scss files.
Put the real working CSS in application.css may not good practice, as the comment generated by rails below:
You're free to add application-wide styles to this file and they'll
appear at the top of the compiled file, but it's generally better to
create a new file per style scope.