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.
I am trying to use Foundation 5 in a Rails 4 app. The problem I am having is I would like to have some custom CSS in addition to Foundation. In my CSS I would like to use some of the variables from Foundation. To use them I did added the following to the top of my scss file
$include-html-classes: false;
#import "foundation/components/global";
This works great except there is some junk still included on each page. According to https://github.com/zurb/foundation/issues/1629 this shouldn't happen.
If you look at the source here https://github.com/zurb/foundation/blob/master/scss/foundation/components/_global.scss then you can see that the meta stuff starting at line 284 will be included.
This is a problem since it will be included on every page that I want to use the variables/mixins on. Rails 4 combines all the css files into one which will have this same code over and over again...
Is there any way to include this file without it including any text?
I just discovered that using
#import "foundation/functions";
#include exports("global") {}
#import "foundation/components/global";
will include all the variables and mixins but won't add anything to your scss file!
I believe this is because the exports function is there to prevent css from being duplicated every time the global file is included. By having the fake exports function call it thinks it's already added the css.
I'm new to LESS and Bootstrap and I'm confused at the outcome of my css file.
My basic goal is to use the mixins and variables in bootstrap in my own css files.
From my understanding the process would be, get the less files, import them into the project, and import the bootstrap reference. So at this point I can now use the mixins in my own css file.
Example:
#import "less/bootstrap.less";
.myRow{
.make-row();
}
However now I have a 7400+ lines of styling in myCustomStyles.css. Is this "correct"? I don't understand why it actually imports all the styles. My understanding is... that I have a reference to bootstrap.min.css CDN or local. Then myCustomStyles.css will be included AFTER that and override the default values.
I guess I'm confused at how do I take advantage of a CDN and still use the mixins and variables in bootstrap?
I've used the following two articles as a reference:
http://www.helloerik.com/bootstrap-3-less-workflow-tutorial
http://www.codeproject.com/Articles/594098/How-to-customize-Twitter-Bootstrap-to-fit-your-web
Bootstrap.less is the full bootstrap implementation. It is going to have all the variables and mixins to build the entire CSS for bootstrap. If you don't want this, then you should probably pick and choose which LESS files to include instead. You probably want variables and mixins, so you could maybe get by with only importing variables.less and mixins.less?
If you look at bootstrap.less it looks like this:
// Core variables and mixins
#import "variables.less";
#import "mixins.less";
// Reset
#import "normalize.less";
#import "print.less";
// Core CSS
#import "scaffolding.less";
#import "type.less";
#import "code.less";
#import "grid.less";
#import "tables.less";
#import "forms.less";
#import "buttons.less";
// snip...
It is nothing but a bunch of imports to other .less files. Each file is sort of specific to what it is doing. At a minimum I think you would need variables and possibly mixins. Normalize does a CSS reset. Grid defines the grid classes, etc.
Possible Since LESS 1.5
You can specify that you want the code only as a reference like so:
#import (reference) "less/bootstrap.less";
.myRow{
.make-row();
}
The addition of the (reference) tells LESS to import it by not compile the code to CSS. This allows you to use the entirety of bootstrap for mixin reference purposes, but avoids adding all the code in. Of course, one needs to know how this may affect the implementation, as there are parts of bootstrap that expect certain code to be in place to work properly. But that this a whole other thing.
I'm having an issue with using #import to load global variables and also for the purpose of #extend from other files.
Let's say I have a settings.css.scss and I want this available in all my files by using #import 'settings'; at the top of each other scss file.
This works fine and I do get proper access to all my variables and stuff -- but doesn't this inject all the styles again to each file?
When I look at the source in the after-compiled version, I'm seeing the same style for a given class repeated 3-4 times in firebug, except it's scratching out all but one.
Is this repetitive bloat normal or am I doing something wrong??
I'm running into an upsetting issue when trying to share variables and mixins across Sass stylesheets.
If I use #import to include a global stylesheet – one which includes global colors, mixins, etc. – it gets included again when Rails combines all stylesheets referenced in the manifest file.
Alternatively, if my manifest file does not include the global stylesheet, but multiple files in the manifest import it, the global stylesheet will still be included more than once. GAH.
How can you get around this? Does Sass have secret inclusion guards? Am I doing something terribly wrong?
I do not understand why this is an issue for your specific question. Variables and mixin declarations should not lead to any selectors or declaration blocks in your generated css file. However, when you use mixins for multiple selectors, the corresponding declarations are included for every such selector. This is how SASS handles it.
So as long as it's only variables and mixins, it should not matter if they are included multiple times in the manifest file since this does not have an effect on the compiled file. On a site-node, I believe it to be good style that SASS forces you to explicitly declare each file's dependencies.
If, however, you also have selectors and declarations in the base file that you want to inherit from in separate files, then indeed these will be included multiple times even in the compiled file. It would still be interesting to know how to prevent this by configuration. However, if you treat each of your sass files to be one encapsulated set of rules without cross-file inheritance, then you should be able to prevent your issue by convention.
For example, when using bootstrap-sass, just the mixins and variable definitions can be brought in scope with;
#import "bootstrap/variables";
#import "bootstrap/mixins";
You can get around this by doing this:
/*
* application.css.scss
*= require_self
* ----> Note the missing = require_tree
*/
#import "global.css.scss"; // Defines global mixins etc
#import "users.css.scss"; // Uses mixins defined in _global.css.scss
Then don't import global.css.scssinside users.css.scss or any other dependent files.
If you haven't already, check out Ryan Bates screencast on SASS and sprockets in rails 3.1, this is what he does to solve this issue.
For now, until SASS 4 is released, I prefer modifiying the import lines to something like:
#if not-imported("font") { #import "font"; }
You will need a function named not-imported then, of course, looking like this:
$imported-once-files: () !default;
#function not-imported($name) {
$module_index: index($imported-once-files, $name);
#if (($module_index == null) or ($module_index == false)) {
$imported-once-files: append($imported-once-files, $name);
#return true;
}
#return false;
}
This works fine and maintains the interoperability with other tools (like StyleDocco). I wrote about it, here
It is currently not possible to use SASS to include files dynamically. #import cannot be used within control directives (e.g. #if) or mixins, using a variable in an import directive is erroneous syntax, and there is no directive for ending file execution early (which effectively would allow conditional imports). However, you can solve your issue by changing how you structure your style rules.
NOTE
There is a SASS plugin that will modify #import to only
include files once. However,
Your code will have added dependence on the environment
We would all do better to understand how style rules are intended to be structured, which would avoid any duplicate rules.
#import may soon be deprecated. The SASS team is planning "large-scale redesign of importing", so re-import protection
might be part of future versions of SASS, as it is popular
requested feature.
Solution
If you have styles that are conditionally included from multiple files, they are not 'global' styles. These styles should be encapsulated in mixins, in 'module' or 'library' files. The main idea is that importing one such file will not output any css. This way, you can import these files redundantly so you can use the mixins wherever you need them.
If you need to do this with variables, then:
Make sure you define variables before including mixins, otherwise they are only available in the mixin scope. A good way to do this is to define all default variables in a vars.sass file, and import it along with imported modules/libraries so the variables are available globally.
Define variables using !default in the mixin, so it can be overridden even before the mixin is called (like in a vars.sass file).
If you have top-level styles that you want to ensure are defined without having rigid inclusion rules, you can use this mixin:
$was-defined: () !default;
#mixin define-once($name) {
#if not index($was-defined, $name) {
$was-defined: append($was-defined, $name);
#content;
}
}
// Example:
#include define-once('body-typography') {
body {
font-size: 100%;
line-height: 2em;
color: #444;
font-family: monospace;
}
}
For more good practices on structuring your code like this, check out this article.