Carry Sass variables across all stylesheet files in Rails - ruby-on-rails

I have a site_settings.scss file which contain all the the variables for my Rails app:
app/assets/stylesheets/site_settings.scss
$primary_color: #4285F4;
$dark_color: #333333;
...
Right now, if I want to use these variable inside a file i need to do this inside that file:
import 'site_settings.scss'
I need to put this at the beginning of EVERY FILE that I want to use these variables, otherwise Rails will give me the Undefined variable: error.
I have tried putting import 'site_settings.scss' inside the application.scss or custom.scss but neither of them is working.
I have also tried to use require 'site_settings' in the aplication.scss and rename application.scss to application.css.scss as being mentioned here: http://mildlyinternet.com/code/scss-variables-asset-pipeline.html , but it's still not working.
Here is my application.scss:
/*
*= require_self
*= require font-awesome
*/
#import "bootstrap-sprockets";
#import "bootstrap";
#import "custom";
#import "devise";
#import "site_settings";
So, how do I solve this, so that I don't have to write import 'site_settings.scss' in every file each time?

You should rename all files that will use the shared variables to start with _.
This will render the other files in context of partial files, which will use the previous declared variables in #import 'site_settings'. So you will have site_settings.scss and quickrails/_general.scss, quickrails/_media_query.scss and so on.
Those imports are considered partials, that is why the name should start with underscore, but when importing you use without it. Here is a material about this:
Why put in front of the file name "_" or "_" in scss/css?

Replace any relevant = require with #import and remove any = require even if you think you've commented it out.

Related

SASS variables do not work when only imported into a master file

I have a partial sass file which holds mixins that I would like to access globally. My understanding is that all you need to do is #import this file into a master.scss file and it should be accessible globally. Sadly this isn't the case for me. I need to import the variable file into every individual .scss file I want to use it in. What do I nee to do to get so that importing it to the master.scss file I can access my mixins globally?
This is a rails app with my master.scss file imported into the application.scss file.
My assets tree
- scss
-- utilities
-- _mixins.scss
-- components
-- buttons.scss
master.scss
Contents of my master.scss file
#import 'utilities/_mixins';
#import 'components/buttons';
Contents of my mixins.scss file
#mixin square-size($size) {
height: $size;
width: $size;
}
Example of how I'm using the mixin in components/buttons.scss:
.square-button {
#include square-size(40px);
}
I'm not 100% sure it will resolve your problem but at least your code is cleaner this way.
Rename your button.scss to _button.scss and you don't need the write the underscore in #import 'utilities/mixins';
The underscore means the scss file is a partial. More info here: Why put in front of the file name "_" or "_" in scss/css?

How to expose SCSS variables from a gem into a rails project with a single `#import`

I have a rails project and a gem. The rails project has .scss files that require variables from the gem:
Rails Project
application.scss:
#import "gem-styles.scss";
#import "my-scss-file-that-needs-access-to-variables.scss"
my-scss-file-that-needs-access-to-variables.scss:
color: $primary-color;
Gem
in gem-styles.scss:
#import "common/variables";
in common/_variables.scss:
$primary-color: #00d9ff;
Doing this, I get the error: Undefined variable: "$primary-color".
I can include common/variables in my-scss-file-that-needs-access-to-variables.scss to fix the issue:
#import "common/variables";
but I don't find that solution DRY enough. I would have to import common/variables into every .scss file that requires them. I would prefer to be able to only import one .scss file from the gem which contains all of the variables that I need exposed in my parent application, as well as the rest of the styles from gem-styles.scss.
you can just paste this #import "common/variables"; into your application.scss only once.
#import "common/variables";
#import "gem-styles.scss";
#import "my-scss-file-that-needs-access-to-variables.scss"
like this

Using variables and mixins in Foundation

I've found a lot of similar questions to this one but nothing that quite solves my problem. Basically, I'm using foundation 4.x with rails 3.x, everything is working fine with foundation_and_overrides being included in my application.css. I can modify the variables in foundation_and_overrides and it all works fine. However, I want to use the $primary-color variable (and a bunch of others) in one of my other scss files (application/global.css.scss). If i use #import "foudation_and_overrides" in my global css file, then it works, but it includes the entire Foundation CSS twice in my compiled application.css, which is obviously not ideal.
I also want to use mixins, such as #include radius() in my global file. This works if I use #import "foundation/components/global" - but then this also ends up with duplicate CSS being compiled. All I want to do is use the global vars & functions, not the CSS - surely this is a really common thing to do?
Previously (before foundation) I just put all my scss functions in a helpers file, and imported this in all other scss files that needed it.
Another quick Q while I'm here, what class do I use to add the little dropdown triangle thing next to some custom text?
Thanks!
With new foundation you do:
$include-html-global-classes: false;
#import "foundation/components/global";
Updated for even newer foundation (see commentS)
Earlier path was
#import "foundation/foundation-global";
As James said you can set the variable $include-html-classes to false and it won't copy any of the styles to the css. You can add the following lines to any scss sheet to get access to variables and mixins.
$include-html-classes: false;
#import "foundation";
There are a bunch of Sass variables named something like, include-grid-css or something like this in _settings.scss or _variables.scss. You can turn them off so it doesn't generate all of those standard presentational classes. If you are confused, just jump into the source of one these and you will see at the bottom of the file, there is an if statement that causes all of that css to be generated with the mixins at the top of the file. Hope this hepls.
Keep only settings in foundation_and_overrides.scss
Remove the following line at the end of the file foundation_and_overrides.scss:
#import "foundation";
And maybe rename foundation_and_overrides.scss to a more appropriate foundation_settings.scss.
Uncomment all settings that you will use in your SASS files. This also makes explicit which Foundation settings you will use in your application files.
Use #import in application.scss
In "application.scss" make sure to use #import instead of require for both Foundation and its settings.
/*
*= require_tree .
*= require_self
*/
#import "foundation_settings";
#import "foundation";
Use Foundation settings in your application files
You can simply add the following line in your files that need to access to Foundation variables:
#import "foundation_settings";
I haven't tested this with mixins yet, but for variables it works and prevents duplicated code.

Import SCSS files from parent directory on Heroku Cedar

I'm trying to deploy a Rails 3.1 app I was working on locally. But once deployed to Heroku (Cedar stack), I encounter an issue I wasn't having locally, and I can't find any solution to this.
Actually, in some of my SCSS files, I import other SCSS files located in the parent directory. Among the several syntaxes I tried :
#import "file.css.scss";
#import "file";
#import "/file.css.scss";
#import "/file";
#import "../file.css.scss";
#import "../file";
Most of these work locally, but none work on my heroku Cedar app. I also tried renaming my imported file into "_file.css.scss" with an underscore, as it seems it's the standard format for SCSS files made to be imported. But didn't change anything.
The error heroku logs are giving me is :
ActionView::Template::Error (File to import not found or unreadable: /mixins.css.scss.
I'm getting out of ideas right now, so would be thankful if you had any clues to solve this.
Thanks a lot,
Cheers !
The syntax should be
With the following folder structure
/app/
/assets/
/stylesheets/
/pages/
index.css.scss
products.css.scss
application.css.scss
If you wanted to include the scss files in /pages/ from application.css.scss you would do this:
#import "pages/index";
#import "pages/products";
You should also be able to do the following (however I'm not sure if this is limited to having Compass in the project or not).
#import "pages/*";
Being able to do glob imports is awesome. But I think it may be Compass only, or at least it used to be.
If the file your importing is within the same folder the following should work:
#import './file.css.scss';
I found it's important to have the relative path and file extension present when I ran into a similar issue. Since you were trying to use ../ that would look for the file your importing in the parent folder rather than within the same folder.
Your best bet is to use the built in Rails Asset Pipeline to handle including your style files.
In your app/assets/stylesheets folder you should have a file named application.css. This file uses Sprockets to automatically include all of your css files placed inside of the app/assets/stylesheets folder.
At the top of the file you'll see this:
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. 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.
*= require_self
*= require_tree .
*/
The *= require_self part includes any css style written in this actual application.css file, while the *= require_tree . part includes assets found in app/assets/stylesheets.
If you'd like to change the order of inclusion, or specify a specific stylesheet, for example a file named mixins.css.scss located in app/assets/stylesheets, here is how you'd do that:
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. 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.
*= require_self
*= require_tree .
*= require_mixins
*/
And the magic of sprockets will include your file for you.

SASS Global Variables + Rails 3.1

I am using Rails 3.1RC4 with default SASS setup. I have the following files
application.css.scss
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. 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.
*= require_self
*= require_tree .
*/
_variables.css.scss
$var1 : somevalue;
...
site_layout.css.scss
#import "variables";
... Some Sass Code
But I can't access the variables defined in _variables.css.scss in site_layout. What am I doing wrong? Rails is apparently finding the variables file since it doesn't throw a "file not found" error, which it does if I change the import filename. Still the vars are not carried over.
Any ideas?
Thanks!
The issue seems to be fixed with the latest release of rails & sprockets. In your gemfile:
gem 'rails', :git => "git://github.com/rails/rails.git", :branch => "3-1-stable"
The first part of your question (the application.css.scss code snippet) doesn't seem to have any relevance here, since it's just commented-out code, so I'll skip that part.
For the second code snippet, I don't believe SASS is set up to import a "partial" quite like you're doing here. You'd be better off doing something like this:
_variables.scss (Renamed from _variables.css.scss):
$var1: somevalue;
Note that the underscore in your filename is not required like it would be for a Ruby partial. You can just as easily name it variables.scss as long as you change the import statement to #import "variables";
site_layout.scss (Renamed from site_layout.css.scss)
#import "_variables";
.test_thingy {
color: $var1;
}
This will generate a site_layout.css file that contains the following code replacement:
.test_thingy {
color: somevalue; }
Note that there's no need to have files named like filename.css.scss like you would with HAML/ERB files. Simply name the file what you want it to be. For example, filename.scss will cause SASS to generate a CSS file called filename.css automatically.

Resources